From e84f7b3711434673328c909908c155ada79c9b40 Mon Sep 17 00:00:00 2001 From: Vincent Rubinetti Date: Tue, 12 Mar 2024 16:45:16 -0400 Subject: [PATCH] Add upload button (#367) * add upload button * comments * add some upload checks * fix "file insufficient" bug * clarify comment * move empty file error to top --- app/create-pr.js | 7 +- app/src/data/completion.json | 564 ++++++++++++++++----------------- app/src/data/lessons.json | 266 ++++++++-------- app/src/data/types.ts | 2 +- app/src/data/update.ts | 16 +- app/src/pages/Edit.tsx | 52 ++- app/src/pages/edit/Footer.tsx | 35 +- app/src/pages/edit/Header.tsx | 1 + app/src/pages/edit/Row.tsx | 46 ++- app/src/pages/edit/Section.tsx | 5 +- app/src/pages/home/Search.tsx | 4 +- app/src/util/download.ts | 68 +++- 12 files changed, 594 insertions(+), 472 deletions(-) diff --git a/app/create-pr.js b/app/create-pr.js index 14f6c5811..3f5d1128a 100644 --- a/app/create-pr.js +++ b/app/create-pr.js @@ -37,6 +37,9 @@ async function createPr(params, debug = false) { if (!title) missing.push("title"); if (!body) missing.push("body"); if (!files.length) missing.push("files"); + files.forEach(({ path, content }, index) => { + if (!path || !content) missing.push(`file ${index}`); + }); if (missing.length) throw Error(`Insufficient ${missing.join(", ")}`); /** get main branch */ @@ -70,9 +73,7 @@ async function createPr(params, debug = false) { } /** update files */ - for (const [index, { path, content }] of Object.entries(files)) { - if (!path || !content) throw Error(`File ${index} insufficient`); - + for (const { path, content } of files) { /** get existing file */ let existing; try { diff --git a/app/src/data/completion.json b/app/src/data/completion.json index ae596cea1..2f8edf302 100644 --- a/app/src/data/completion.json +++ b/app/src/data/completion.json @@ -185,18 +185,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -387,18 +387,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.0029091591591591595 @@ -589,18 +589,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -791,18 +791,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.008765578193012363 @@ -993,18 +993,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -1195,18 +1195,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -1397,18 +1397,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0.6666666666666666, "mandelbrot": 0, + "cube-shadow-puzzle": 0.6666666666666666, + "visual-proofs": 0, "total": 0.03333333333333333 }, "total": 0.0045045045045045045 @@ -1599,18 +1599,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -1801,18 +1801,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.0017830330330330332 @@ -2003,18 +2003,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -2205,18 +2205,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.02027027027027027 @@ -2407,18 +2407,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -2609,18 +2609,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -2811,18 +2811,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0.5306122448979592, - "moser": 0, + "eola-preview": 0.06451612903225806, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0.06451612903225806, - "newton-art-puzzle": 0.375, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0.375, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0.4444444444444444, - "cube-shadow-puzzle": 0.7777777777777778, "mandelbrot": 0.8333333333333334, + "cube-shadow-puzzle": 0.7777777777777778, + "visual-proofs": 0.5306122448979592, "total": 0.15128419647428865 }, "total": 0.037477325336310374 @@ -3013,18 +3013,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -3215,18 +3215,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0.4827586206896552, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0.4827586206896552, "subset-sum": 0, - "cube-shadow-puzzle": 0.5555555555555556, "mandelbrot": 1, + "cube-shadow-puzzle": 0.5555555555555556, + "visual-proofs": 0, "total": 0.10191570881226056 }, "total": 0.05097541969031687 @@ -3417,18 +3417,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -3619,18 +3619,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.006756756756756757 @@ -3821,18 +3821,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.010880834482808167 @@ -4023,18 +4023,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0.4444444444444444, - "cube-shadow-puzzle": 0.4444444444444444, "mandelbrot": 0, + "cube-shadow-puzzle": 0.4444444444444444, + "visual-proofs": 0, "total": 0.04444444444444444 }, "total": 0.006771339008181112 @@ -4225,18 +4225,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.021856491799239892 @@ -4427,18 +4427,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.0005790131007728729 @@ -4629,18 +4629,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.07942805135945673 @@ -4831,18 +4831,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -5033,18 +5033,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 1, "mandelbrot": 0, + "cube-shadow-puzzle": 1, + "visual-proofs": 0, "total": 0.05 }, "total": 0.013928402086296823 @@ -5235,18 +5235,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -5437,18 +5437,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -5639,18 +5639,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.002598752598752599 @@ -5841,18 +5841,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -6043,18 +6043,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.002353477072578196 @@ -6245,18 +6245,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -6447,18 +6447,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0.35374149659863946, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0.35374149659863946, "total": 0.017687074829931974 }, "total": 0.006491080849771695 @@ -6649,18 +6649,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -6851,18 +6851,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.010420782683878053 @@ -7053,18 +7053,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -7255,18 +7255,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -7457,18 +7457,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -7659,18 +7659,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0.375, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0.12643678160919541, + "newton-art-puzzle": 0.375, "how-they-fool-ya": 0, + "ego-and-math": 0.12643678160919541, "subset-sum": 0.1111111111111111, - "cube-shadow-puzzle": 0, "mandelbrot": 0.5, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0.06007183908045978 }, "total": 0.036503174447194454 @@ -7861,18 +7861,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -8063,18 +8063,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -8265,18 +8265,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -8467,18 +8467,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -8669,18 +8669,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.007641570141570141 @@ -8871,18 +8871,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.0027233866519580804 @@ -9073,18 +9073,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0 @@ -9275,18 +9275,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.0006077506077506078 @@ -9477,18 +9477,18 @@ "binary-counting": 0, "eulers-formula-old": 0, "eulers-formula-poem": 0, - "visual-proofs": 0, - "moser": 0, + "eola-preview": 0, "qa4": 0, "fourier-series-montage": 0, - "eola-preview": 0, - "newton-art-puzzle": 0, + "moser": 0, "on-shorts": 0, - "ego-and-math": 0, + "newton-art-puzzle": 0, "how-they-fool-ya": 0, + "ego-and-math": 0, "subset-sum": 0, - "cube-shadow-puzzle": 0, "mandelbrot": 0, + "cube-shadow-puzzle": 0, + "visual-proofs": 0, "total": 0 }, "total": 0.040635443079251224 diff --git a/app/src/data/lessons.json b/app/src/data/lessons.json index e4182bc90..1dd41bc04 100644 --- a/app/src/data/lessons.json +++ b/app/src/data/lessons.json @@ -2,14 +2,14 @@ { "path": "2017/essence-of-calculus", "lesson": "essence-of-calculus", - "title": "essence-of-calculus", + "title": "The essence of calculus", "topic": "Calculus", "nextLesson": "derivatives" }, { "path": "2017/derivatives", "lesson": "derivatives", - "title": "derivatives", + "title": "The paradox of the derivative | Chapter 2, Essence of calculus", "topic": "Calculus", "previousLesson": "essence-of-calculus", "nextLesson": "derivative-formulas-geometrically" @@ -17,7 +17,7 @@ { "path": "2017/derivative-formulas-geometrically", "lesson": "derivative-formulas-geometrically", - "title": "derivative-formulas-geometrically", + "title": "Derivative formulas through geometry | Chapter 3, Essence of calculus", "topic": "Calculus", "previousLesson": "derivatives", "nextLesson": "derivatives-power-rule" @@ -25,7 +25,7 @@ { "path": "2017/chain-rule-and-product-rule", "lesson": "chain-rule-and-product-rule", - "title": "chain-rule-and-product-rule", + "title": "Visualizing the chain rule and product rule | Chapter 4, Essence of calculus", "topic": "Calculus", "previousLesson": "derivatives-trig-functions", "nextLesson": "eulers-number" @@ -33,7 +33,7 @@ { "path": "2017/eulers-number", "lesson": "eulers-number", - "title": "eulers-number", + "title": "What's so special about Euler's number e? | Chapter 5, Essence of calculus", "topic": "Calculus", "previousLesson": "chain-rule-and-product-rule", "nextLesson": "implicit-differentiation" @@ -41,7 +41,7 @@ { "path": "2017/implicit-differentiation", "lesson": "implicit-differentiation", - "title": "implicit-differentiation", + "title": "Implicit differentiation, what's going on here? | Chapter 6, Essence of calculus", "topic": "Calculus", "previousLesson": "eulers-number", "nextLesson": "limits" @@ -49,7 +49,7 @@ { "path": "2017/limits", "lesson": "limits", - "title": "limits", + "title": "Limits, L'Hôpital's rule, and epsilon delta definitions | Chapter 7, Essence of calculus", "topic": "Calculus", "previousLesson": "implicit-differentiation", "nextLesson": "epsilon-delta" @@ -57,7 +57,7 @@ { "path": "2017/integration", "lesson": "integration", - "title": "integration", + "title": "Integration and the fundamental theorem of calculus | Chapter 8, Essence of calculus", "topic": "Calculus", "previousLesson": "l-hopitals-rule", "nextLesson": "area-and-slope" @@ -65,7 +65,7 @@ { "path": "2017/area-and-slope", "lesson": "area-and-slope", - "title": "area-and-slope", + "title": "What does area have to do with slope? | Chapter 9, Essence of calculus", "topic": "Calculus", "previousLesson": "integration", "nextLesson": "higher-order-derivatives" @@ -73,7 +73,7 @@ { "path": "2017/higher-order-derivatives", "lesson": "higher-order-derivatives", - "title": "higher-order-derivatives", + "title": "Higher order derivatives | Chapter 10, Essence of calculus", "topic": "Calculus", "previousLesson": "area-and-slope", "nextLesson": "taylor-series" @@ -81,7 +81,7 @@ { "path": "2017/taylor-series", "lesson": "taylor-series", - "title": "taylor-series", + "title": "Taylor series | Chapter 11, Essence of calculus", "topic": "Calculus", "previousLesson": "higher-order-derivatives", "nextLesson": "taylor-series-geometric-view" @@ -89,7 +89,7 @@ { "path": "2018/derivatives-and-transforms", "lesson": "derivatives-and-transforms", - "title": "derivatives-and-transforms", + "title": "The other way to visualize derivatives | Chapter 12, Essence of calculus", "topic": "Calculus", "previousLesson": "taylor-series-geometric-view" }, @@ -183,7 +183,7 @@ { "path": "2019/cramers-rule", "lesson": "cramers-rule", - "title": "cramers-rule", + "title": "Cramer's rule, explained geometrically | Chapter 12, Essence of linear algebra", "topic": "Linear Algebra", "previousLesson": "cross-products-extended", "nextLesson": "change-of-basis" @@ -191,7 +191,7 @@ { "path": "2016/change-of-basis", "lesson": "change-of-basis", - "title": "Change of basis | Chapter 13, Essence of linear algebra", + "title": "change-of-basis", "topic": "Linear Algebra", "previousLesson": "cramers-rule", "nextLesson": "eigenvalues" @@ -207,7 +207,7 @@ { "path": "2021/quick-eigen", "lesson": "quick-eigen", - "title": "quick-eigen", + "title": "A quick trick for computing eigenvalues | Chapter 15, Essence of linear algebra", "topic": "Linear Algebra", "previousLesson": "eigenvalues", "nextLesson": "abstract-vector-spaces" @@ -222,14 +222,14 @@ { "path": "2017/neural-networks", "lesson": "neural-networks", - "title": "neural-networks", + "title": "But what is a neural network? | Chapter 1, Deep learning", "topic": "Neural Networks", "nextLesson": "gradient-descent" }, { "path": "2017/gradient-descent", "lesson": "gradient-descent", - "title": "gradient-descent", + "title": "Gradient descent, how neural networks learn | Chapter 2, Deep learning", "topic": "Neural Networks", "previousLesson": "neural-networks", "nextLesson": "neural-network-analysis" @@ -237,7 +237,7 @@ { "path": "2017/backpropagation", "lesson": "backpropagation", - "title": "backpropagation", + "title": "What is backpropagation really doing? | Chapter 3, Deep learning", "topic": "Neural Networks", "previousLesson": "neural-network-analysis", "nextLesson": "backpropagation-calculus" @@ -245,21 +245,21 @@ { "path": "2017/backpropagation-calculus", "lesson": "backpropagation-calculus", - "title": "backpropagation-calculus", + "title": "Backpropagation calculus | Chapter 4, Deep learning", "topic": "Neural Networks", "previousLesson": "backpropagation" }, { "path": "2019/differential-equations", "lesson": "differential-equations", - "title": "differential-equations", + "title": "Differential equations, a tourist's guide | DE1", "topic": "Differential Equations", "nextLesson": "pdes" }, { "path": "2019/pdes", "lesson": "pdes", - "title": "pdes", + "title": "But what is a partial differential equation? | DE2", "topic": "Differential Equations", "previousLesson": "differential-equations", "nextLesson": "heat-equation" @@ -267,7 +267,7 @@ { "path": "2019/heat-equation", "lesson": "heat-equation", - "title": "heat-equation", + "title": "Solving the heat equation | DE3", "topic": "Differential Equations", "previousLesson": "pdes", "nextLesson": "fourier-series" @@ -275,7 +275,7 @@ { "path": "2019/fourier-series", "lesson": "fourier-series", - "title": "fourier-series", + "title": "But what is a Fourier series? From heat flow to drawing with circles | DE4", "topic": "Differential Equations", "previousLesson": "heat-equation", "nextLesson": "eulers-formula-dynamically" @@ -291,21 +291,21 @@ { "path": "2021/matrix-exponents", "lesson": "matrix-exponents", - "title": "matrix-exponents", + "title": "How (and why) to raise e to the power of a matrix | DE6", "topic": "Differential Equations", "previousLesson": "eulers-formula-dynamically" }, { "path": "2022/subsets-puzzle", "lesson": "subsets-puzzle", - "title": "subsets-puzzle", + "title": "Olympiad level counting (Generating functions)", "topic": "Puzzles", "nextLesson": "hardest-problem" }, { "path": "2017/hardest-problem", "lesson": "hardest-problem", - "title": "hardest-problem", + "title": "The hardest problem on the hardest test", "topic": "Puzzles", "previousLesson": "subsets-puzzle", "nextLesson": "windmills" @@ -321,7 +321,7 @@ { "path": "2019/prime-spirals", "lesson": "prime-spirals", - "title": "prime-spirals", + "title": "Why do prime numbers make these spirals? | Dirichlet’s theorem and pi approximations", "topic": "Puzzles", "previousLesson": "windmills", "nextLesson": "moser-reboot" @@ -329,7 +329,7 @@ { "path": "2023/moser-reboot", "lesson": "moser-reboot", - "title": "moser-reboot", + "title": "This pattern breaks, but for a good reason | Moser's circle problem", "topic": "Puzzles", "previousLesson": "prime-spirals", "nextLesson": "chessboard-puzzle" @@ -337,7 +337,7 @@ { "path": "2020/chessboard-puzzle", "lesson": "chessboard-puzzle", - "title": "chessboard-puzzle", + "title": "The impossible chessboard puzzle", "topic": "Puzzles", "previousLesson": "moser-reboot", "nextLesson": "shadows" @@ -345,7 +345,7 @@ { "path": "2021/shadows", "lesson": "shadows", - "title": "shadows", + "title": "A tale of two problem solvers (Average cube shadows)", "topic": "Puzzles", "previousLesson": "chessboard-puzzle", "nextLesson": "three-utilities" @@ -353,7 +353,7 @@ { "path": "2017/three-utilities", "lesson": "three-utilities", - "title": "three-utilities", + "title": "Why this puzzle is impossible", "topic": "Puzzles", "previousLesson": "shadows" }, @@ -367,7 +367,7 @@ { "path": "2019/clacks-solution", "lesson": "clacks-solution", - "title": "clacks-solution", + "title": "Why do colliding blocks compute pi?", "topic": "Why Pi", "previousLesson": "clacks", "nextLesson": "clacks-via-light" @@ -375,7 +375,7 @@ { "path": "2019/clacks-via-light", "lesson": "clacks-via-light", - "title": "clacks-via-light", + "title": "How colliding blocks act like a beam of light...to compute pi.", "topic": "Why Pi", "previousLesson": "clacks-solution", "nextLesson": "basel-problem" @@ -383,7 +383,7 @@ { "path": "2018/basel-problem", "lesson": "basel-problem", - "title": "basel-problem", + "title": "Why is pi here? And why is it squared? A geometric answer to the Basel problem", "topic": "Why Pi", "previousLesson": "clacks-via-light", "nextLesson": "leibniz-formula" @@ -391,7 +391,7 @@ { "path": "2017/leibniz-formula", "lesson": "leibniz-formula", - "title": "leibniz-formula", + "title": "Pi hiding in prime regularities", "topic": "Why Pi", "previousLesson": "basel-problem", "nextLesson": "wallis-product" @@ -399,7 +399,7 @@ { "path": "2018/wallis-product", "lesson": "wallis-product", - "title": "wallis-product", + "title": "The Wallis product for pi, proved geometrically", "topic": "Why Pi", "previousLesson": "leibniz-formula", "nextLesson": "pi-was-628" @@ -407,21 +407,21 @@ { "path": "2018/pi-was-628", "lesson": "pi-was-628", - "title": "pi-was-628", + "title": "How pi was almost 6.283185...", "topic": "Why Pi", "previousLesson": "wallis-product" }, { "path": "2018/sphere-area", "lesson": "sphere-area", - "title": "sphere-area", + "title": "But why is a sphere's surface area four times its shadow?", "topic": "Geometry", "nextLesson": "dandelin-spheres" }, { "path": "2018/dandelin-spheres", "lesson": "dandelin-spheres", - "title": "dandelin-spheres", + "title": "Why slicing a cone gives an ellipse (beautiful proof)", "topic": "Geometry", "previousLesson": "sphere-area", "nextLesson": "higher-dimensions" @@ -429,7 +429,7 @@ { "path": "2017/higher-dimensions", "lesson": "higher-dimensions", - "title": "higher-dimensions", + "title": "Thinking outside the 10-dimensional box", "topic": "Geometry", "previousLesson": "dandelin-spheres", "nextLesson": "pythagorean-triples" @@ -437,7 +437,7 @@ { "path": "2017/pythagorean-triples", "lesson": "pythagorean-triples", - "title": "pythagorean-triples", + "title": "All possible pythagorean triples, visualized", "topic": "Geometry", "previousLesson": "higher-dimensions", "nextLesson": "quaternions" @@ -445,7 +445,7 @@ { "path": "2018/quaternions", "lesson": "quaternions", - "title": "quaternions", + "title": "Visualizing quaternions (4d numbers) with stereographic projection", "topic": "Geometry", "previousLesson": "pythagorean-triples", "nextLesson": "quaternions-and-3d-rotation" @@ -453,7 +453,7 @@ { "path": "2018/quaternions-and-3d-rotation", "lesson": "quaternions-and-3d-rotation", - "title": "quaternions-and-3d-rotation", + "title": "Quaternions and 3d rotation, explained interactively", "topic": "Geometry", "previousLesson": "quaternions", "nextLesson": "eulers-characteristic-formula" @@ -461,7 +461,7 @@ { "path": "2015/eulers-characteristic-formula", "lesson": "eulers-characteristic-formula", - "title": "eulers-characteristic-formula", + "title": "Euler's Formula and Graph Duality", "topic": "Geometry", "previousLesson": "quaternions-and-3d-rotation", "nextLesson": "hyperdarts" @@ -469,14 +469,14 @@ { "path": "2018/fourier-transforms", "lesson": "fourier-transforms", - "title": "fourier-transforms", + "title": "But what is the Fourier Transform? A visual introduction.", "topic": "Analysis", "nextLesson": "uncertainty-principle" }, { "path": "2018/uncertainty-principle", "lesson": "uncertainty-principle", - "title": "uncertainty-principle", + "title": "The more general uncertainty principle, regarding Fourier transforms", "topic": "Analysis", "previousLesson": "fourier-transforms", "nextLesson": "newtons-fractal" @@ -484,7 +484,7 @@ { "path": "2021/newtons-fractal", "lesson": "newtons-fractal", - "title": "newtons-fractal", + "title": "From Newton’s method to Newton’s fractal (which Newton knew nothing about)", "topic": "Analysis", "previousLesson": "uncertainty-principle", "nextLesson": "holomorphic-dynamics" @@ -492,7 +492,7 @@ { "path": "2021/holomorphic-dynamics", "lesson": "holomorphic-dynamics", - "title": "holomorphic-dynamics", + "title": "Beyond the Mandelbrot set, an intro to holomorphic dynamics", "topic": "Analysis", "previousLesson": "newtons-fractal", "nextLesson": "zeta" @@ -500,7 +500,7 @@ { "path": "2016/zeta", "lesson": "zeta", - "title": "zeta", + "title": "But what is the Riemann zeta function? Visualizing analytic continuation", "topic": "Analysis", "previousLesson": "holomorphic-dynamics", "nextLesson": "divergence-and-curl" @@ -508,7 +508,7 @@ { "path": "2018/divergence-and-curl", "lesson": "divergence-and-curl", - "title": "divergence-and-curl", + "title": "Divergence and curl: The language of Maxwell's equations, fluid flow, and more", "topic": "Analysis", "previousLesson": "zeta", "nextLesson": "borwein" @@ -516,7 +516,7 @@ { "path": "2022/borwein", "lesson": "borwein", - "title": "borwein", + "title": "Researchers thought this was a bug (Borwein integrals)", "topic": "Analysis", "previousLesson": "divergence-and-curl", "nextLesson": "hilbert-curve" @@ -524,7 +524,7 @@ { "path": "2016/hilbert-curve", "lesson": "hilbert-curve", - "title": "hilbert-curve", + "title": "Fractal charm: Space filling curves", "topic": "Analysis", "previousLesson": "borwein", "nextLesson": "fractal-dimension" @@ -540,7 +540,7 @@ { "path": "2017/fractal-dimension", "lesson": "fractal-dimension", - "title": "fractal-dimension", + "title": "Fractals are typically not self-similar", "topic": "Analysis", "previousLesson": "hilbert-curve", "nextLesson": "winding-numbers" @@ -548,7 +548,7 @@ { "path": "2018/winding-numbers", "lesson": "winding-numbers", - "title": "winding-numbers", + "title": "Winding numbers and domain coloring", "topic": "Analysis", "previousLesson": "fractal-dimension", "nextLesson": "inventing-math" @@ -564,7 +564,7 @@ { "path": "2015/music-and-measure-theory", "lesson": "music-and-measure-theory", - "title": "music-and-measure-theory", + "title": "Music And Measure Theory", "topic": "Analysis", "previousLesson": "inventing-math" }, @@ -586,7 +586,7 @@ { "path": "2023/prism", "lesson": "prism", - "title": "Why light can “slow down”, and why it depends on color | Optics puzzles 3", + "title": "Understanding prisms requires understanding springs | Optics puzzles 3", "topic": "Physics", "previousLesson": "barber-pole-2", "nextLesson": "refractive-index-questions" @@ -602,7 +602,7 @@ { "path": "2017/light-quantum-mechanics", "lesson": "light-quantum-mechanics", - "title": "light-quantum-mechanics", + "title": "Some light quantum mechanics (with minutephysics)", "topic": "Physics", "previousLesson": "refractive-index-questions", "nextLesson": "feynmans-lost-lecture" @@ -610,7 +610,7 @@ { "path": "2018/feynmans-lost-lecture", "lesson": "feynmans-lost-lecture", - "title": "feynmans-lost-lecture", + "title": "Feynman's Lost Lecture (ft. 3Blue1Brown)", "topic": "Physics", "previousLesson": "light-quantum-mechanics", "nextLesson": "brachistochrone" @@ -618,7 +618,7 @@ { "path": "2016/brachistochrone", "lesson": "brachistochrone", - "title": "brachistochrone", + "title": "The Brachistochrone, with Steven Strogatz", "topic": "Physics", "previousLesson": "feynmans-lost-lecture", "nextLesson": "snells-law" @@ -634,21 +634,21 @@ { "path": "2018/turbulence", "lesson": "turbulence", - "title": "turbulence", + "title": "Why 5/3 is a fundamental constant for turbulence", "topic": "Physics", "previousLesson": "snells-law" }, { "path": "2023/clt", "lesson": "clt", - "title": "clt", + "title": "But what is the Central Limit Theorem?", "topic": "Probability", "nextLesson": "gaussian-integral" }, { "path": "2023/gaussian-integral", "lesson": "gaussian-integral", - "title": "gaussian-integral", + "title": "Why π is in the normal distribution (beyond integral tricks)", "topic": "Probability", "previousLesson": "clt", "nextLesson": "convolutions2" @@ -656,7 +656,7 @@ { "path": "2023/convolutions2", "lesson": "convolutions2", - "title": "convolutions2", + "title": "Convolutions | Why X+Y in probability is a beautiful mess", "topic": "Probability", "previousLesson": "gaussian-integral", "nextLesson": "gaussian-convolution" @@ -664,7 +664,7 @@ { "path": "2023/gaussian-convolution", "lesson": "gaussian-convolution", - "title": "gaussian-convolution", + "title": "A pretty reason why Gaussian + Gaussian = Gaussian", "topic": "Probability", "previousLesson": "convolutions2", "nextLesson": "bayes-theorem" @@ -672,7 +672,7 @@ { "path": "2019/bayes-theorem", "lesson": "bayes-theorem", - "title": "bayes-theorem", + "title": "Bayes theorem, the geometry of changing beliefs", "topic": "Probability", "previousLesson": "gaussian-convolution", "nextLesson": "bayes-theorem-quick" @@ -680,7 +680,7 @@ { "path": "2019/bayes-theorem-quick", "lesson": "bayes-theorem-quick", - "title": "bayes-theorem-quick", + "title": "The quick proof of Bayes' theorem", "topic": "Probability", "previousLesson": "bayes-theorem", "nextLesson": "better-bayes" @@ -688,7 +688,7 @@ { "path": "2020/better-bayes", "lesson": "better-bayes", - "title": "better-bayes", + "title": "The medical test paradox, and redesigning Bayes' rule", "topic": "Probability", "previousLesson": "bayes-theorem-quick", "nextLesson": "binomial-distributions" @@ -696,7 +696,7 @@ { "path": "2020/binomial-distributions", "lesson": "binomial-distributions", - "title": "binomial-distributions", + "title": "Binomial distributions | Probabilities of probabilities, part 1", "topic": "Probability", "previousLesson": "better-bayes", "nextLesson": "pdfs" @@ -704,21 +704,21 @@ { "path": "2020/pdfs", "lesson": "pdfs", - "title": "pdfs", + "title": "Why “probability of 0” does not mean “impossible” | Probabilities of probabilities, part 2", "topic": "Probability", "previousLesson": "binomial-distributions" }, { "path": "2022/convolutions", "lesson": "convolutions", - "title": "convolutions", + "title": "But what is a convolution?", "topic": "Computer Science", "nextLesson": "wordle" }, { "path": "2022/wordle", "lesson": "wordle", - "title": "wordle", + "title": "Solving Wordle using information theory", "topic": "Computer Science", "previousLesson": "convolutions", "nextLesson": "wordle-2" @@ -726,7 +726,7 @@ { "path": "2022/wordle-2", "lesson": "wordle-2", - "title": "wordle-2", + "title": "Oh, wait, actually the best Wordle opener is not “crane”…", "topic": "Computer Science", "previousLesson": "wordle", "nextLesson": "bitcoin" @@ -734,7 +734,7 @@ { "path": "2017/bitcoin", "lesson": "bitcoin", - "title": "bitcoin", + "title": "But how does bitcoin actually work?", "topic": "Computer Science", "previousLesson": "wordle-2", "nextLesson": "256-bit-security" @@ -742,7 +742,7 @@ { "path": "2017/256-bit-security", "lesson": "256-bit-security", - "title": "256-bit-security", + "title": "How secure is 256 bit security?", "topic": "Computer Science", "previousLesson": "bitcoin", "nextLesson": "hamming-codes" @@ -750,7 +750,7 @@ { "path": "2020/hamming-codes", "lesson": "hamming-codes", - "title": "hamming-codes", + "title": "But what are Hamming codes? The origin of error correction", "topic": "Computer Science", "previousLesson": "256-bit-security", "nextLesson": "hamming-codes-2" @@ -758,7 +758,7 @@ { "path": "2020/hamming-codes-2", "lesson": "hamming-codes-2", - "title": "hamming-codes-2", + "title": "Hamming codes part 2: The one-line implementation", "topic": "Computer Science", "previousLesson": "hamming-codes", "nextLesson": "hanoi-and-sierpinski" @@ -766,21 +766,21 @@ { "path": "2016/hanoi-and-sierpinski", "lesson": "hanoi-and-sierpinski", - "title": "hanoi-and-sierpinski", + "title": "Binary, Hanoi and Sierpinski, part 1", "topic": "Computer Science", "previousLesson": "hamming-codes-2" }, { "path": "2016/inscribed-rectangle-problem", "lesson": "inscribed-rectangle-problem", - "title": "inscribed-rectangle-problem", + "title": "Who cares about topology? (Inscribed rectangle problem)", "topic": "Topology", "nextLesson": "borsuk-ulam" }, { "path": "2018/borsuk-ulam", "lesson": "borsuk-ulam", - "title": "borsuk-ulam", + "title": "Using topology for discrete problems | The Borsuk-Ulam theorem and stolen necklaces", "topic": "Topology", "previousLesson": "inscribed-rectangle-problem" }, @@ -794,7 +794,7 @@ { "path": "2017/eulers-formula-via-group-theory", "lesson": "eulers-formula-via-group-theory", - "title": "eulers-formula-via-group-theory", + "title": "Euler's formula with introductory group theory", "topic": "Group Theory", "previousLesson": "groups-and-monsters" }, @@ -816,21 +816,21 @@ { "path": "2020/dp3t", "lesson": "dp3t", - "title": "The DP-3T algorithm for contact tracing (via Nicky Case)", + "title": "dp3t", "topic": "Epidemics", "previousLesson": "epidemic-simulations" }, { "path": "2020/lockdown-math-announcement", "lesson": "lockdown-math-announcement", - "title": "lockdown-math-announcement", + "title": "Lockdown math announcement", "topic": "Lockdown Math", "nextLesson": "ldm-quadratic" }, { "path": "2020/ldm-quadratic", "lesson": "ldm-quadratic", - "title": "ldm-quadratic", + "title": "The simpler quadratic formula | Ep. 1 Lockdown live math", "topic": "Lockdown Math", "previousLesson": "lockdown-math-announcement", "nextLesson": "ldm-trigonometry" @@ -838,7 +838,7 @@ { "path": "2020/ldm-trigonometry", "lesson": "ldm-trigonometry", - "title": "ldm-trigonometry", + "title": "Trigonometry fundamentals | Ep. 2 Lockdown live math", "topic": "Lockdown Math", "previousLesson": "ldm-quadratic", "nextLesson": "ldm-complex-numbers" @@ -846,7 +846,7 @@ { "path": "2020/ldm-complex-numbers", "lesson": "ldm-complex-numbers", - "title": "ldm-complex-numbers", + "title": "Complex number fundamentals | Ep. 3 Lockdown live math", "topic": "Lockdown Math", "previousLesson": "ldm-trigonometry", "nextLesson": "ldm-eulers-formula" @@ -854,7 +854,7 @@ { "path": "2020/ldm-eulers-formula", "lesson": "ldm-eulers-formula", - "title": "ldm-eulers-formula", + "title": "What is Euler's formula actually saying? | Ep. 4 Lockdown live math", "topic": "Lockdown Math", "previousLesson": "ldm-complex-numbers", "nextLesson": "ldm-imaginary-interest" @@ -862,7 +862,7 @@ { "path": "2020/ldm-imaginary-interest", "lesson": "ldm-imaginary-interest", - "title": "ldm-imaginary-interest", + "title": "Imaginary interest rates | Ep. 5 Lockdown live math", "topic": "Lockdown Math", "previousLesson": "ldm-eulers-formula", "nextLesson": "ldm-logarithms" @@ -870,7 +870,7 @@ { "path": "2020/ldm-logarithms", "lesson": "ldm-logarithms", - "title": "ldm-logarithms", + "title": "Logarithm Fundamentals | Ep. 6 Lockdown live math", "topic": "Lockdown Math", "previousLesson": "ldm-imaginary-interest", "nextLesson": "ldm-natural-logs" @@ -878,7 +878,7 @@ { "path": "2020/ldm-natural-logs", "lesson": "ldm-natural-logs", - "title": "ldm-natural-logs", + "title": "What makes the natural log \"natural\"? | Ep. 7 Lockdown live math", "topic": "Lockdown Math", "previousLesson": "ldm-logarithms", "nextLesson": "ldm-power-towers" @@ -886,7 +886,7 @@ { "path": "2020/ldm-power-towers", "lesson": "ldm-power-towers", - "title": "ldm-power-towers", + "title": "The power tower puzzle | Ep. 8 Lockdown live math", "topic": "Lockdown Math", "previousLesson": "ldm-natural-logs", "nextLesson": "ldm-i-to-i" @@ -894,7 +894,7 @@ { "path": "2020/ldm-i-to-i", "lesson": "ldm-i-to-i", - "title": "ldm-i-to-i", + "title": "Intuition for i to the power i | Ep. 9 Lockdown live math", "topic": "Lockdown Math", "previousLesson": "ldm-power-towers", "nextLesson": "ldm-tips-to-problem-solving" @@ -902,7 +902,7 @@ { "path": "2020/ldm-tips-to-problem-solving", "lesson": "ldm-tips-to-problem-solving", - "title": "ldm-tips-to-problem-solving", + "title": "Tips to be a better problem solver [Last live lecture] | Ep. 10 Lockdown live math", "topic": "Lockdown Math", "previousLesson": "ldm-i-to-i" }, @@ -955,7 +955,7 @@ { "path": "2017/tattoos-on-math", "lesson": "tattoos-on-math", - "title": "tattoos-on-math", + "title": "Tattoos on Math", "topic": "Miscellaneous", "previousLesson": "qa3", "nextLesson": "triangle-of-power" @@ -963,7 +963,7 @@ { "path": "2016/triangle-of-power", "lesson": "triangle-of-power", - "title": "triangle-of-power", + "title": "Triangle of Power", "topic": "Miscellaneous", "previousLesson": "tattoos-on-math", "nextLesson": "binary-counting" @@ -971,7 +971,7 @@ { "path": "2015/binary-counting", "lesson": "binary-counting", - "title": "binary-counting", + "title": "How to count to 1000 on two hands", "topic": "Miscellaneous", "previousLesson": "triangle-of-power", "nextLesson": "eulers-formula-old" @@ -990,22 +990,14 @@ "title": "Euler's Formula Poem", "topic": "Miscellaneous", "previousLesson": "eulers-formula-old", - "nextLesson": "visual-proofs" + "nextLesson": "eola-preview" }, { - "path": "2022/visual-proofs", - "lesson": "visual-proofs", - "title": "visual-proofs", + "path": "2016/eola-preview", + "lesson": "eola-preview", + "title": "eola-preview", "topic": "Miscellaneous", "previousLesson": "eulers-formula-poem", - "nextLesson": "moser" - }, - { - "path": "2015/moser", - "lesson": "moser", - "title": "moser", - "topic": "Miscellaneous", - "previousLesson": "visual-proofs", "nextLesson": "qa4" }, { @@ -1013,7 +1005,7 @@ "lesson": "qa4", "title": "Q&A with Grant, windy walk edition", "topic": "Miscellaneous", - "previousLesson": "moser", + "previousLesson": "eola-preview", "nextLesson": "fourier-series-montage" }, { @@ -1022,22 +1014,14 @@ "title": "Pure Fourier series animation montage", "topic": "Miscellaneous", "previousLesson": "qa4", - "nextLesson": "eola-preview" + "nextLesson": "moser" }, { - "path": "2016/eola-preview", - "lesson": "eola-preview", - "title": "eola-preview", + "path": "2015/moser", + "lesson": "moser", + "title": "moser", "topic": "Miscellaneous", "previousLesson": "fourier-series-montage", - "nextLesson": "newton-art-puzzle" - }, - { - "path": "2023/shorts/newton-art-puzzle", - "lesson": "newton-art-puzzle", - "title": "The Newton art puzzle", - "topic": "Miscellaneous", - "previousLesson": "eola-preview", "nextLesson": "on-shorts" }, { @@ -1045,13 +1029,13 @@ "lesson": "on-shorts", "title": "on-shorts", "topic": "Miscellaneous", - "previousLesson": "newton-art-puzzle", - "nextLesson": "ego-and-math" + "previousLesson": "moser", + "nextLesson": "newton-art-puzzle" }, { - "path": "2023/ego-and-math", - "lesson": "ego-and-math", - "title": "ego-and-math", + "path": "2023/shorts/newton-art-puzzle", + "lesson": "newton-art-puzzle", + "title": "The Newton art puzzle", "topic": "Miscellaneous", "previousLesson": "on-shorts", "nextLesson": "how-they-fool-ya" @@ -1061,7 +1045,15 @@ "lesson": "how-they-fool-ya", "title": "How They Fool Ya (live) | Math parody of Hallelujah", "topic": "Miscellaneous", - "previousLesson": "ego-and-math", + "previousLesson": "newton-art-puzzle", + "nextLesson": "ego-and-math" + }, + { + "path": "2023/ego-and-math", + "lesson": "ego-and-math", + "title": "ego-and-math", + "topic": "Miscellaneous", + "previousLesson": "how-they-fool-ya", "nextLesson": "subset-sum" }, { @@ -1069,21 +1061,29 @@ "lesson": "subset-sum", "title": "A challenging puzzle about subset sums", "topic": "Miscellaneous", - "previousLesson": "how-they-fool-ya", + "previousLesson": "ego-and-math", + "nextLesson": "mandelbrot" + }, + { + "path": "2024/shorts/mandelbrot", + "lesson": "mandelbrot", + "title": "How the Mandelbrot set is defined", + "topic": "Miscellaneous", + "previousLesson": "subset-sum", "nextLesson": "cube-shadow-puzzle" }, { "path": "2024/shorts/cube-shadow-puzzle", "lesson": "cube-shadow-puzzle", - "title": "The cube shadow puzzle", + "title": "cube shadow puzzle", "topic": "Miscellaneous", - "previousLesson": "subset-sum", - "nextLesson": "mandelbrot" + "previousLesson": "mandelbrot", + "nextLesson": "visual-proofs" }, { - "path": "2024/shorts/mandelbrot", - "lesson": "mandelbrot", - "title": "How the Mandelbrot set is defined", + "path": "2022/visual-proofs", + "lesson": "visual-proofs", + "title": "How to lie using visual proofs", "topic": "Miscellaneous", "previousLesson": "cube-shadow-puzzle" } diff --git a/app/src/data/types.ts b/app/src/data/types.ts index db0a2fd9f..ca8db82c8 100644 --- a/app/src/data/types.ts +++ b/app/src/data/types.ts @@ -1,6 +1,6 @@ /** paths read from repo directory structure */ export type Path = { - full: string; + path: string; year: string; lesson: string; language: string; diff --git a/app/src/data/update.ts b/app/src/data/update.ts index 4787a0ca0..33d96044b 100644 --- a/app/src/data/update.ts +++ b/app/src/data/update.ts @@ -20,7 +20,7 @@ let paths = globSync("**/**/", { return { /** path, minus language */ - full: path.split("/").slice(0, -1).join("/"), + path: path.split("/").slice(0, -1).join("/"), year, lesson, language, @@ -67,23 +67,21 @@ for (const language of languageList) completion[language]![topic]![lesson] = 0; } -for (const { full, lesson, language } of paths) { +for (const { path, lesson, language } of paths) { /** cross-ref topic */ const topic = topics.find((topic) => topic.lessons.includes(lesson))!; /** init entry */ const newLesson: Lesson = { - path: full, + path: path, lesson, title: lesson, topic: topic.name, }; /** get full lesson name */ - if (newLesson.title === lesson) { - const titleFile = `../${full}/${language}/title.json`; - newLesson.title = readFile<_Title>(titleFile)?.input || lesson || ""; - } + const titleFile = `../${path}/${language}/title.json`; + newLesson.title = readFile<_Title>(titleFile)?.input || lesson || ""; /** find next/prev lessons */ const index = topic.lessons.indexOf(lesson); @@ -93,13 +91,13 @@ for (const { full, lesson, language } of paths) { /** get completion */ const translation = - readFile<_Entry[]>(`../${full}/${language}/sentence_translations.json`) || + readFile<_Entry[]>(`../${path}/${language}/sentence_translations.json`) || []; const percent = calcCompletion(translation.map(convert), language); completion[language]![topic.name]![lesson] = clamp(percent, 0, 1); /** add lesson to list */ - lessons[full] = newLesson; + lessons[path] = newLesson; } /** calc totals */ diff --git a/app/src/pages/Edit.tsx b/app/src/pages/Edit.tsx index 956cd3a70..f04fa7db2 100644 --- a/app/src/pages/Edit.tsx +++ b/app/src/pages/Edit.tsx @@ -8,6 +8,7 @@ import { _Entry, Entry } from "@/data/types"; import Footer from "@/pages/edit/Footer"; import Header from "@/pages/edit/Header"; import Section from "@/pages/edit/Section"; +import { UploadResult } from "@/util/download"; /** translation edit page */ function Edit() { @@ -18,9 +19,17 @@ function Edit() { <>
-
-
-
+
+
+