// Define a list of objects with "front" and "back" HTML content const pages = [ { front: "This is the front page!", back: "This is the back page!" }, { front: "Another front page", back: "Another back page" } ]; // Select the first page from the list let currentPage = pages[0]; let showFront = true; // Replace the page with the front HTML initially document.body.innerHTML = currentPage.front; // Add an event listener for the spacebar press window.addEventListener('keydown', (event) => { if (event.code === 'Space') { // Toggle between front and back content if (showFront) { document.body.innerHTML = currentPage.back; } else { document.body.innerHTML = currentPage.front; } showFront = !showFront; } }); // Constants: W as an array of f64 values const W = [ 0.40255, 1.18385, 3.173, 15.69105, 7.1949, 0.5345, 1.4604, 0.0046, 1.54575, 0.1192, 1.01925, 1.9395, 0.11, 0.29605, 2.2698, 0.2315, 2.9898, 0.51655, 0.6621 ]; // Grade enum representation const Grade = { Forgot: 1.0, Hard: 2.0, Good: 3.0, Easy: 4.0 }; // Helper to convert Grade to f64 (as in From for f64) function gradeToNumber(g) { return Grade[g]; } // Constants const F = 19.0 / 81.0; const C = -0.5; // retrievability(t: T, s: S) -> R function retrievability(t, s) { return Math.pow(1.0 + F * (t / s), C); } // interval(r_d: R, s: S) -> T function interval(rD, s) { return (s / F) * (Math.pow(rD, 1.0 / C) - 1.0); } // s_0(g: Grade) -> S function s0(g) { switch (g) { case Grade.Forgot: return W[0]; case Grade.Hard: return W[1]; case Grade.Good: return W[2]; case Grade.Easy: return W[3]; default: throw new Error("Invalid grade"); } } // s_success(d: D, s: S, r: R, g: Grade) -> S function sSuccess(d, s, r, g) { const tD = 11.0 - d; const tS = Math.pow(s, -W[9]); const tR = Math.exp(W[10] * (1.0 - r)) - 1.0; const h = (g === Grade.Hard) ? W[15] : 1.0; const b = (g === Grade.Easy) ? W[16] : 1.0; const c = Math.exp(W[8]); const alpha = 1.0 + tD * tS * tR * h * b * c; return s * alpha; } // s_fail(d: D, s: S, r: R) => number function sFail(d, s, r) { return Math.exp(W[8]) - 1.0; } // Main function function main() { // All functions } const W = [ 0.40255, 1.18385, 3.173, 15.69105, 7.1949, 0.5345, 1.4604, 0.0046, 1.54575, 0.1192, 1.01925, 1.9395, 0.11, 0.29605, 2.2698, 0.2315, 2.9898, 0.51655, 0.6621, ]; const F = 19.0 / 81.0; const C = -0.5; const Grade = { Forgot: 1.0, Hard: 2.0, Good: 3.0, Easy: 4.0 }; function retrievability(t, s) { return Math.pow(1.0 + F * (t / s), C); } function interval(r_d, s) { return (s / F) * (Math.pow(r_d, 1.0 / C) - 1.0); } function s_0(g) { switch (g) { case Grade.Forgot: return W[0]; case Grade.Hard: return W[1]; case Grade.Good: return W[2]; case Grade.Easy: return W[3]; } } function s_success(d, s, r, g) { const t_d = 11.0 - d; const t_s = Math.pow(s, -W[9]); const t_r = Math.exp(W[10] * (1.0 - r)) - 1.0; const h = g === Grade.Hard ? W[15] : 1.0; const b = g === Grade.Easy ? W[16] : 1.0; const c = Math.exp(W[8]); const alpha = 1.0 + t_d * t_s * t_r * h * b * c; return s * alpha; } function s_fail(d, s, r) { const d_f = Math.pow(d, -W[12]); const s_f = Math.pow(s + 1.0, W[13]) - 1.0; const r_f = Math.exp(W[14] * (1.0 - r)); const c_f = W[11]; const result = d_f * s_f * r_f * c_f; return Math.min(result, s); } function stability(d, s, r, g) { return g === Grade.Forgot ? s_fail(d, s, r) : s_success(d, s, r, g); } function clamp_d(d) { return Math.min(10.0, Math.max(1.0, d)); } function d_0(g) { const g_value = Grade[g]; return clamp_d(W[4] - Math.exp(W[5] * (g_value - 1.0)) + 1.0); } function difficulty(d, g) { return clamp_d(W[7] * d_0('Easy') + (1.0 - W[7]) * dp(d, g)); } function dp(d, g) { return d + delta_d(g) * ((10.0 - d) / 9.0); } function delta_d(g) { const g_value = Grade[g]; return -W[6] * (g_value - 3.0); } function sim(grades) { let t = 0.0; const r_d = 0.9; const steps = []; // Initial review if (grades.length === 0) { throw new Error("Grades cannot be empty"); } let gradesCopy = [...grades]; let g = gradesCopy.shift(); // Remove the first grade let s = s_0(g); let d = d_0(g); let i = Math.max(Math.round(interval(r_d, s)), 1.0); steps.push({ t, s, d, i }); // n-th review for (let g of gradesCopy) { t += i; const r = retrievability(i, s); s = stability(d, s, r, g); d = difficulty(d, g); i = Math.max(Math.round(interval(r_d, s)), 1.0); steps.push({ t, s, d, i }); } return steps; }