{"common":{"appDescription":"Coding assessments with explainable learning evidence.","home":"Home","signOut":"Sign out","loading":"Loading…","saving":"Saving…","save":"Save","saveChanges":"Save changes","cancel":"Cancel","close":"Close","delete":"Delete","remove":"Remove","edit":"Edit","add":"Add","back":"Back","continue":"Continue","confirm":"Confirm","retry":"Try again","copy":"Copy","copied":"Copied","search":"Search","yes":"Yes","no":"No","none":"None","language":"Language","roles":{"TEACHER":"Teacher","STUDENT":"Student"},"justNow":"just now","errors":{"requestFailed":"The request could not be completed.","checkValues":"Check the submitted values.","invalidEmail":"Enter a valid email address.","signInToContinue":"Sign in to continue.","teacherRequired":"Teacher access is required.","adminRequired":"Only organization admins can do this.","notFound":"Not found.","tooManyAttempts":"Too many attempts. Wait 15 minutes and try again.","rateLimited":"Too many requests. Try again later."}},"account":{"footnote":"Coding assessment workspace","visual":{"label":"How Echelio works","eyebrow":"A focused loop","line1":"Read the prompt.","line2":"Write the code.","line3":"See the evidence.","hint":"Sweep your pointer across the field."},"login":{"metaTitle":"Sign in","folderEyebrow":"Folder invitation","classEyebrow":"Class invitation","folderTitle":"Review your invitation.","classTitle":"Join your class.","title":"Welcome back.","folderIntro":"Sign in with the invited teacher account to review and accept the folder invitation.","classIntro":"Sign in to be added automatically, or register if you do not have an account yet.","intro":"Sign in or create a student account to continue to your assessment workspace.","teacherSignUp":"A teacher? <a>Start a free trial</a>"},"form":{"accessLabel":"Account access","signIn":"Sign in","register":"Register","registerLabel":"Create a student account","fullName":"Full name","namePlaceholder":"Your name","email":"Email address","emailPlaceholder":"name@example.com","emailLocked":"This email address is fixed by your class invitation.","password":"Password","passwordHelp":"At least 8 characters.","forgotPassword":"Forgot password?","signingIn":"Signing in…","creatingAccount":"Creating account…","createAccount":"Create student account","signInFailed":"Sign-in failed.","registerFailed":"Registration failed."},"google":{"continue":"Continue with Google","or":"or","chooseMetaTitle":"Finish signing up","chooseEyebrow":"New account","chooseTitle":"Welcome, {name}.","chooseIntro":"You are signing up with <b>{email}</b>. Are you a student or a teacher?","student":"I am a student","studentHelp":"Practise code challenges, join your classes and take tests.","teacher":"I am a teacher","teacherHelp":"Create tests and quizzes for your classes.","teacherTrialHelp":"Start a 14-day free trial of the Teacher plan.","creating":"Creating your account…","teacherClosedTitle":"Teacher accounts open soon","teacherClosedBody":"For now, teachers join through their school. If your school uses Echelio, ask one of its admins to invite {email}.","otherAccount":"Use another account","failed":"Your account could not be created.","errors":{"unavailable":"Google sign-in is not available right now. Use your email and password.","failed":"Google sign-in did not work. Try again, or use your email and password.","expired":"Your Google sign-in took too long or was interrupted. Try again.","unverified":"Google has not confirmed this email address, so it cannot open your account. Sign in with your password instead.","unverifiedNew":"Google has not confirmed this email address, so it cannot be used for an account.","closed":"This account is closed and can no longer sign in.","otherGoogleAccount":"Your account is linked to another Google account. Sign in with that one, or with your password.","linkedElsewhere":"This Google account already signs in to another Echelio account.","passwordNeeded":"Set a password before you disconnect Google, or you could no longer sign in."}},"recovery":{"eyebrow":"Account recovery","forgotMetaTitle":"Forgot password","forgotTitle":"Forgot your password?","forgotIntro":"Enter your account email and we will send you a reset link.","requestLabel":"Request a password reset","sending":"Sending link…","send":"Send reset link","sent":"If an account uses that email address, a password reset link is on its way. It expires in 1 hour.","backToSignIn":"Back to sign in","resetMetaTitle":"Reset password","resetTitle":"Choose a new password.","resetIntro":"Enter a new password for your account.","missingToken":"This reset link is missing its token.","openEmailLink":"Open the link from your reset email, or request a new one.","requestNewLink":"Request a new link","newPassword":"New password","confirmPassword":"Confirm new password","mismatch":"Passwords do not match.","resetting":"Resetting…","reset":"Reset password","resetFailed":"The password could not be reset.","done":"Your password has been reset. Sign in with your new password.","goToSignIn":"Go to sign in"},"profile":{"metaTitle":"Profile","backToOverview":"Back to overview","backToSessions":"Back to sessions","backToProfile":"Back to profile","title":"Profile","intro":"Update the information used for your Echelio account. This is private and is not a public profile.","profileTitle":"Photo and name","profileDescription":"Your picture and name, as people in your school see them.","noPasswordDescription":"You sign in with Google, so your account has no password yet.","googleDescription":"Sign in with your Google account instead of typing a password.","googleStatusConnected":"Connected","googleStatusNotConnected":"Not connected","accountTitle":"Account","accountDescriptionStudent":"The email you sign in with, and your school.","accountDescriptionTeacher":"The email you sign in with, and your organization.","schoolLabel":"School","organizationLabel":"Organization","signOutHelp":"Signs you out on this device only.","sessions":"Sessions","fullName":"Full name","nameHelp":"This name is shown in your account and assessment records.","email":"Email address","emailHelp":"Your sign-in and account recovery email is fixed for now.","updated":"Profile updated.","updateFailed":"Your profile could not be updated.","passwordTitle":"Password","currentPassword":"Current password","newPassword":"New password","newPasswordHelp":"Use at least 8 characters.","confirmPassword":"Confirm new password","passwordUpdated":"Password updated. Other active sessions were signed out.","passwordFailed":"Your password could not be updated.","securityNote":"Updating your password signs out other active sessions.","updating":"Updating…","updatePassword":"Update password","setPasswordBody":"To also sign in with a password, we email a link to {email} so you can set one.","sendSetPasswordLink":"Email me a link","sending":"Sending…","setPasswordSent":"Check your inbox. The link expires in 1 hour.","setPasswordFailed":"The link could not be sent.","googleTitle":"Google","googleConnectedBody":"You can sign in with the Google account {email}.","googleNotConnected":"Sign in once with Continue with Google, using {email}, to connect it.","googleOnly":"Google is how you sign in. To disconnect it, set a password first.","googleDisconnect":"Disconnect Google","googleDisconnecting":"Disconnecting…","googleDisconnected":"Google disconnected. Sign in with your email and password from now on.","googleDisconnectFailed":"Google could not be disconnected.","schoolEyebrow":"Your school","classesTitle":"Your classes","classTeachers":{"one":"Teacher: {names}","other":"Teachers: {names}"},"noClasses":"You are not in a class yet. Open the class link your teacher shares to join one.","classesHelp":"Only your teachers can add you to a class or remove you from one.","languageTitle":"Language","languageHelp":"Echelio uses this language on every device you sign in to.","productNewsTitle":"Product news","productNewsHelp":"Occasional emails from Echelio about what is new."},"languageSwitcher":{"label":"Language","failed":"The language could not be changed."},"productNewsSwitch":{"label":"Emails about new features, a few times a year","help":"Emails about your classes and tests keep coming either way.","failed":"Your choice could not be saved."},"confirmEmail":{"metaTitle":"Confirm your email","eyebrow":"One more step","title":"Check your email.","existingEyebrow":"Your account","existingTitle":"Confirm your email address.","existingIntro":"We will send a 6-digit code to <b>{email}</b>. Once your address is confirmed, you can reset your password if you forget it.","send":"Send code","sending":"Sending…","changePrompt":"Not your address? <button>Change it</button>","changeTitle":"Your correct address","newEmail":"Email","password":"Your password","passwordHelp":"So nobody else can move your account to their inbox.","changeSubmit":"Send the code there","changing":"Sending…","cancel":"Cancel","back":"Back to Echelio","notYou":"Not {email}? <a>Sign out</a>"},"confirmBar":{"text":"Your email address is not confirmed. Confirm it to keep using Echelio.","action":"Confirm"},"avatar":{"title":"Profile picture","help":"JPEG, PNG or WebP, up to 5 MB. It is cropped to a square. People in your school can see it. Without one, a generated avatar is shown.","choose":"Choose a picture","uploading":"Uploading…","remove":"Remove picture","removing":"Removing…","uploaded":"Picture updated.","removed":"Picture removed.","uploadFailed":"The picture could not be uploaded.","removeFailed":"The picture could not be removed.","wrongType":"Choose a JPEG, PNG or WebP picture.","removeStudent":"Remove picture","studentRemoved":"Picture removed.","removeStudentConfirm":"Remove {name}’s picture? They can upload a new one."},"navigation":{"primary":"Primary","overview":"Overview","classes":"Classes","progress":"Progress","questions":"Problems","quizzes":"Quizzes","profile":"Profile","organization":"Organization","account":"Account"},"theme":{"label":"Theme","system":"System","light":"Light","dark":"Dark"},"errors":{"invalidCredentials":"Email or password is incorrect.","tooManySignIns":"Too many sign-in attempts. Wait 15 minutes and try again.","emailInUse":"An account already uses this email. Sign in instead.","tooManyStudentSignUps":"Too many accounts were created from this network in the last hour. Try again later, or use the class link your teacher shares.","invitationNotFound":"This class invitation is not valid.","enterFullName":"Enter your full name.","nameTooLong":"Your name is too long.","passwordTooShort":"Use at least 8 characters for your password.","newPasswordTooShort":"Use at least 8 characters for your new password.","enterCurrentPassword":"Enter your current password.","confirmNewPassword":"Confirm your new password.","passwordsDoNotMatch":"Your new passwords do not match.","currentPasswordIncorrect":"Your current password is incorrect.","passwordIncorrect":"Your password is incorrect.","emailTaken":"Another account already uses this email.","emailAlreadyConfirmed":"This address is already confirmed.","confirmEmailFirst":"Confirm your email address first.","resetTokenRequired":"Reset token is required.","resetLinkInvalid":"This reset link is invalid or has expired. Request a new one.","tooManyResets":"Too many reset requests from this network. Try again later.","invalidLanguage":"Choose English or French.","avatarTooBig":"This picture is larger than 5 MB.","avatarNotImage":"This file is not a JPEG, PNG or WebP picture.","avatarTooMany":"Too many uploads. Try again in an hour.","avatarMissing":"Choose a picture to upload."}},"student":{"backToSessions":"Back to sessions","nav":{"home":"Home","tests":"Tests","quizzes":"Quizzes","leaderboard":"Leaderboard","profile":"Profile","settings":"Account settings"},"shell":{"streakLabel":{"one":"{count} day streak","other":"{count} day streak"}},"home":{"metaTitle":"Home","asideLabel":"Your progress","practisedToday":"You practised today. See you tomorrow.","startStreak":"Solve a problem today to start a streak.","thisWeek":"This week","dayPractised":"{day}: practised","dayMissed":"{day}: no solve","dayAhead":"{day}: still to come","weekGoal":"Weekly goal","solvedTitle":"Solved","summaryLabel":"Your profile: {summary}","summaryRank":"#{rank} in school","points":{"one":"{count} point","other":"{count} points"},"classGoalHelp":"Every first solve in your class counts.","challengeBonus":"The same problem for the whole school today, worth a bonus point.","challengeBonusSolo":"The same problem today for every student practising without a school, worth a bonus point.","bonusPoint":"+1 bonus point today","questionsTitle":"Problems","pickOne":"Pick one"},"tests":{"metaTitle":"Tests","title":"Tests","intro":"Tests and quizzes your teachers give you, and your quiz results.","noTests":"No test is open or coming up. Your teachers assign them here, or give you a code to join one."},"profile":{"metaTitle":"Your profile","editAccount":"Account settings","points":"Points","schoolRank":"School rank","rankOf":"#{rank} of {count}","longest":{"one":"longest streak: {count} day","other":"longest streak: {count} days"}},"settings":{"metaTitle":"Account settings","title":"Account settings","intro":"Your picture, name, language and sign-in. This is private."},"leaderboard":{"intro":"Students of your school, ranked by practice points.","noSchool":"Leaderboards rank the students of one school. Once a teacher adds you to a class, you appear on your school’s leaderboard with every point you have earned.","youTitle":"Your position","tiersTitle":"Tiers","tierFrom":{"one":"from {count} point","other":"from {count} points"},"yourPoints":{"one":"You have {count} point in all.","other":"You have {count} points in all."},"rulesTitle":"How points work","rulesNote":"Each problem earns points once, on its first solve. At most {cap} points a day count on the leaderboard."},"dashboard":{"practice":"Practice","joinTitle":"Join a session","joinIntro":"Use the code shared by your teacher.","quizResultsTitle":"Quiz results","quizResultsIntro":"Your scores and the correct answers.","seeResults":"See results"},"join":{"codeLabel":"Session code","join":"Join","joining":"Joining…","failed":"Could not join this session."},"assigned":{"title":"Assigned to you","intro":"Sessions your teachers have made available.","opening":"Opening…","completed":"Completed","join":"Join","failed":"Could not open this session."},"timer":{"remaining":"{clock} remaining"},"screen":{"checkedIn":"You’re checked in. The test opens at <time></time>.","submittedTitle":"Assessment submitted","timedOutTitle":"Time expired","stoppedTitle":"Session stopped","closedSubmitted":"{name} is closed. Your submitted answers have been recorded.","closedUnsubmitted":"{name} is closed. Your saved draft is available to your teacher as ungraded work. Only submitted answers contribute to your score."},"quizzes":{"metaTitle":"Practice quizzes","title":"Practice quizzes","intro":"Quizzes from your teachers and from Echelio. See the right answer after each question and retake them as often as you like.","privacy":"Your teachers do not see your answers or scores in practice quizzes, and they earn no points.","asideLabel":"Your quiz history","searchLabel":"Search quizzes","searchPlaceholder":"Search by title","pagesLabel":"Quiz pages","matching":{"one":"{count} quiz","other":"{count} quizzes"},"empty":"No quiz is open for practice yet. When one opens, it shows up here.","platformSource":"Echelio","emptySearch":"No quiz matches this search.","tries":{"one":"{count} try","other":"{count} tries"},"notTried":"Not tried yet","best":"Best {score}","inProgress":"In progress","lastTry":"Last try: {score} of {total} points","start":"Start","retake":"Retake","continue":"Continue","startFailed":"The quiz could not be started. Try again.","facts":{"questions":"Questions","points":"Points","best":"Best","tries":"Tries"},"recent":{"title":"Recent tries","score":"{score}/{total}","empty":"Finish a quiz and your scores show up here."},"player":{"back":"Quizzes","progress":"{done} of {total} answered","check":"Check answer","showKey":"Show the key","skip":"Skip","next":"Next question","seeResults":"See results","checking":"Checking…","correct":"Correct","wrong":"Not quite","skipped":"Skipped","correctAnswer":"Correct answer","acceptedAnswers":"Accepted answers","notes":"What to look for","explanation":"Why","selfCheckIntro":"Compare what you wrote with the key, then mark it yourself.","gotIt":"I got it","notQuite":"Not quite","saveFailed":"Your answer could not be saved. Try again.","leaveNote":"You can leave and come back: your try is kept.","hintChoose":"<kbd>1</kbd>–<kbd>{keys}</kbd> to choose · <kbd>Enter</kbd> to check · ","hintSubmit":"<kbd>Enter</kbd> to check · ","startOver":"Start over","restartTitle":"Start over?","restartIntro":"This try ends without a score, and a new one starts with the questions in a new order.","keepGoing":"Keep going"},"summary":{"title":"Quiz finished","score":"{score} of {total} points","newBest":"New best! Your previous best was {previous}.","best":"Your best so far: {best}","yourAnswers":"Your answers","reviewHint":"Open a question to see your answer, the correct one, and why.","tryAgain":"Try again","allQuizzes":"All quizzes","points":{"one":"{count} point","other":"{count} points"}},"errors":{"notFound":"This quiz is not open for practice.","attemptNotFound":"This try was not found.","questionNotFound":"This question was not found.","notCurrent":"This is not the question you are on."}},"practice":{"unavailableTitle":"Practice is unavailable","unavailableFallback":"Practice could not open. Try again in a moment.","metaTitle":"Practice","metaQuestion":"{title} · Practice","status":{"new":"New","attempted":"Attempted","solved":"Solved"},"catalog":{"sessions":"Sessions","stats":"Your stats","leaderboard":"Leaderboard","eyebrow":"Practice","title":"Code challenges","intro":"Solve challenges at your own pace. Practice is never graded and never changes your Progress levels.","teachersSee":"Your teachers see which problems you solved and when, never your code or your failed attempts.","teachersSeeLater":"If a school adds you to a class later, its teachers will see which problems you solved and when, never your code or your failed attempts.","summaryLabel":"Your practice","points":{"one":"point","other":"points"},"solvedOf":{"one":"solved of {count} problem","other":"solved of {count} problems"},"search":"Search","searchPlaceholder":"Problem title","language":"Language","allLanguages":"All languages","difficulty":"Difficulty","allDifficulties":"All difficulties","skill":"Skill","allSkills":"All skills","status":"Status","allStatuses":"All","clear":"Clear filters","matching":{"one":"{count} problem","other":"{count} problems"},"empty":"No problem matches these filters.","pages":"Pages","previous":"Previous","next":"Next","pageOf":"Page {page} of {count}"},"workspace":{"badge":"Practice · not graded","questionInfo":"Problem details","allQuestions":"All problems","worth":{"one":"{count} point for the first solve","other":"{count} points for the first solve"},"solvedFirst":{"one":"Solved! +{count} point.","other":"Solved! +{count} points."},"solvedAgain":"Solved again. Points count the first solve only.","solvedWithBonus":{"one":"Solved! +{count} point, with the daily challenge bonus.","other":"Solved! +{count} points, with the daily challenge bonus."},"notSolved":"{passed} of {total} cases passed. Only a full pass solves the problem.","nextQuestion":"Next problem","attemptsTitle":"Your attempts","noAttempts":"No attempts yet.","descriptionTab":"Description","attemptsTab":"Attempts ({count})","accepted":"Accepted","opening":"Opening the problem…","attemptRun":"Run","attemptSubmit":"Submit","casesPassed":"{passed} / {total} cases","notGraded":"Not graded","grading":"Grading…"},"rewards":{"streakDays":{"one":"day streak","other":"day streak"},"keepStreak":"Solve one today to keep it.","longest":"Longest: {count}","thisWeek":"solved this week","goalMet":"weekly goal met","weeklyStreak":{"one":"{count} week in a row","other":"{count} weeks in a row"},"goalLabel":"Goal","goalOption":{"one":"{count} a week","other":"{count} a week"},"goalFailed":"Could not save your goal.","solved":"problems solved","seeStats":"See your stats","challengeTitle":"Today’s challenge","challengeIntro":"The same problem for the whole school today. Solve it today for a bonus point.","challengeDone":"Bonus earned. Come back tomorrow for a new challenge.","challengeBadge":"Today’s challenge","solvedToday":"Solved today","toNextTier":{"one":"{count} point to {tier}","other":"{count} points to {tier}"},"classGoalTitle":"Your class this week","classGoalIntro":"Every first solve by your classmates counts toward one shared goal: the sum of everyone’s weekly goals.","classGoalCount":"{solved} / {goal} solved","classGoalStudents":{"one":"{count} student","other":"{count} students"},"classGoalMet":"Class goal met. Well done, everyone."},"stats":{"metaTitle":"Your practice stats","title":"Your practice","intro":"Every problem you solved, counted once, on the day you first solved it.","longestStreak":"longest streak","weeksMet":{"one":"week goal met in a row","other":"weeks goal met in a row"},"calendarTitle":"Activity","activeDays":{"one":"{count} day with a first solve this year","other":"{count} days with a first solve this year"},"calendarLabel":{"one":"Activity calendar: {count} active day this year","other":"Activity calendar: {count} active days this year"},"dayTitle":{"one":"{day}: {count} problem solved","other":"{day}: {count} problems solved"},"less":"Less","more":"More","byDifficulty":"By difficulty","bySkill":"By skill","byTopic":"By topic","latestTitle":"Latest attempts","noAttempts":"No attempts yet. Open a problem to start."},"tiers":{"BRONZE":"Bronze","SILVER":"Silver","GOLD":"Gold","PLATINUM":"Platinum","DIAMOND":"Diamond"},"skillSets":{"title":"Skill sets","intro":"Solve every problem of a skill to complete its set.","count":"{solved} / {total} solved","complete":"Complete"},"suggestions":{"title":"Suggested for you","intro":"Problems one level above where your tests put you, in your weakest skills first.","reason":"For {skill}","resumeIntro":"Problems you started and have not solved yet, then new ones at your level.","triedReason":"Started","newReason":"At your level"},"leaderboard":{"metaTitle":"Practice leaderboard","title":"Leaderboard","intro":"Students of your school, ranked by practice points: 1 for an easy problem, 3 for medium, 5 for hard, from each problem’s first solve, plus {bonus} for the daily challenge. At most {cap} points a day count here.","tabsLabel":"Leaderboard period","tabs":{"all":"All time","month":"This month","improved":"Most improved"},"you":{"one":"You are number {rank} of {count} student.","other":"You are number {rank} of {count} students."},"youImproved":{"one":"You are number {rank} of {count} student who improved this month.","other":"You are number {rank} of {count} students who improved this month."},"notRanked":"Solve a problem to appear on the leaderboard.","notImproved":"Earn more points this month than last month to appear here.","rank":"Rank","student":"Student","points":"Points","improvement":"Gain","youBadge":"You","empty":"Nobody has points here yet. Be the first."},"errors":{"studentsOnly":"Practice is for students.","readOnly":"Your school’s Echelio access is read-only, so practice is closed for now.","questionNotFound":"This problem is not open for practice.","invalidGoal":"Choose 1, 3, 5 or 10 problems a week.","invalidTimeZone":"This time zone is not recognised.","tooManyRuns":"You ran a lot of code in the last {minutes} minutes. Wait a moment, then try again."}},"share":{"button":"Share","title":"Share a milestone","intro":"Pick a milestone to make an image for LinkedIn or Instagram. It shows only your name, the milestone and echelio.com.","listLabel":"Your milestones","empty":"No milestone yet. Practise seven days in a row and your first card is ready to share.","earnedOn":"Earned {date}","holdsNow":"This month","back":"All milestones","previewAlt":"Card preview: {title}","cardAlt":"Card: {title}","format":"Format","linkedin":"LinkedIn post","story":"Instagram story","language":"Language of the card and caption","captionLabel":"Caption","captionHelp":"LinkedIn cannot pre-fill a post, so copy this caption and paste it when you share the image.","share":"Share","sharing":"Sharing…","download":"Download image","copyCaption":"Copy caption","captionCopied":"Caption copied","imageFailed":"The image could not be loaded. Try again in a moment.","shareFailed":"Sharing did not open. Download the image instead.","copyFailed":"The caption could not be copied. Select it and copy it by hand.","prompt":{"title":"New milestone","text":"{title}. Do you want to share it?","share":"Share","later":"Not now"},"card":{"eyebrow":"My Echelio practice","titles":{"streak":"{count}-day streak","tier":"{tier} tier","solved":"{count} problems solved","firstHard":"First hard problem solved","top3":"Top 3 in my school this month","skillset":"{skill} skill set complete"},"details":{"streak":"At least one problem solved every day.","tier":"Earned by solving code challenges.","solved":"Code challenges solved, one at a time.","firstHard":"One of the toughest code challenges, solved.","top3":"Among the best of my school on the practice leaderboard.","skillset":"Every practice problem of the skill solved."}},"captions":{"streak":"I just hit a {count}-day coding streak on Echelio. One problem at a time. echelio.com #Echelio #coding","tier":"I just reached the {tier} tier on Echelio by solving code challenges. echelio.com #Echelio #coding","solved":"{count} code challenges solved on Echelio. echelio.com #Echelio #coding","firstHard":"I just solved my first hard code challenge on Echelio. echelio.com #Echelio #coding","top3":"I am in the top 3 of my school’s practice leaderboard on Echelio this month. echelio.com #Echelio #coding","skillset":"I solved every practice problem of the {skill} skill set on Echelio. echelio.com #Echelio #coding"},"errors":{"notFound":"This milestone has not been earned.","invalidCard":"Choose a card format (linkedin or story) and a language (en or fr)."}},"parts":{"code":"Part {number} of {count} · Code","quiz":"Part {number} of {count} · Quiz","recorded":"Leaving this page is recorded","opening":"Opening part {number}…","saved":"Part {number} is saved.","breakTitle":"Part {number} done","nextCode":{"one":"Part {number}: {count} code problem.","other":"Part {number}: {count} code problems."},"nextQuiz":{"one":"Part {number}: {count} quiz question.","other":"Part {number}: {count} quiz questions."},"noReturn":"You cannot go back to part {number}, and the time keeps running.","start":"Start part {number}"},"quizTranslation":{"label":"Quiz language","byAi":{"en":"Translated from English by AI","fr":"Translated from French by AI"},"byTeacher":{"en":"Translated from English by your teacher","fr":"Translated from French by your teacher"},"original":"Original text","showOriginal":"Show original","showTranslation":"Show translation"},"problemTranslation":{"label":"Problem language","byAi":{"en":"Translated from English by AI","fr":"Translated from French by AI"},"byTeacher":{"en":"Translated from English","fr":"Translated from French"},"byAiUnknown":"Translated by AI","original":"Original text","showOriginal":"Show original","showTranslation":"Show translation","translating":"Translating this problem…","unavailable":"Translation unavailable"},"workspace":{"runPrompt":"Run the examples to see public-case output.","timeUp":"Time is up. Your work is saved on this device and will close when you reconnect.","closeFailed":"The session could not be closed.","saveFailed":"Your work could not be saved. Reconnect to try again.","lockFailed":"This problem could not be locked.","unavailable":"Execution service is temporarily unavailable. This attempt will not count against you.","scoreRun":"{percent} of public examples passed.","scoreSubmit":"{percent} of all cases passed.","failSummary":"{count} of {total} cases passed.","gradingSlow":"Grading is taking longer than usual. Your attempt is saved; reload the page to see the result.","stillRunning":"Still running. This is taking longer than usual…","stillGrading":"Still grading. This is taking longer than usual…","running":"Running public examples…","submitting":"Submitting against public and hidden cases…","startFailed":"Execution could not start.","opening":"Opening problem {number}…","previousSaved":"Your previous answer is saved.","practiceComplete":"Practice complete","sessionComplete":"Session complete","practiceDone":"You finished every problem in {name}. Practice is ungraded, so you can start it again whenever you like.","sessionEnded":"{name} has ended. Your latest work was saved automatically, and this session is now closed.","sessionFinished":"{name} is finished. Your answers are saved, and this session cannot be opened again.","practiceAgain":"Practice again","practiceBadge":"Practice · ungraded","compared":"Your code is compared with your classmates’","scored":"Scored assessment","offline":"Offline","untimed":"Untimed","untimedLabel":"Practice is untimed","questions":"Problems","locked":"Locked","examples":"Examples ({count})","example":"Example {number}","standardInput":"Standard input","arguments":"Arguments","expectedOutput":"Expected output","expectedResult":"Expected result","hiddenCases":{"one":"{count} hidden case runs only on submit. Its data is never shown.","other":"{count} hidden cases run only on submit. Their data is never shown."},"constraints":"Constraints","editor":"{language} editor","resizeProblem":"Resize the problem and the editor","resizeResults":"Resize the editor and the results","resizeDrag":"Drag to resize","resizeReset":"Double-click to reset","results":"Results · {message}","passedLabel":"Passed","notPassedLabel":"Not passed","hiddenCase":"Hidden case {number}","outcomeReturned":"{outcome} · returned {value}","phpKeyGaps":"Your array's keys are {keys}: return <code>array_values(…)</code> to number them from 0","phpKeysOutOfOrder":"Your array's keys are out of order: return <code>array_values(…)</code> to number them from 0","pass":"PASS","check":"CHECK","closingAndSaving":"Saving and closing…","saved":"Saved","recovered":"Recovered from this device","savedLocally":"Saved on this device · reconnect to sync","run":"Run examples","runningAction":"Running…","closing":"Closing…","submittingAction":"Submitting…","submit":"Submit solution","failedTitle":"Some tests failed","failedBody":"{summary} Submit this answer anyway? You will not be able to return to this problem.","failedBodyLast":"{summary} Submit this answer anyway? You will not be able to return to this problem, and you will not be able to enter this session again.","keepWorking":"Keep working","finishSession":"Finish session","submitAnyway":"Submit anyway"},"sql":{"tables":"Tables","primaryKey":"primary key","notNull":"not null","references":"references {target}","startingRows":"Starting rows of {table}","check":"Then this check runs","yourResult":"Your result","expected":"Expected","rolledBack":"Your transaction was never committed, so it was rolled back.","pdo":"Your function gets <code>$pdo</code>, a PDO connection to SQLite holding these tables. Errors are thrown as <code>PDOException</code>, and rows come back as associative arrays (<code>PDO::FETCH_ASSOC</code>).","arguments":"Arguments after <code>$pdo</code>","checkAfter":"The check after your function","dialect":{"title":"This runs on SQLite","intro":"It is close to MySQL, with a few differences.","division":"Dividing two whole numbers gives a whole number: <code>5 / 2</code> is 2. Use <code>5 / 2.0</code> for 2.5.","text":"Text comparison is case-sensitive: <code>'a' = 'A'</code> is false. Use <code>lower()</code> to ignore case.","functions":"There is no <code>NOW()</code>, <code>YEAR()</code> or <code>DATE_FORMAT()</code>. Use <code>date('now')</code> and <code>strftime()</code>.","varchar":"<code>VARCHAR(n)</code> lengths are not enforced."},"hints":{"NOW":"SQLite has no NOW() function. Use datetime('now') for the date and time, or date('now') for the date.","CURDATE":"SQLite has no CURDATE() function. Use date('now').","DATE_FORMAT":"SQLite has no DATE_FORMAT() function. Use strftime('%Y-%m', your_date), where the format comes first.","IF":"SQLite has no IF() function. Use iif(condition, a, b) or CASE WHEN.","YEAR":"SQLite has no YEAR() function. Use strftime('%Y', your_date), which gives text.","MONTH":"SQLite has no MONTH() function. Use strftime('%m', your_date), which gives text such as '03'.","DATEDIFF":"SQLite has no DATEDIFF() function. Use julianday(a) - julianday(b) for a number of days.","AUTO_INCREMENT":"SQLite has no AUTO_INCREMENT keyword. Declare the column as INTEGER PRIMARY KEY, which counts up by itself."},"mismatch":{"lastStatement":"Your last statement","checkStatement":"Check statement {number}","unreadable":"The result could not be read.","noStatement":"Your script ran no statement.","resultCount":"Expected {expected} results, got {actual}.","outcome":{"rows":"a result with rows","ok":"a statement that returns no rows","rejected":"a rejection ({constraint})","error":"an error ({message})","message":"{where}: expected {expected}, got {actual}."},"columnCount":"{where}: wrong number of columns (expected {expected}, got {actual}).","columnName":"{where}: column {column} should be named {expected}, not {actual}.","rowCount":"{where}: wrong number of rows (expected {expected}, got {actual}).","value":"{where}: row {row}, column {column}: expected {expected}, got {actual}.","order":"{where}: same rows, different order (this problem needs ORDER BY).","missingRow":"{where}: the row ({row}) is missing."}},"outcomes":{"PASSED":"passed","WRONG_ANSWER":"wrong answer","COMPILE_ERROR":"compile error","RUNTIME_ERROR":"runtime error","TIMEOUT":"timeout","INFRA_ERROR":"infra error"},"workerMessages":{"unavailable":"Execution service is temporarily unavailable.","retrying":"Execution service is busy. Retrying…","ungradable":"This attempt could not be graded. It will not count against you."},"duration":{"minutes":{"one":"{count} minute","other":"{count} minutes"},"hours":{"one":"{count} hour","other":"{count} hours"},"days":{"one":"{count} day","other":"{count} days"},"hoursMinutes":"{hours} h {minutes} min"},"errors":{"chooseStudent":"Choose a student.","sessionNotFound":"Session not found.","draftNotFound":"Draft not found.","idempotencyInUse":"Idempotency key is already in use.","runInProgress":"Your previous run is still being graded. Wait for its result, then try again.","runnerUnavailable":"The code runner is unavailable right now. This attempt was not graded and will not count against you. Try again in a moment.","stillOpen":"This assessment is still open. Submit your work before finishing.","questionNotFound":"Problem not found.","invalidJoinCode":"That join code is invalid, expired, or revoked.","notEnrolled":"You are not enrolled in this cohort.","notAssigned":"This session has not been assigned to you.","alreadyCompleted":"You already completed this session.","submissionNotFound":"Submission not found.","cannotViewSubmission":"You cannot view this submission.","streamFailed":"Could not stream status.","tooManyJoinAttempts":"Too many join attempts. Try again in two minutes.","practiceNotReady":"Practice is not ready. Seed the database and try again.","practiceForbidden":"Practice is available to enrolled students."}},"sessions":{"errors":{"notFound":"Session not found.","invalidAssignment":"Every selected learner must belong to this class.","finalized":"A finalized session cannot be changed.","assignEachOnce":"Assign each student once.","questionOnce":"Each problem can appear only once in a session.","questionsNotPublished":"Every selected problem must be published.","quizNotFound":"Quiz not found.","emptyQuiz":"Add a question to this quiz before giving it as a test.","invalidSchedule":"End time must be after start time.","closesInPast":"The closing time has passed. Choose a later one.","draftNotFound":"Draft not found.","draftGone":"This draft was already published or deleted.","draftLimit":"You have {limit} drafts, the most you can keep. Delete one to save this one.","invalidStudents":"Assign the session only to students of this class.","joinCodeFailed":"Could not allocate a join code.","cohortForbidden":"You do not have access to this cohort.","cohortOwnerRequired":"Only the class owner can delete this class.","sessionForbidden":"Join this session before opening it.","alreadyCompleted":"You already completed this session.","notAcceptingWork":"This session is not accepting work.","notStarted":"The assessment has not started yet.","deadlinePassed":"The submission deadline has passed.","submissionNotFound":"Submission not found.","notASubmit":"Only submitted solutions can lock a problem.","waitForTests":"Wait for the tests to finish.","questionLocked":"This problem is locked. Continue from the current problem.","questionNotFound":"Question not found.","openAnswer":"Grade open answers one by one.","invalidResponse":"This response does not fit the question."},"participation":{"upcoming":"Upcoming","notStarted":"Not started","working":"Working","submitted":"Submitted","timedOut":"Timed out","missed":"Missed","stopped":"Stopped"},"grading":{"noSubmissions":"No submissions","awaitingGrading":"Awaiting grading","executionIssue":"Execution issue","graded":"Graded"},"phase":{"DRAFT":"Draft","SCHEDULED":"Scheduled","LIVE":"Live","CLOSED":"Closed"},"status":{"DRAFT":"draft","PUBLISHED":"published","ACTIVE":"active","CLOSED":"closed","FINALIZED":"finalized"},"shared":{"question":"Question {number}","questions":{"one":"{count} question","other":"{count} questions"},"problems":{"one":"{count} problem","other":"{count} problems"},"points":{"one":"{count} point","other":"{count} points"},"students":{"one":"{count} student","other":"{count} students"},"answers":{"one":"{count} answer","other":"{count} answers"},"tabSwitches":{"one":"{count} tab switch","other":"{count} tab switches"},"away":"{duration} away","provisional":"Provisional","backToResults":"Session results","durationHoursMinutes":"{hours}h {minutes}m","durationMinutesSeconds":"{minutes}m {seconds}s","durationSeconds":"{seconds}s","format":{"CODE":"Code test","QUIZ":"Quiz","MIXED":"Code and quiz"}},"options":{"questionsShuffled":"Questions shuffled","questionsInOrder":"Questions in quiz order","questionsSameOrder":"Same problem order","problemsShuffled":"Problems shuffled","levelsShuffledLong":"Problems easy to hard, shuffled within each level","easyToHardLong":"Problems easy to hard, in the same order for everyone","answersShuffled":"Answers shuffled","answersInOrder":"Answers in quiz order","copyBlocked":"Copy and paste blocked","copyAllowed":"Copy and paste allowed","tabsRecorded":"Tab switches recorded","tabsNotRecorded":"Tab switches not recorded","codeCompared":"Code compared","codeNotCompared":"Code not compared","resultsShownLong":"Score and correct answers shown to students","resultsHiddenLong":"Results hidden from students","resultsShown":"Results shown","resultsHidden":"Results hidden","partsQuizFirst":"Quiz first, then code","partsCodeFirst":"Code first, then quiz","partsQuizFirstShort":"Quiz first","partsCodeFirstShort":"Code first","splitLong":"Code counts {code}, the quiz {quiz}","splitShort":"Code {code} · Quiz {quiz}","mixedQuestionsShuffled":"Quiz questions shuffled; code problems easy to hard, shuffled within each level","mixedQuestionsInOrder":"Quiz questions in quiz order; code problems easy to hard, in the same order for everyone"},"overview":{"title":"Overview","intro":"Scored assessments, participation, and the evidence behind each result.","summaryLabel":"Cohort summary","enrolled":"Enrolled learners","activeTests":"Active tests","withEvidence":"Learners with evidence","published":"Published sessions","recent":"Recent assessments","rowMeta":"{className} · {format} · code <code></code>","format":{"CODE":"code test","QUIZ":"quiz","MIXED":"code and quiz"},"assigned":{"one":"{count} assigned","other":"{count} assigned"},"joined":{"one":"{count} joined","other":"{count} joined"},"empty":"No sessions yet. Publish the first assessment to create a join code.","pages":"Assessment pages"},"drafts":{"title":"Drafts","untitled":"Untitled draft","rowMeta":"{className} · {format}","noProblems":"No problems yet","noQuiz":"No quiz yet","saved":"Saved <time></time>","continue":"Continue","continueLabel":"Continue {name}","delete":"Delete draft","deleteLabel":"Delete {name}","deleteTitle":"Delete this draft?","deleteIntro":"{name} will be deleted. This cannot be undone.","keep":"Keep draft","deleting":"Deleting…","deleteFailed":"The draft could not be deleted.","closeDelete":"Close","pages":"Draft pages"},"display":{"metaTitle":"Class display","codeLabel":"Code {code}","joinLabel":"Join","joinWithCode":"Join with code","lobbyHint":"Go to <b>{host}</b> and enter the code","waiting":"Waiting for students to join…","empty":"No student took this test.","restOfTopTen":"The rest of the top ten","live":"Live","startsAt":"Starts at <time></time>","finalResults":"Final results","joinAt":"Join at <b>{host}</b>","joined":{"one":"{count} joined","other":"{count} joined"},"finished":{"one":"{count} finished","other":"{count} finished"},"topOf":"Top {size} of {joined}","awaitingReview":"Open answers count once they are graded"},"board":{"timeLeft":"Time left","leaderboard":"Leaderboard","placesUp":{"one":" places up","other":" places up"},"placesDown":{"one":" places down","other":" places down"},"done":"Done","topThree":"Top three"},"copyCode":{"label":"Session code","failed":"Copy failed","copiedAria":"Copied session code {code}","copyAria":"Copy session code {code}"},"stop":{"failed":"The session could not be stopped.","button":"Stop session","title":"Stop this session?","body":"Students will be removed from the assessment. Their latest editor draft will be saved automatically.","closeDialog":"Close stop session dialog","keepRunning":"Keep running","stopping":"Stopping…"},"assignments":{"assignFailed":"Students could not be assigned.","assignedCount":{"one":"{count} student assigned.","other":"{count} students assigned."},"unchanged":"Assignments unchanged.","emailsFailed":{"one":"{count} email failed.","other":"{count} emails failed."},"emailsQueued":{"one":"{count} email was queued.","other":"{count} emails were queued."},"emailsSent":{"one":"{count} email was sent.","other":"{count} emails were sent."},"assignStudents":"Assign students","emailsQueuedButton":"Emails queued","classAssigned":"Class assigned","intro":"Students enrolled when the session was published are assigned automatically. Use this list for anyone added later.","closeDialog":"Close assignment dialog","configNote":"Assignments will save, but emails will remain pending until <code></code> is configured.","emailSent":"Email sent","emailFailed":"Email failed","emailQueued":"Email queued","available":"Available","retryFailed":"Retry failed emails","assigning":"Assigning…","assignCount":"Assign {count}","assignSelected":"Assign selected"},"similar":{"title":"Similar code","intro":"Once the test ends, each student’s final code is compared with their classmates’ answers. Only the closest show here.","waiting":"Compared when the test ends.","nothingStandsOut":"Nothing stands out","comparedCount":{"one":"{count} problem compared","other":"{count} problems compared"},"noneCompared":"No problem could be compared.","tooShort":{"one":"Problem {list} is too short to compare.","other":"Problems {list} are too short to compare."},"notEnough":{"one":"Problem {list} has too few answers to compare.","other":"Problems {list} have too few answers to compare."},"problemLine":"Problem {position} · {percent} shared code","problemsLine":"Alike on {count} of {total} problems · up to {percent} shared code","compare":"Compare","compareLabel":"Compare {names}","showMore":{"one":"Show {count} more","other":"Show {count} more"},"back":"Results","pageTitle":"Similar code","alikeOn":{"one":"Alike on {alike} of {count} problem","other":"Alike on {alike} of {count} problems"},"notAlike":"Not alike on any problem compared","group":"Alike as a group of {count}","left":"Left","right":"Right","problems":"Problems","problemTab":"Problem {position}","sharedCode":"{percent} shared code","tooShortTab":"Too short to compare","notEnoughTab":"Too few answers to compare","noAnswer":"No answer to this problem.","submitted":"Submitted <time></time>","savedNotSubmitted":"Saved, not submitted","score":"Score {percent}","notGraded":"Not graded","tabSwitches":{"one":"{count} tab switch · {time} away","other":"{count} tab switches · {time} away"},"noTabSwitches":"No tab switch","sameResult":"Both return {output} on case {position}.","sameResults":"Both return the same wrong results on cases {list}.","sameHidden":{"one":"Both fail hidden case {list} the same way.","other":"Both fail hidden cases {list} the same way."},"legend":"Highlighted: code both answers share, one colour per stretch.","legendStarter":"Faded: the starter code.","help":"Answers can be alike by chance, or because both students used the same source: a tutorial, a classmate, an AI. Only you can tell.","stretches":"Shared stretches","stretchLines":"{left} ↔ {right}","line":"line {line}","lines":"lines {first}–{last}","codeOf":"{name}’s code"},"detail":{"quizSummary":{"one":"Quiz for {className} · {count} question from {source}","other":"Quiz for {className} · {count} questions from {source}"},"codeSummary":{"one":"Code test for {className} · {count} problem","other":"Code test for {className} · {count} problems"},"mixedSummary":"Code and quiz for {className} · {first}, then {second}","mixedPart":{"CODE":{"one":"{count} code problem","other":"{count} code problems"},"QUIZ":{"one":"{count} quiz question from {source}","other":"{count} quiz questions from {source}"}},"quotedTitle":"“{title}”","deletedQuiz":"a deleted quiz","reviewAnswers":{"one":"Review {count} answer","other":"Review {count} answers"},"reviewAnswersIdle":"Review answers","showToClass":"Show to class","exportCsv":"Export CSV","starts":"Starts","ends":"Ends","length":"Length","settings":"Settings","webhook":{"waiting":"Sent to your platform when it ends","sending":"Sending to your platform","sent":"Sent to your platform · <time></time>","failed":"Not sent to your platform","notSent":"Not sent to your platform","log":"Delivery log","send":"Send to your platform","sendFailed":"The results could not be sent."},"assigned":"Assigned","joined":"Joined","submitted":"Submitted","passedAll":"Passed all problems","outcomesTitle":"Student outcomes","outcomesHelp":"Ranked by overall score, then fastest completion. Provisional scores can change.","selectStudent":"Select a student to inspect responses","noStudents":"No students are assigned yet. Assign students to begin collecting responses.","versionsTitle":"Problem versions","versionLine":"Version {version} · content {hash}","weight":"weight {weight}"},"review":{"pickedOptions":"Picked options","correctOption":" (a correct option)","true":"True","false":"False","correctOfTotal":{"one":"{count} of {total} correct","other":"{count} of {total} correct"},"title":"Review answers","toReview":{"one":"{count} answer to review on this question","other":"{count} answers to review on this question"},"markHint":"Mark any answer correct or wrong; scores update straight away.","gradedByAi":{"one":"{count} graded by AI","other":"{count} graded by AI"},"nextToReview":"Next to review","questions":"Questions","questionPending":{"one":"Question {number}, {count} answer to review","other":"Question {number}, {count} answers to review"},"questionOf":"Question {number} of {total}","skips":{"one":"{count} skip","other":"{count} skips"},"picksTitle":"What students picked","picksSummary":"{answers}. Correct options are ticked.","picksSummarySkips":"{answers}, {skips}. Correct options are ticked.","correctSr":" (correct)","combinations":"Combinations","responses":"Responses","combinationsHint":"Identical selections grouped together.","responsesHint":"Identical answers grouped together, ignoring extra spaces and case.","responsesHintCase":"Identical answers grouped together, ignoring extra spaces.","noAnswers":"No answers yet.","acceptNote":"Accept for everyone changes the answers already in. Students still answering are graded automatically, so accept again once the session closes.","studentsTitle":"Every student","studentsSummary":"{answers} from {students}","waitingForReview":"{count} waiting for review","aiHint":"{count} graded by AI. Press Correct or Wrong to confirm or change an AI grade","noStudents":"No students are assigned to this session.","notAnsweredYet":"Not answered yet","notStarted":"Not started","gradeAnswer":"Grade {name}’s answer"},"student":{"scoreLabel":"Score","scoreLine":{"one":"<b>{earned}</b> / {count} point · {percent}","other":"<b>{earned}</b> / {count} points · {percent}"},"noAnswers":"No answers","counts":{"CORRECT":{"one":"{count} correct","other":"{count} correct"},"WRONG":{"one":"{count} wrong","other":"{count} wrong"},"PENDING":{"one":"{count} waiting for review","other":"{count} waiting for review"},"SKIPPED":{"one":"{count} skipped","other":"{count} skipped"},"NOT_REACHED":{"one":"{count} not reached","other":"{count} not reached"}},"gradeAnswer":"Grade {name}’s answer to question {number}","everyoneAnswers":"Everyone’s answers","mixed":{"totalLine":"Total <b>{percent}</b>","partTitle":{"CODE":"Part {number} · Code","QUIZ":"Part {number} · Quiz"},"quizLine":{"one":"{earned}/{count} point · {percent}","other":"{earned}/{count} points · {percent}"},"codeLine":"{passed}/{total} problems passed · {percent}","nothingScored":"Nothing scored yet","share":"Counts {percent} of the total","codeQuestion":"Code problem {number}","best":"Best {percent}","notSubmitted":"Not submitted","notGraded":"Not graded yet","noSubmission":"No submission for this problem."}},"table":{"rank":"Rank","student":"Student","participation":"Participation","inviteEmail":"Invite email","overallScore":"Overall score","questionsPassed":"Problems passed","bestResponse":"Best response","gradedResponses":"Graded responses","firstPass":"First pass","completionTime":"Completion time","tabSwitches":"Tab switches","topScore":"Top score","removed":"Removed","emailSent":"Sent","emailFailed":"Failed","emailQueued":"Queued","ungradedDrafts":{"one":"{count} ungraded draft","other":"{count} ungraded drafts"},"notYet":"Not yet","attempt":"Attempt {number}","studentResponses":"Student responses","assignedOn":"{email} · assigned {date}","closeResponses":"Close student responses","overallScoreSummary":"<b>{value}</b> overall score","questionsPassedSummary":"<b>{value}</b> problems passed","completionTimeSummary":"<b>{value}</b> completion time","gradedResponsesSummary":"<b>{value}</b> graded responses","tabSwitchSummary":{"one":"<b>{count}</b> tab switch","other":"<b>{count}</b> tab switches"},"scoreProvisional":"Score is provisional.","leftPage":"Left the test page · {duration} in total","awayFor":"away {duration}","draftsLabel":"Saved ungraded drafts","draftsTitle":"Saved drafts · ungraded","draftsHelp":"This saved work differs from the latest submitted response, or has never been submitted. It does not affect the score.","savedAt":"Saved {date}","ungradedDraft":"Ungraded draft","savedDraft":"Saved draft · ungraded","lastGraded":"Last graded submission","submittedAt":"Submitted {date}","noGradedSubmission":"No graded submission for this problem.","loadFailed":"This response could not be loaded. Close and reopen it to try again.","submittedCode":"Submitted code","caseResults":"Case results","case":"Case {number}","input":"Input","expected":"Expected","returned":"Returned","error":"Error","logs":"Logs","sqlData":"Case data","sqlCheck":"Check","sqlDifference":"Difference","expectedCheck":"Expected check","returnedCheck":"Check results","noResponse":"This student has not submitted a response yet.","attemptStatus":{"QUEUED":"queued","RUNNING":"running","COMPLETED":"completed","INFRA_ERROR":"infra error"},"visibility":{"PUBLIC":"public","HIDDEN":"hidden"},"caseOutcome":{"PASSED":"passed","WRONG_ANSWER":"wrong answer","COMPILE_ERROR":"compile error","RUNTIME_ERROR":"runtime error","TIMEOUT":"timeout","INFRA_ERROR":"infra error"}},"export":{"rank":"rank","student":"student","email":"email","joined":"joined","participation":"participation","grading":"grading","provisional":"provisional","scorePoints":"score_points","totalPoints":"total_points","scorePercent":"score_percent","correct":"correct","wrong":"wrong","toReview":"to_review","skipped":"skipped","notReached":"not_reached","completionTimeMinutes":"completion_time_minutes","tabSwitches":"tab_switches","timeAwayMinutes":"time_away_minutes","overallScorePercent":"overall_score_percent","questionsPassed":"questions_passed","totalQuestions":"total_questions","completedAttempts":"completed_attempts","bestResponseScorePercent":"best_response_score_percent","firstQuestionPassAttempt":"first_question_pass_attempt","timeToFirstQuestionPassMinutes":"time_to_first_question_pass_minutes","totalScorePercent":"total_score_percent","codeScorePercent":"code_score_percent","codeQuestionsPassed":"code_questions_passed","quizPoints":"quiz_points","quizTotalPoints":"quiz_total_points","quizScorePercent":"quiz_score_percent","outcomes":{"CORRECT":"correct","WRONG":"wrong","PENDING":"to_review","SKIPPED":"skipped","NOT_REACHED":"not_reached"}},"builder":{"newSession":"New session","assignQuiz":"Assign quiz","createClassFirst":"Create a class first","close":"Close session builder","stepperLabel":"Session setup progress","stepCompleted":", completed","steps":{"details":"Details","quiz":"Quiz","questions":"Problems","options":"Options","review":"Review"},"descriptions":{"detailsQuiz":"Choose what learners answer, pick a class, and set when it is open.","detailsCode":"Choose what learners answer, name the session, pick a class, and set when it is open.","quiz":"Pick the quiz learners will answer. They get a copy, so later edits to the quiz don’t change this test.","quizMixed":"Pick the quiz that makes up the other part. Learners get a copy, so later edits to the quiz don’t change this test.","questions":"Narrow the bank with filters, then pick what learners will answer.","questionsMixed":"Narrow the bank with filters, then pick the code problems for this test.","optionsQuiz":"Choose how questions appear, what the test blocks and records, and what learners see afterwards.","optionsCode":"Choose the problem order and what the test blocks and records while learners work.","optionsMixed":"Choose which part comes first and how much each counts, then how problems and questions appear, what the test blocks and records, and what learners see afterwards.","review":"Check everything once more, then publish it to the class."},"next":{"quiz":"Choose a quiz","questions":"Choose problems","options":"Set options","review":"Review"},"duration":{"days":"{count} d","hours":"{count} h","minutes":"{count} min","zero":"0 min"},"difficulty":{"EASY":"Easy","MEDIUM":"Medium","HARD":"Hard"},"easyCount":{"one":"{count} easy","other":"{count} easy"},"mediumCount":{"one":"{count} medium","other":"{count} medium"},"hardCount":{"one":"{count} hard","other":"{count} hard"},"allTopics":"All topics","topicsSelected":{"one":"{count} selected","other":"{count} selected"},"nameRequired":"Give the session a name.","nameTooShort":"Use at least {min} characters.","closingBeforeOpening":"Choose a closing time after the opening time.","everyStudentIn":"Every student in {className}","questionsLoadFailed":"Problems could not be loaded.","quizzesLoadFailed":"Quizzes could not be loaded.","createFailed":"Session could not be created.","chooseQuizToContinue":"Choose a quiz to continue.","selectQuestionToContinue":"Select at least one problem to continue.","chooseQuizToPublish":"Choose a quiz before publishing.","selectQuestionToPublish":"Select at least one problem before publishing.","publishedTitle":"Session published","publishedWhole":{"one":"“{name}” is ready and assigned to {count} student in this class.","other":"“{name}” is ready and assigned to {count} students in this class."},"publishedSome":{"one":"“{name}” is ready and assigned to {count} student.","other":"“{name}” is ready and assigned to {count} students."},"emailsSending":"Assignment emails are being sent.","emailsPending":"Assignment emails are pending until email delivery is configured.","done":"Done","viewSession":"View session","formatLegend":"What will learners answer?","codeTest":"Code test","codeTestHint":"Coding problems, graded by running tests.","quiz":"Quiz","quizHint":"Choice, short, and open answers from one of your quizzes.","codeAndQuiz":"Code and quiz","codeAndQuizHint":"Code problems and one quiz, in two parts, scored together.","name":"Name","namePlaceholder":"e.g. Week 3 · Loops check-in","nameMixedHint":"Leave it empty to use the quiz’s title.","class":"Class","assignedTo":"Assigned to","wholeClass":"Assign to the whole class instead","whenOpen":"When is it open?","opens":"Opens","closes":"Closes","lengthLabel":"Session length","openFor":"Open for {duration}","quizTitle":"Quiz title","quizzesYouCanGive":"Quizzes you can assign","sharedBy":"Shared by {name}","noQuestionsYet":"No questions yet","loadingQuizzes":"Loading quizzes…","noQuizMatches":"No quiz matches this search.","noQuizzes":"You have no quizzes yet. <link>Write one in Quizzes</link>, then assign it from there.","titleOrTopic":"Title or topic","difficultyLabel":"Difficulty","anyFeminine":"Any","anyMasculine":"Any","skill":"Skill","language":"Language","folder":"Folder","allFolders":"All folders","topics":"Topics","topicsAria":"Topics: {label}","searchTopics":"Search topics","noTopicsMatch":"No topics match your search.","noTopics":"No topics yet.","clearTopics":"Clear topics","selectedCount":{"one":"{count} selected","other":"{count} selected"},"libraryOnly":"My library only","clear":"Clear","pickAtRandom":"Pick at random","pickAtRandomHint":"Replace the selection with 2 easy, 2 medium, and 1 hard problem","publishedQuestions":"Published problems","loadingQuestions":"Loading published problems…","noQuestionsMatch":"No published problems match these filters. Clear a filter or create matching problems first.","loadingMore":"Loading more problems…","preview":"Preview","previewProblem":"Preview “{title}”","loadingPreview":"Loading the problem…","previewFailed":"The problem could not be loaded.","showing":{"one":"Showing {shown} of {count} matching problem","other":"Showing {shown} of {count} matching problems"},"partsLegend":"Parts","quizFirst":"Quiz first","quizFirstHint":"Then the code problems. Recommended: students who spend their time on code have still answered the quiz.","codeFirst":"Code first","codeFirstHint":"Then the quiz.","splitLegend":"Score split","splitLabel":"How much the code part counts","splitValueText":"Code {code}, quiz {quiz}","splitHint":"Each part is scored on its own, then the two are combined using these shares.","orderLegend":"Order","shuffleQuestions":"Shuffle question order","shuffleProblems":"Shuffle problem order","shuffleQuestionsHint":"Each learner gets the questions in their own order, so neighbours are rarely on the same one.","shuffleQuestionsCodeHint":"Problems always go from easy to hard. Within each level, each learner gets their own order, so neighbours are rarely on the same one.","shuffleQuestionsMixedHint":"Each part follows its own rule: the quiz part in any order, the code part easy to hard, shuffled within each level.","shuffleAnswers":"Shuffle answer order","shuffleAnswersHint":"The options of each choice question appear in a different order for each learner. True or false keeps its order.","shuffleAnswersMixedHint":"Covers the quiz part. The options of each choice question appear in a different order for each learner. True or false keeps its order.","antiCheat":"Anti-cheat","blockCopy":"Block copy and paste","blockCopyQuizHint":"Learners cannot copy questions or paste answers while the test is open.","blockCopyCodeHint":"Learners cannot copy, cut, paste, or drop text while the test is open, and the editor’s right-click menu is off.","recordTabs":"Record tab switches","recordTabsHint":"Each time a learner leaves the test for another tab or window, the session page shows when and for how long. Learners are told it is recorded.","compareCode":"Compare code across the class","compareCodeHint":"After the test, the closest answers are shown side by side. Learners are told.","afterTest":"After the test","showResults":"Score and correct answers","showResultsHint":"Learners see their score when they finish. Once the session closes, they also see each correct answer and its explanation.","showResultsMixedHint":"Covers the whole test. When they finish, learners see their total and each part’s score. Once the session closes, they also see each correct quiz answer and its explanation.","hideResults":"Don’t show results","hideResultsHint":"Learners only see that their answers are recorded: no score, no correct answers. You can assign the same quiz again.","hideResultsMixedHint":"Learners only see that their answers are recorded: no scores, no correct answers.","editDetails":" details","editQuiz":" quiz","editQuestions":" problems","editOptions":" options","untitled":"Untitled session","open":"Open","translationPending":{"one":"{count} question is still being translated. Students who read the other language will see it in the original.","other":"{count} questions are still being translated. Students who read the other language will see them in the original."},"quizSummaryShuffled":"each learner gets their own order","quizSummaryInOrder":"learners see them in quiz order","noQuizChosen":"No quiz chosen","reviewPartQuiz":"Part {number} · Quiz","reviewPartCode":"Part {number} · Code","quizTitleLabel":"Title","inThisOrder":"{mix} · learners see them in this order","inLevelOrder":"{mix} · easy to hard, each learner in their own order within a level","publishing":"Publishing…","publish":"Publish session","draft":{"save":"Save draft","saving":"Saving…","saved":"Saved","savedStatus":"Draft saved.","savedFindIt":"Draft saved. Find it on the <link>Overview</link>.","saveFailed":"The draft could not be saved.","closeTitle":"Save as a draft?","closeBody":"Keep what you picked and finish this session later from the Overview.","keepEditing":"Keep editing","discard":"Discard","opening":"Opening draft","loading":"Loading the draft…","openFailed":"This draft could not be opened.","removed":"Some choices are no longer available and were taken out: {items}.","removedProblems":{"one":"{count} problem","other":"{count} problems"},"removedQuiz":"the quiz","removedStudents":{"one":"{count} student","other":"{count} students"},"movedToNow":"The opening time had passed, so it was moved to now. The session keeps its length."}}},"questions":{"page":{"title":"Problems","intro":"Browse the published problem bank, create original problems, and keep the ones you reuse in your library and shared folders."},"tabs":{"label":"Problem views","bank":"Problem bank","library":"My library"},"pagination":{"label":"Problem pages","previous":"Previous","next":"Next"},"pageOf":"Page {page} of {pageCount}","difficulty":{"EASY":"Easy","MEDIUM":"Medium","HARD":"Hard"},"labels":{"title":"Title","difficulty":"Difficulty","topics":"Topics","constraints":"Constraints","starterCode":"Starter code","referenceSolution":"Reference solution","skills":"Skills","testCases":"Test cases","standardInput":"Standard input","arguments":"Arguments","expectedOutput":"Expected output","expectedResult":"Expected result","publicExample":"Public example","hiddenCase":"Hidden case"},"bank":{"title":"Problem bank","showing":{"one":"Showing {shown} of {count} published problem","other":"Showing {shown} of {count} published problems"},"filterQuery":"with “{query}” in the title","filterLanguage":"in {language}","filterFolder":"in {folder}","thisFolder":"this folder","filterIncluded":"about {topics}","filterExcluded":"without {topics}","emptyFiltered":"No problems match these filters yet. Clear a filter or create a matching problem.","empty":"No problems yet. Create the first published problem."},"filters":{"searchPlaceholder":"Problem title","allDifficulties":"All difficulties","language":"Language","allLanguages":"All languages","includeTopics":"Include topics","excludeTopics":"Exclude topics","allTopics":"All topics","noExcludedTopics":"No excluded topics","selected":"{count} selected","noTopics":"No topics yet.","clearSelection":"Clear selection","folder":"Folder","allFolders":"All folders","clear":"Clear"},"list":{"meta":{"one":"version {version} · {count} case","other":"version {version} · {count} cases"},"platform":"Platform library","versions":{"one":"{count} version","other":"{count} versions"},"usedIn":"used in {count}","question":"Problem"},"translationPanel":{"tabsLabel":"Problem language","original":"Original","translation":"Translation","into":{"en":"English translation","fr":"French translation"},"byAi":"Translated by AI","editedBy":"Edited by {name}","edited":"Edited by a teacher","loading":"Loading the translation…","translating":"Translating…","unavailable":"No translation for now: AI is not available for this problem, or translating it failed.","loadFailed":"Could not load the translation.","edit":"Edit","translateAgain":"Translate again","confirmReplace":"Translate again? This replaces the edited translation.","titleLabel":"Title","promptLabel":"Statement","constraintsLabel":"Constraints","constraintsHelp":{"one":"One per line, as many as the original: {count}.","other":"One per line, as many as the original: {count}."},"codeHelp":"Keep the code between backticks exactly as in the original.","save":"Save","saving":"Saving…","cancel":"Cancel","saveFailed":"Could not save the translation."},"preview":{"title":"Student preview","close":"Close student preview","untitled":"Untitled problem","addPrompt":"Add a problem statement.","publicExamples":"Public examples","exampleArguments":"Example {number} · Arguments","exampleStandardInput":"Example {number} · Standard input","exampleData":"Example {number} · Starting data","exampleRows":"Example {number} · Rows","sqlSetup":"Tables"},"sqlResult":{"rows":"Result rows","noRows":"No rows.","moreRows":{"one":"{count} more row not shown.","other":"{count} more rows not shown."},"ok":"Runs without returning rows.","rejected":"Rejected ({constraint}).","error":"Error: {message}","noStatement":"No statement ran.","statement":"Check statement {number}"},"history":{"loadFailed":"Version history could not be loaded.","deleteFailed":"Problem could not be deleted.","confirmDelete":"Delete “{title}” and all its versions? This cannot be undone.","hide":"Hide versions","view":"View versions","delete":"Delete problem","loading":"Loading versions…","unpublished":"unpublished","summary":{"one":"Version {version} · {title} · {date} · used in {count} session","other":"Version {version} · {title} · {date} · used in {count} sessions"},"difficulty":"Difficulty:","topics":"Topics:","hiddenCase":"Hidden {position}","publicCase":"Public {position}"},"libraryButton":{"failed":"The library could not be updated.","updating":"Updating…","remove":"Remove from my library","save":"Save to my library"},"folderButton":{"loadFailed":"Folders could not be loaded.","addFailed":"Problem could not be added.","removeFailed":"Problem could not be removed.","removing":"Removing…","remove":"Remove from folder","add":"Add to folder","pickerHelp":"A problem can belong to more than one folder.","closePicker":"Close folder picker","added":"Added","noFolders":"You have no folders yet. <link>Create one in My library.</link>"},"skills":{"loadFailed":"Skills could not be loaded.","saveFailed":"Skills could not be saved.","notTagged":"Not tagged yet.","edit":"Edit skills","intro":"Tag “{title}” with what it assesses. Tags are shared with your organization's teachers and stay on new versions.","close":"Close skill picker","none":"Your organization has no skills yet. An organization admin adds them on the Organization page.","save":"Save skills"},"library":{"foldersTitle":"Folders","foldersIntro":"Choose a folder to see its problems or manage collaborators.","ownedByYou":"Owned by you","sharedBy":"Shared by {name}","questionCount":{"one":"{count} problem","other":"{count} problems"},"collaboratorCount":{"one":"{count} collaborator","other":"{count} collaborators"},"openFolder":"Open folder","noFolders":"No folders yet. Create one to group problems and share it with another teacher.","savedTitle":"Personal saved problems","savedCount":{"one":"{count} problem saved for your own quick access","other":"{count} problems saved for your own quick access"},"emptyList":"Your library is empty. Browse the problem bank and save the problems you want to reuse."},"folder":{"yours":"Your folder","browse":"Browse problems","questionsTitle":"Folder problems","questionsIntro":"Everyone in this folder can add and remove problems.","empty":"This folder is empty. Browse the problem bank and use Add to folder on a problem."},"newFolder":{"failed":"Folder could not be created.","button":"New folder","title":"New library folder","intro":"Collect problems around a topic, class, or teaching plan.","close":"Close folder form","name":"Folder name","placeholder":"JavaScript foundations","creating":"Creating…","create":"Create folder"},"manage":{"renameFailed":"Folder could not be renamed.","renamed":"Folder renamed.","inviteFailed":"Invitation could not be created.","inviteSent":"Invitation emailed to {email}. The folder will appear after they accept.","resendFailed":"The email could not be sent. Their existing access remains; try again later.","invitePending":"Invitation is pending, but the email could not be sent. Resend it later.","cancelFailed":"Invitation could not be canceled.","canceled":"Invitation canceled.","removeFailed":"Collaborator could not be removed.","removed":"Collaborator removed.","linkCopied":"Folder link copied. Only its collaborators can open it.","copyThisLink":"Copy this link: {url}","deleteFailed":"Folder could not be deleted.","leaving":"Leaving…","leave":"Leave folder","open":"Manage & share","title":"Manage {name}","intro":"Collaborators can add and remove problems in this folder.","close":"Close folder settings","folderName":"Folder name","saveName":"Save name","collaborators":"Collaborators","inviteIntro":"Invite an existing teacher by email. The folder appears in their library only after they accept.","teacherEmail":"Teacher email","emailPlaceholder":"teacher@example.com","sendInvitation":"Send invitation","pending":"{name} · Pending","emailFailed":"The email could not be sent","expired":"Invitation expired","waiting":"Waiting for acceptance","resend":"Resend","active":"Active collaborators","requireAcceptance":"Require acceptance","removeAria":"Remove {name}","onlyYou":"Only you can access this folder so far.","copyLink":"Copy folder link","delete":"Delete folder","deleteTitle":"Delete {name}?","deleteIntro":"The folder and its collaborator access will be removed. Problems in the bank and personal libraries stay available.","closeDelete":"Close delete confirmation","keep":"Keep folder","deleting":"Deleting…"},"invite":{"failed":"Could not accept the invitation.","title":"Join {folder}?","intro":"{owner} invited you to collaborate on this problem folder. It will appear in your library after you accept.","notNow":"Not now","accepting":"Accepting…","accept":"Accept invitation"},"invitePage":{"unavailableTitle":"Invitation unavailable.","unavailableText":"This link is invalid or expired. Ask the folder owner to resend the invitation.","wrongAccountTitle":"Different account required.","wrongAccountText":"This invitation was sent to {email}. Sign in with that teacher account to accept it.","goBack":"Go back"},"builder":{"explain":"Explain {label}","loadFailed":"Problem details could not be loaded.","validationFailed":"Problem validation could not be completed.","createFailed":"Problem could not be created.","created":"Created and saved “{title}”.","published":"Published version {version} of “{title}”.","newQuestion":"New problem","duplicateToEdit":"Duplicate to edit","editTitle":"Edit {title}","duplicateTitle":"Duplicate {title}","createTitle":"Create a problem","editIntro":"Your changes will publish version {version}. Existing sessions keep their version.","duplicateIntro":"Review the copy, then create it as your own problem. The original will stay unchanged.","createIntro":"Add at least two public examples and one hidden case. Publication checks every case against the reference solution.","close":"Close problem builder","titleHelp":"The short problem name students and teachers see in lists.","titlePlaceholder":"Count distinct values","copySuffix":"(copy)","difficultyHelp":"Controls how the problem is grouped for balanced random session selection.","languageHelp":"Each problem has one language. Publishing another version cannot change it.","languageFunction":"JavaScript · function","javaFormat":"Java problem format","javaFormatHelp":"Method problems test arguments and return values. Complete programs test standard input and output.","javaMethod":"Method with arguments (recommended)","javaProgram":"Complete program · stdin/stdout","languageSql":"SQL · SQLite","languagePython":"Python 3.14","pythonFormat":"Python problem format","pythonFormatHelp":"Function problems test arguments and return values. Complete programs read with input() and are checked on what they print.","pythonFunction":"Function with arguments (recommended)","pythonProgram":"Complete program · input()/print()","languagePhp":"PHP 8.5","phpFormat":"PHP problem format","phpFormatHelp":"Function problems test arguments and return values. Complete programs read standard input with fgets(STDIN) and are checked on what they print. Database problems call the function with PDO $pdo, on SQLite holding your tables.","phpFunction":"Function with arguments (recommended)","phpProgram":"Complete program · STDIN/echo","phpDatabase":"Database · PDO","phpTables":"Tables","phpTablesHelp":"The CREATE TABLE statements every case starts from, on SQLite. Students see these tables. Each case adds its own rows.","phpOrderedHelp":"On: a returned list and the check's rows must come in the reference's order. Off: the same items in any order pass.","databaseArgumentsLabel":"Arguments after $pdo, as JSON array","databaseArgumentsHelp":"A JSON array of the arguments passed after $pdo, such as [\"Lyon\"], or [] when the function only takes $pdo.","caseRows":"Rows","caseRowsHelp":"Statements run after the tables are created and before the function, usually INSERTs giving this case its rows.","caseCheckOptional":"Check (optional)","caseCheckDatabaseHelp":"Statements run after the function, such as SELECT * FROM orders ORDER BY id after an insert. Each statement's result is compared as in SQL problems. Leave it empty when the function only reads.","expectedReturn":"Expected return value","expectedCheck":"Expected check results","sqlTask":"Kind of SQL problem","sqlTaskHelp":"Query: students write a SELECT on existing tables. Change data: students write INSERT, UPDATE or DELETE, and a check reads the tables afterwards. Design tables: students write CREATE TABLE, and a check inserts rows that must be accepted or rejected.","sqlTasks":{"QUERY":"Query","CHANGE":"Change data","SCHEMA":"Design tables"},"sqlSetup":"Setup","sqlSetupHelp":"The CREATE TABLE statements every case starts from. Students see these tables. Each case adds its own rows.","sqlOptions":"Comparison","sqlOrdered":"Order matters","sqlOrderedHelp":"On: rows must come in the reference's order. Off: the same rows in any order pass. Turned on when the reference's last query ends with ORDER BY.","sqlColumnNames":"Column names matter","sqlColumnNamesHelp":"On: result columns must have the reference's names (any case), for prompts that ask for aliases. Off: columns are compared by position.","caseData":"Case data","caseDataHelp":"Statements run after the setup and before the student's script, usually INSERTs giving this case its rows.","caseCheck":"Check","caseCheckHelp":"Statements run after the student's script. Each statement's result is compared: rows, or whether a row was accepted or rejected and by which constraint.","expectedResults":"Expected results","notRunYet":"Not filled yet. Choose Run the reference below.","promptPlaceholderSql":"Name the tables and say exactly which columns and rows the result must have.","methodName":"Method name","functionName":"Function name","functionNameHelp":"The exact method or function name the grader calls for every test case.","topicsHelp":"Comma-separated lesson tags used to filter problems when creating a session.","topicsPlaceholder":"arrays, sets","prompt":"Prompt","promptHelp":"The complete problem statement shown to students, including the input and expected output. Markdown works: `code`, **bold**, lists and code blocks. Check it with Student preview.","promptPlaceholderProgram":"Describe the standard input and exact standard output.","promptPlaceholderMethod":"Describe what the method receives and returns.","promptPlaceholderFunction":"Describe what the function receives and returns.","constraintsHelp":"One rule per line, such as naming requirements, edge cases, or forbidden mutations.","constraintsPlaceholder":"One requirement per line\nDo not mutate the input","starterCodeHelp":"The editable code students receive when they open the problem.","referenceSolutionHelp":"A trusted solution used to verify every public and hidden case.","case":"Case {number}","visibility":"Visibility","argumentsLabel":"Arguments as JSON array","argumentsHelp":"A JSON array of arguments passed to the method or function.","stdinHelp":"Text sent to the program on standard input. Newlines are preserved.","expectedJson":"Expected JSON value","expectedJsonHelp":"The valid JSON result expected when the method or function runs with these arguments.","expectedStdout":"Expected standard output","expectedStdoutHelp":"Expected standard output. Line endings and one final newline are normalized; other whitespace matters.","removeCaseAria":"Remove case {number}","removeCase":"Remove case","addCase":"Add test case","caseCount":"{count}/30 cases · At least two public examples and one hidden case are required.","check":{"label":"Problem validation","eyebrow":"Before publishing","title":"Check the answer key","intro":"Run your reference solution against every public and hidden case.","checking":"Checking cases…","validate":"Validate problem","progress":"Checking {count} cases. This may take a moment.","couldNotFinish":"Validation could not finish","ready":"Ready to publish","needsAttention":"Some cases need attention","passedCount":{"one":"{passed} of {count} cases passed.","other":"{passed} of {count} cases passed."},"matches":"The expected results match your reference solution.","review":"Review the failed cases below.","results":"Test case results","passed":"Passed","failed":"Failed","footnote":"Publishing checks the latest edits again.","introSql":"Run your reference solution on every case. Its results become the expected results: read them in each case before publishing.","runReference":"Run the reference","running":"Running the reference…","filled":"Expected results filled","filledDetail":"Read each case's expected results above, then publish."},"publishing":"Validating and publishing…","publishNew":"Publish new version","createCopy":"Create my copy","create":"Create problem"},"validation":{"timeout":"Reference solution exceeded the execution time limit.","matches":"Reference solution matches the expected result.","mismatch":"Expected {expected}; returned {returned}.","sqlFilled":"Expected results filled from the reference solution.","sqlNotRun":"No expected results yet. Run the reference.","sqlChanged":"The reference solution no longer gives the expected results. Run the reference again.","phpBuiltinName":"{name} is a PHP built-in function, which PHP cannot declare again. Choose another function name."},"generator":{"open":"Generate with AI","title":"Generate with AI","intro":"The AI writes one problem and runs its reference solution on every case.","close":"Close Generate with AI","briefLabel":"What should this problem practise?","briefPlaceholder":"Loops over a list: count the values above a limit","languageLabel":"Written in","languages":{"en":"English","fr":"French"},"write":"Write problem","writing":"Writing…","progress":"Writing and checking the problem… {elapsed}","stop":"Stop","failed":"The problem could not be written. Try again.","confirmReplace":"Replace what you changed in the form with a new problem?","confirmStop":"Stop writing the problem?","writtenPassed":"“{title}” is written, and its reference solution passes every case. Read it before you publish.","writtenFilled":"“{title}” is written, and its expected results are filled from the reference solution. Read them before you publish.","writtenFailed":{"one":"“{title}” is written, but its reference solution still fails {count} case. See the check below.","other":"“{title}” is written, but its reference solution still fails {count} cases. See the check below."},"writtenUnchecked":"“{title}” is written, but the check could not run. Check the reference solution before you publish.","briefRequired":"Describe what the problem should practise.","briefTooLong":"Keep the description under 500 characters.","rateLimited":"You can generate {limit} times an hour. Try again later.","allowanceUsed":"Your organization has used this month's AI generations. They reset on {date}.","noProblem":"Its answer held no problem.","brokeRules":"The AI could not write a problem that follows the builder's rules. {reason} Try again.","timeout":"The AI took too long to write the problem. Try again.","truncated":"The AI's answer was cut off before the end. Try again."},"translation":{"unsupportedText":"This problem's text contains ⟦ or ⟧, which translation cannot handle.","invalidAnswer":"The translation came back incomplete.","codeChanged":"The translation changed the code in the problem, so it was not kept.","codeEdited":"Keep the code exactly as in the original. You can move it within a sentence, not change it.","constraintCount":"Keep one translated constraint for each constraint of the original.","titleLength":"Titles must be 1 to 150 characters.","promptLength":"The statement must be 1 to 6,000 characters.","constraintLength":"Each constraint must be 1 to 400 characters.","unavailable":"Translation is not available for this problem.","sameLanguage":"This problem is already written in that language.","editOwnerOnly":"Only the teacher who wrote this problem can change its translation.","tooManyRetranslations":"You asked for many translations in the last hour. Try again later."},"errors":{"invitationNotFound":"Invitation not found.","leaveYourself":"You can only leave this folder yourself.","collaboratorNotFound":"Collaborator not found.","teacherNotFound":"No active teacher account uses that email.","alreadyOwner":"You already own this folder.","alreadyCollaborating":"This teacher already collaborates on this folder.","folderNotFound":"Library folder not found.","folderOwnerOnly":"Only the folder owner can manage sharing and settings.","folderInvitationInvalid":"This folder invitation is invalid or expired. Ask the owner to resend it.","folderInvitationAccount":"Sign in with the invited teacher account to accept this folder.","folderInvitationGone":"This invitation is no longer available.","folderName":"Folder names must be 2 to 80 characters.","publishedQuestionNotFound":"Published problem not found.","questionNotFound":"Problem not found.","publishOwnerOnly":"Only the problem creator can publish a new version. Duplicate it to make your own copy.","languageLocked":"A problem's language cannot change. Create a new problem for another language.","versionConflict":"This problem was just updated in another tab or by another request. Reload it and try again.","deleteOwnerOnly":"Only the problem creator can delete it.","questionUsed":"This problem has been used in a session and must remain available for its assessment record.","questionReferenced":"This problem is still referenced and cannot be deleted.","chooseEachSkillOnce":"Choose each skill once.","invalidSkill":"Choose skills from your organization's list.","titleLength":"The title must be 4 to 100 characters.","topicsLength":"Topics must be 1 to 200 characters.","promptLength":"The prompt must be 20 to 4000 characters.","constraintsLength":"Constraints must be 3 to 2000 characters.","starterCodeLength":"The starter code must be 10 to 20000 characters.","referenceSolutionLength":"The reference solution must be 10 to 20000 characters.","caseCount":"A problem needs 3 to 30 test cases.","caseSize":"Each test case input and output can have up to 5000 characters.","functionNameInvalid":"Enter a valid JavaScript function name.","javaProgramMain":"Java programs must define class Main in both the starter code and reference solution.","javaMethodSignature":"Java method problems need matching static method signatures in class Solution in both code fields.","twoPublic":"At least two public examples are required.","oneHidden":"At least one hidden case is required.","javascriptCases":"JavaScript cases need JSON arguments and a JSON result.","pythonCases":"Python function cases need JSON arguments and a JSON result.","pythonFunctionName":"Enter a valid Python function name, such as count_words.","pythonFunctionMissing":"Define the function with def and its exact name in both the starter code and the reference solution.","phpOpenTag":"PHP code must start with <?php, in both the starter code and the reference solution.","phpCases":"PHP function cases need JSON arguments and a JSON result.","phpFunctionName":"Enter a valid PHP function name, such as countWords.","phpFunctionMissing":"Declare the function at the start of a line, with function and its exact name, in both the starter code and the reference solution.","phpBuiltinName":"{name} is a PHP built-in function, which PHP cannot declare again. Choose another function name before publishing.","phpPdoParameter":"The function's first parameter must be PDO $pdo, in both the starter code and the reference solution.","phpDatabaseSetupRequired":"Add the tables: the CREATE TABLE statements every case starts from.","phpDatabaseCases":"Database cases need their arguments as a JSON array: [] when the function only takes $pdo.","databaseKind":"Only PHP problems can be database problems.","caseArgumentsInvalidJson":"Case {case} arguments is not valid JSON. Check brackets, quotes, and commas.","caseOutputInvalidJson":"Case {case} output is not valid JSON. Check brackets, quotes, and commas.","caseArgumentsNotArray":"Case {case} arguments must be a JSON array of function arguments.","javaSignatureInvalid":"Java method signature is invalid.","caseArguments":"Case {case} arguments must match the Java method parameter types.","caseResult":"Case {case} expected result must match the Java method return type.","runnerMock":"Problem validation needs a configured code runner. Mock execution cannot validate reference solutions.","runnerUnavailable":"The code runner is unavailable. Retry validation when it is available; this problem has not been published.","caseTimeout":"Case {position}: Reference solution exceeded the execution time limit. Fix the reference solution or expected result before publishing.","caseMismatch":"Case {position}: Expected {expected}; returned {returned}. Fix the reference solution or expected result before publishing.","caseRunner":"Case {position}: {message} Fix the reference solution or expected result before publishing.","sqlCaseSize":"SQL case data and checks can have up to 20000 characters.","sqlSetupLength":"The setup can have up to 20000 characters.","sqlSetupRequired":"Add the setup: the CREATE TABLE statements every case starts from.","sqlCheckRequired":"Every case needs a check for this kind of SQL problem.","sqlSetup":"The setup could not run ({message}). Fix it, then run the reference again.","sqlCaseData":"Case {position}: its data could not run ({message}). Fix it, then run the reference again.","sqlNotRun":"Case {position} has no expected results yet. Choose Run the reference, read the results, then publish.","sqlChanged":"Case {position}: the reference solution no longer gives the expected results. Choose Run the reference again, read the results, then publish."}},"quizzes":{"types":{"SINGLE_CHOICE":"Single choice","MULTIPLE_CHOICE":"Multiple choice","TRUE_FALSE":"True or false","SHORT_ANSWER":"Short answer","OPEN_ANSWER":"Open answer"},"typeDescriptions":{"SINGLE_CHOICE":"One correct option among 2 to 6.","MULTIPLE_CHOICE":"Several correct options, all needed.","TRUE_FALSE":"A statement students judge.","SHORT_ANSWER":"A word or value, checked automatically.","OPEN_ANSWER":"A written answer you grade."},"levels":{"BEGINNER":"Beginner","INTERMEDIATE":"Intermediate","ADVANCED":"Advanced"},"languages":{"en":"English","fr":"French"},"outcomes":{"CORRECT":"Correct","WRONG":"Wrong","PENDING":"Waiting for review","SKIPPED":"Skipped","NOT_REACHED":"Not reached"},"trueValue":"True","falseValue":"False","points":{"one":"{count} point","other":"{count} points"},"pts":{"one":"{count} pt","other":"{count} pts"},"questionCount":{"one":"{count} question","other":"{count} questions"},"question":"Question {number}","questionOf":"Question {number} of {total}","optional":"Optional","deleting":"Deleting…","provisional":"Provisional","genericError":"Something went wrong. Try again.","errors":{"notFound":"Quiz not found.","authorRequired":"Only the quiz's author can change it. Duplicate it to edit your own copy.","titleTooShort":"Use at least 2 characters for the title.","titleTooLong":"Keep the title under 120 characters.","descriptionTooLong":"Keep the description under 500 characters.","optionNeedsText":"Every option needs text.","optionTooLong":"Keep each option under 500 characters.","optionsMin":"Add at least 2 options.","optionsMax":"Use at most 6 options.","optionIdShared":"Two options share an id.","optionTextShared":"Two options have the same text.","markCorrect":"Mark the correct option.","correctMissing":"A correct answer points to an option that does not exist.","singleChoiceOneCorrect":"A single-choice question has one correct option.","chooseTrueFalse":"Choose whether the statement is true or false.","acceptedEmpty":"Accepted answers cannot be empty.","acceptedTooLong":"Keep each accepted answer under 200 characters.","acceptedMin":"Add at least one accepted answer.","acceptedMax":"Use at most 10 accepted answers.","acceptedShared":"Two accepted answers are the same.","gradingNotesTooLong":"Keep grading notes under 2000 characters.","maxLengthRequired":"Enter the maximum length in characters.","maxLengthMin":"Allow at least 50 characters.","maxLengthMax":"Allow at most 5000 characters.","codeRequired":"Add the code or remove the snippet.","codeTooLong":"Keep the code under 5000 characters.","promptRequired":"Write the question.","promptTooLong":"Keep the question under 2000 characters.","pointsWhole":"Enter the points as a whole number.","pointsMin":"A question is worth at least 1 point.","pointsMax":"A question is worth at most 100 points.","explanationTooLong":"Keep the explanation under 2000 characters.","chooseType":"Choose a question type.","answerTooLong":"Keep your answer under {max} characters.","answerRequired":"Write an answer, or skip the question.","chooseOne":"Choose one answer.","chooseAtLeastOne":"Choose at least one answer.","chooseEachOnce":"Choose each answer once.","checkAnswer":"Check your answer and try again.","topicRequired":"Describe what the questions should cover.","topicTooLong":"Keep the description under 500 characters.","countRequired":"Choose how many questions to write.","countWhole":"Choose a whole number of questions.","countMin":"Ask for at least 1 question.","countMax":"Ask for at most 20 questions at a time.","typesMin":"Tick at least one question type.","typesOnce":"Tick each question type once.","levelRequired":"Choose a level.","languageRequired":"Choose English or French.","sourceTooLong":"Keep the source material under 20,000 characters.","quizFull":"A quiz holds at most 100 questions.","roomFor":{"one":"The quiz has room for {count} more question.","other":"The quiz has room for {count} more questions."},"chooseQuestionToAdd":"Choose at least one question to add.","orderStale":"The quiz changed while you were reordering. Reload the page and try again.","questionNotFound":"Question not found.","shareAuthorRequired":"Only the quiz's author can manage sharing.","shareNotFound":"This quiz is not shared with that teacher.","alreadyOwner":"You already own this quiz.","teacherNotFound":"No active teacher in your organization has that account.","generateRateLimited":"You can generate {limit} times an hour. Try again later.","generateAllowanceUsed":"Your organization has used this month's AI generations. They reset on {date}.","aiGradingAllowanceUsed":"Your organization has used this month's AI-graded answers. They reset on {date}. Grading by hand always works.","notAQuiz":"This session has no quiz.","idempotencyConflict":"Idempotency key is already in use.","questionLocked":"This question is already answered. Continue from the current question.","sessionNotFound":"Session not found.","answerNotFound":"Answer not found.","answerSkipped":"A skipped question has no answer to grade.","aiRateLimited":"You can grade {limit} answers with AI an hour. Try again later.","aiGradingUnavailable":"AI grading is unavailable right now. Try again in a moment.","aiGradingUnavailableAskAgain":"AI grading was unavailable. Ask again."},"ai":{"timeout":"The model took too long to answer. Ask for fewer questions or try again.","cancelled":"The request was cancelled.","unreachable":"OpenRouter could not be reached. Try again in a moment.","keyRefused":"OpenRouter refused your organization's key. An organization admin can replace it on the Organization page.","noCredit":"Your organization's OpenRouter key has no credit left. An organization admin can add credit on openrouter.ai.","rateLimited":"OpenRouter is limiting requests right now. Try again in a minute.","couldNotAnswerWith":"OpenRouter could not answer: {detail}","couldNotAnswer":"OpenRouter could not answer. Try again in a moment.","newKeyRefused":"OpenRouter refused this key. Copy it again from openrouter.ai/keys.","modelUnknown":"OpenRouter has no model called “{model}”. Copy the id from openrouter.ai/models.","modelUnsupported":"{model} does not support structured outputs, which quiz generation needs. Choose another model.","invalidJson":"The model's answer was not valid JSON. Try again.","truncated":"The answer was cut off before the end. Ask for fewer questions.","emptyAnswer":"The model sent an empty answer. Try again.","invalidVerdict":"The model's answer did not give a verdict with a reason.","notAvailable":"AI is not available right now. Try again later.","platformUnavailable":"AI is not available right now. Try again later.","seeUsage":"See AI use","generationsUsed":"Your organization has used this month's {limit} AI generations. They reset on {date}.","gradingsUsed":"Your organization has used this month's {limit} AI-graded answers. They reset on {date}. Grading by hand always works.","generationsLeft":"{count} of this month's {limit} AI generations left. They reset on {date}.","gradingsLeft":"{count} of this month's {limit} AI-graded answers left. They reset on {date}."},"details":{"title":"Title","description":"Description"},"list":{"title":"Quizzes","intro":"Check what code tests cannot: concepts, reading code, HTML and CSS, Git. Write a quiz, then assign it to a class.","panelLabel":"Quizzes","tabsLabel":"Quiz lists","yourQuizzes":"Your quizzes · {count}","sharedWithYou":"Shared with you · {count}","fromEchelio":"Echelio · {count}","quiz":"Quiz","sortedAZ":", sorted A to Z","sortAZ":", sort A to Z","lastUpdated":"Last updated","newestFirst":", newest first","sortNewest":", sort newest first","sharedWithTeachers":{"one":"Shared with {count} teacher","other":"Shared with {count} teachers"},"onlyYou":"Only you","practiceBadge":"Open for practice","by":"By {name}","lastGiven":"Last assigned {when}","notGiven":"Not assigned yet","updated":"Updated","view":"View","duplicateTitle":"Duplicate {title}","copyToMine":"Copy to my quizzes","platformNote":"Ready-made quizzes from Echelio. Students of every school can practise them and see the answers, so copy one to your quizzes and change it before you assign it as a test.","pagesLabel":"Quiz pages","empty":{"own":"Write your first quiz with New quiz: add a few questions, then assign it to a class.","shared":"Quizzes other teachers in your organization share with you appear here.","platform":"No Echelio quiz is available yet."}},"page":{"back":"Quizzes","yours":"Your quiz","sharedBy":"Shared by {name}","fromEchelio":"From Echelio","platformNote":"Students of every school can practise this quiz and see its answers. Copy it to your quizzes and change it before you assign it as a test."},"newQuiz":{"button":"New quiz","title":"New quiz","intro":"You add questions on the next page.","close":"Close quiz form","titlePlaceholder":"JavaScript arrays, week 3","descriptionPlaceholder":"What the quiz covers, for you and the teachers you share it with.","creating":"Creating…","create":"Create quiz","failed":"The quiz could not be created."},"actions":{"leaveFailed":"You could not remove this quiz from your list.","saveFailed":"The quiz could not be saved.","deleteFailed":"The quiz could not be deleted.","duplicateToEdit":"Duplicate to edit","removeFromMine":"Remove from my quizzes","duplicate":"Duplicate","settings":"Quiz settings","practiceOpen":"Open for practice","practiceOpenHelp":"Students of your school can practise this quiz on their own and see the correct answer and explanation after each question. You don’t see their answers. Keep it closed if you still plan to assign it as a test.","closeSettings":"Close quiz settings","deleteQuiz":"Delete quiz","deleteTitle":"Delete {title}?","deleteIntro":"The quiz and its questions are deleted for you and for the teachers you shared it with. Tests already given keep their own copy.","closeDelete":"Close delete confirmation","keepQuiz":"Keep quiz","copySuffix":"(copy)"},"share":{"duplicateFailed":"The quiz could not be duplicated.","chooseTeacher":"Choose a teacher to share with.","shareFailed":"The quiz could not be shared.","unshareFailed":"Sharing could not be removed.","share":"Share","labelShared":"Share, shared with {count}","labelFor":"{label}: {title}","buttonCount":"Share · {count}","dialogTitle":"Share {title}","dialogIntro":"Teachers you share with can preview the quiz and duplicate it into their own copy. Only you can edit it.","close":"Close sharing","teacherLabel":"Teacher in your organization","chooseOption":"Choose a teacher","sharing":"Sharing…","allShared":"This quiz is shared with every other teacher in your organization.","noColleagues":"There are no other teachers in your organization yet.","stopSharing":"Stop sharing with {name}","onlyYou":"Only you can see this quiz so far."},"launcher":{"createClassFirst":"Create a class first","addQuestionFirst":"Add a question before assigning this quiz","giveAria":"Assign {title}","giveTest":"Assign quiz"},"editor":{"questions":"Questions","noQuestionsEdit":"No questions yet. Choose a type to add the first one.","noQuestionsView":"This quiz has no questions yet.","newUnsaved":"New question, not saved yet","addQuestion":"Add question","generate":"Generate with AI","preview":"Preview quiz","sectionLabel":"Question","pickType":"Choose a question type","closeTypes":"Close question types","discardTitle":"Discard unsaved changes?","discardBody":"Your edits to this question are not saved yet.","keepEditing":"Keep editing","discard":"Discard changes","moveFailed":"The question could not be moved.","generateTitle":"Generate questions with AI"},"form":{"typeHelp":{"SINGLE_CHOICE":"Tick the one correct option.","MULTIPLE_CHOICE":"Tick every correct option. Students must pick exactly these to get the points.","TRUE_FALSE":"Choose whether the statement is true or false.","SHORT_ANSWER":"Students type a word or value. Spaces at the ends are ignored and repeated spaces count as one.","OPEN_ANSWER":"Students write freely and you grade each answer correct or wrong after the test."},"previewFix":"Fix the highlighted fields to preview this question.","saveFix":"Fix the highlighted fields, then save.","saveFailed":"The question could not be saved.","deleteFailed":"The question could not be deleted.","newQuestion":"New question","moveUp":"Move question up","moveDown":"Move question down","typeLabel":"Question type","points":"Points","prompt":"Question","promptPlaceholderTrueFalse":"let declares a block-scoped variable.","promptPlaceholder":"What does this code print?","codeLanguage":"Code language","plainText":"Plain text","removeCode":"Remove code","code":"Code","codeHelp":"Students see it highlighted and read-only, under the question.","addCode":"Add code snippet","legendOptions":"Options","legendCorrect":"Correct answer","legendAccepted":"Accepted answers","legendGrading":"Grading","optionCorrect":"Option {number} is correct","option":"Option {number}","removeOption":"Remove option {number}","addOption":"Add option","acceptedAnswer":"Accepted answer {number}","anotherSpelling":"Another spelling","removeAccepted":"Remove accepted answer {number}","addAccepted":"Add accepted answer","caseSensitive":"Case sensitive","gradingNotes":"Grading notes","gradingNotesPlaceholder":"What a correct answer must mention.","gradingNotesHelp":"Only teachers see these, while grading.","maxLength":"Maximum length, in characters","explanation":"Explanation","explanationPlaceholder":"b points to the same array as a, so pushing to b changes a too.","explanationHelp":"Shown with the correct answer once the test closes.","preview":"Preview","saveDraft":"Save draft","undo":"Undo changes","discardNew":"Discard","saved":"Saved","deleteTitle":"Delete question {number}?","deleteIntro":"Tests already given with this quiz keep their own copy.","keepQuestion":"Keep question","deleteQuestion":"Delete question"},"view":{"chooseEvery":"Choose every correct answer.","chooseOne":"Choose one answer.","yourAnswer":"Your answer","typePlaceholder":"Type your answer","writePlaceholder":"Write your answer","count":"{length} / {max} characters · Your teacher grades this answer.","countPractice":"{length} / {max} characters","marks":{"correct":"Correct","wrong":"Wrong","missed":"Correct answer"}},"key":{"title":"Answer key","correctSr":"(correct)","statement":"The statement is <b>{value}</b>.","isTrue":"true","isFalse":"false","acceptedAnyCase":"Accepted answers, in any case:","acceptedCaseSensitive":"Accepted answers, case sensitive:","openGraded":"Graded by the teacher, correct or wrong. Up to {max} characters.","explanation":"Explanation"},"preview":{"title":"Student preview","intro":"Question {number} of {total} · {points}. During a test, students only learn their results once it closes.","close":"Close preview","pendingNote":"You grade open answers yourself after the test.","previous":"Previous","next":"Next","check":"Check answer"},"generator":{"alsoTranslate":{"en":"Also show it in English to students who read English","fr":"Also show it in French to students who read French"},"translatedFor":{"en":"Students who read English will see it translated.","fr":"Students who read French will see it translated."},"mixedLanguage":{"en":"This quiz is written in English. Questions in French would mix two languages in one quiz.","fr":"This quiz is written in French. Questions in English would mix two languages in one quiz."},"title":"Generate questions with AI","reviewTitle":"Review the drafts","describeIntro":"Describe what the questions should cover. You review every draft before anything is added to the quiz.","reviewIntro":{"one":"{count} draft. Untick the ones you don't want and edit the rest; nothing is added until you confirm.","other":"{count} drafts. Untick the ones you don't want and edit the rest; nothing is added until you confirm."},"confirmStop":"Stop writing questions?","confirmDiscard":"Discard these drafts? None of them has been added to the quiz.","confirmReplace":"Write new drafts? The current ones will be replaced.","writeFailed":"The questions could not be written.","noUsable":"No usable questions came back. Try again, or describe the topic differently.","addFailed":"The questions could not be added.","dropped":{"one":"{count} draft was dropped because it broke the question rules:","other":"{count} drafts were dropped because they broke the question rules:"},"topicLabel":"What should the questions cover?","topicPlaceholder":"JavaScript array methods: map, filter, and reduce, with short code to read.","countLabel":"Number of questions","countHelp":"Up to {max} at a time.","levelLabel":"Level","languageLabel":"Language","typesLabel":"Question types","typesHelp":"Open answers are graded by you after the test.","sourceLabel":"Source material","sourcePlaceholder":"Paste lesson notes or a brief.","sourceHelp":"The questions stick to it. Up to {max} characters.","writing":{"one":"Writing {count} question, which can take a minute… {elapsed}","other":"Writing {count} questions, which can take a minute… {elapsed}"},"backToDrafts":"Back to drafts","stop":"Stop","write":"Write questions","writingNow":"Writing questions…","draftLabel":"Draft {number}","draftHeading":"Draft {number} · {type} · {points}","saveOrCancel":"Save or cancel the draft you are editing first.","adding":"Adding…","add":{"one":"Add {count} question","other":"Add {count} questions"},"tickDraft":"Tick a draft to add","unnamed":"A question without a prompt","named":"“{prompt}”","droppedReason":"{name}: {reason}","noList":"The model's answer did not contain a list of questions.","incomplete":"A question was incomplete.","typeNotTicked":"its type was not one you ticked.","rulesNotMet":"it did not fit the question rules."},"player":{"savingAnswers":"Saving your answers…","timeIsUp":"Time is up","scoreOnItsWay":"Your score is on its way.","savedOpening":"Your answers so far are saved. Opening your results…","quiz":"Quiz","quizRecorded":"Quiz · Leaving this page is recorded","done":"{done} of {total} done","doneSkipped":"{done} of {total} done · {skipped} skipped","hintChoose":"<kbd>1</kbd>–<kbd>{keys}</kbd> to choose · <kbd>Enter</kbd> to submit · ","hintSubmit":"<kbd>Enter</kbd> to submit · ","final":"Answers are final: you can’t go back.","skip":"Skip","skipping":"Skipping…","submit":"Submit answer","savedAnswer":"Answer {number} saved","skippedQuestion":"Question {number} skipped","locked":"That question was already answered, maybe in another tab. Here is where you are now.","saveFailed":"Your answer could not be saved.","notSent":"Your answer was not sent. Check your connection, then try again."},"done":{"results":"Quiz results","sessions":"Sessions","submitted":"Quiz submitted","timedOut":"Time’s up","stopped":"Session stopped","recorded":"Your answers are recorded.","closedEarly":"The session closed before you finished.","closedEarlyUnreached":{"one":"The session closed before you finished. {count} question you didn’t reach counts as not answered.","other":"The session closed before you finished. {count} questions you didn’t reach count as not answered."},"scoreLine":"<earned></earned> / {points} · <percent></percent>","scoreLineProvisional":"<earned></earned> / {points} · <percent></percent> so far","scoreAria":{"one":"{earned} of {count} point earned","other":"{earned} of {count} points earned"},"scoreAriaPending":{"one":"{earned} of {count} point earned, {pending} waiting for review","other":"{earned} of {count} points earned, {pending} waiting for review"},"answersLabel":"Your answers","pending":{"one":"{count} answer waiting for review. Your score can go up once your teacher grades it.","other":"{count} answers waiting for review. Your score can go up once your teacher grades them."},"opensAt":"Correct answers and explanations appear here when the session closes, at <time></time>.","notShared":"Your teacher isn’t sharing results for this quiz.","reviewTitle":"Your answers","jumpLabel":"Jump to a question","jumpTo":"Question {number}, {state}","explanation":"Explanation","mixed":{"results":"Test results","submitted":"Test submitted","totalLine":"<total></total> total","totalLineProvisional":"<total></total> total so far","totalAria":"Total score {percent}","partsLabel":"Your score by part","quizPart":"Part {number} · Quiz","codePart":"Part {number} · Code","quizScore":"{earned} / {points} · {percent}","codeScore":"Passed: {passed} of {total} · {percent}","weight":"Counts for {percent} of the total.","codeQuestions":"Your code problems","passed":"Passed","notSubmitted":"Not submitted","checking":"Being checked","codePending":"A submission is still being checked. Your score can still change.","notShared":"Your teacher isn’t sharing results for this test.","reviewTitle":"Your quiz answers"}},"review":{"student":{"answer":"Your answer","picked":"Your answer","skipped":"You skipped this question.","notReached":"You didn’t reach this question."},"teacher":{"answer":"Answer","picked":"Picked","skipped":"Skipped this question.","notReached":"Didn’t reach this question."},"correctSr":"(correct answer)","accepted":{"one":"Accepted answer","other":"Accepted answers"},"acceptedCaseSensitive":{"one":"Accepted answer, case sensitive","other":"Accepted answers, case sensitive"},"notGradedYet":"Your teacher hasn’t graded this answer yet.","gradingNotes":"Grading notes","overrideCorrect":"Your teacher marked this answer correct.","overrideWrong":"Your teacher marked this answer wrong.","aiGrading":"AI is grading this answer…","aiFailed":"AI could not grade this answer. {error}","aiErrors":{"failed":"Something went wrong while grading.","timeout":"The model took too long to answer.","truncated":"The model's answer was cut off.","lost":"The grading job was lost. Ask again."},"gradedByAi":"Graded by AI","aiAgreed":"AI agreed","aiSaidCorrect":"AI said correct","aiSaidWrong":"AI said wrong","aiProgress":"AI is grading","aiProgressCount":"{done} of {total}","aTeacher":"a teacher","gradedBy":"Graded by {name}","gradedByAutoCorrect":"Graded by {name} · automatic grading said correct","gradedByAutoWrong":"Graded by {name} · automatic grading said wrong","gradedAutomatically":"Graded automatically"},"grading":{"saveFailed":"The grade could not be saved.","acceptFailed":"The answers could not be accepted.","accepting":"Accepting…","accept":"Accept for everyone","acceptAria":{"one":"Accept for everyone: mark this answer correct","other":"Accept for everyone: mark these {count} answers correct"}},"aiGrading":{"button":"Grade with AI","dialogTitle":"Grade open answers with AI","startFailed":"AI grading could not start.","noneWaiting":"No answers were waiting for the AI any more.","limitReached":{"one":"The AI is grading {count} answer. You reached the hourly limit, so press again in an hour for the other {remaining}.","other":"The AI is grading {count} answers. You reached the hourly limit, so press again in an hour for the other {remaining}."},"allowanceReached":{"one":"The AI is grading {count} answer. This month's AI allowance is now used: grade the others by hand, or press again after it resets on {date}.","other":"The AI is grading {count} answers. This month's AI allowance is now used: grade the others by hand, or press again after it resets on {date}."},"allowanceShort":{"one":"Only {count} AI-graded answer is left this month: the first answer is graded and the rest stay for you. It resets on {date}.","other":"Only {count} AI-graded answers are left this month: the first {count} are graded and the rest stay for you. It resets on {date}."},"intro":{"one":"The AI grades {count} open answer waiting for review, one at a time. It reads the question, your grading notes, and the answer, never the student’s name.","other":"The AI grades {count} open answers waiting for review, one at a time."},"listLabel":"Answers to grade","answers":{"one":"{count} answer","other":"{count} answers"},"noNotes":"No grading notes","countNow":"Grades count straight away. You can change any grade.","withoutNotesOne":"Question {numbers} has no grading notes, so the AI judges from the question and its explanation. Check those grades.","withoutNotesMany":"Questions {numbers} have no grading notes, so the AI judges from the question and its explanation. Check those grades.","retrying":{"one":"Includes {count} answer the AI could not grade before.","other":"Includes {count} answers the AI could not grade before."},"stillOpen":"The session is still open. Answers that arrive later need another press.","starting":"Starting…","start":{"one":"Grade {count} answer","other":"Grade {count} answers"}},"translation":{"off":"Switch translation on in the quiz’s settings first.","notReady":"This question has no translation yet. Wait for it, then edit it.","optionsChanged":"The translation must keep the question’s options.","switch":"Students can read it in English and French","switchHelp":"Echelio translates the questions with AI. Students see them in their own language.","noAi":"Translation needs AI, which isn’t set up for your school.","into":{"en":"English","fr":"French"},"statusReady":"Translated into {language}","statusPending":{"one":"Translating {count} question…","other":"Translating {count} questions…"},"statusFailed":"Translation failed","statusFailedLong":"Translation stopped before every question was translated.","statusWaiting":"Translation is taking longer than usual. Check back in a moment.","translateAgain":"Translate again","confirmAgain":"Translate every question again? This replaces your edits.","againFailed":"Could not start the translation.","toggleLabel":"Show the {language} translation of this question","panel":{"loading":"Loading the translation…","loadFailed":"Could not load the translation.","none":"No translation for this question yet. It appears here once it is ready.","byAi":"Translated by AI","edited":"Edited","outOfDate":"Out of date, being translated again","explanation":"Explanation","options":"Options","acceptedAnswers":"Accepted answers","edit":"Edit","promptLabel":"Question","explanationLabel":"Explanation","optionLabel":"Option {number}","acceptedLabel":"Accepted answers","acceptedHelp":"One per line.","codeHelp":"Keep the code between backticks exactly as in the original.","save":"Save","saving":"Saving…","cancel":"Cancel","saveFailed":"Could not save the translation."}},"session":{"checkedIn":"You’re checked in. The quiz opens at <time></time>.","backToSessions":"Back to sessions"},"results":{"assigned":"Assigned","joined":"Joined","finished":"Finished every question","toReview":"Answers to review","scoresTitle":"Student scores","scoresIntro":"Ranked by score, then fastest completion. Scores stay provisional until open answers are graded.","rank":"Rank","student":"Student","participation":"Participation","score":"Score","answers":"Answers","correct":"Correct","wrong":"Wrong","skipped":"Skipped","notAnswered":"Not answered","toReviewColumn":"To review","completionTime":"Completion time","tabSwitches":"Tab switches","away":"{time} away","durationHours":"{hours}h {minutes}m","durationMinutes":"{minutes}m {seconds}s","noStudentsAssigned":"No students are assigned yet. Assign students to begin collecting answers.","removed":"Removed","questionsTitle":"Questions","questionsIntro":"How each question went. Open one to see what students picked and grade open answers.","cellsLabel":"Answers by question","cell":"Question {number}: {state}","notYet":"not answered yet","states":{"CORRECT":"correct","WRONG":"wrong","PENDING":"to review","SKIPPED":"skipped","NOT_REACHED":"not reached"},"counts":{"CORRECT":{"one":"{count} correct","other":"{count} correct"},"WRONG":{"one":"{count} wrong","other":"{count} wrong"},"PENDING":{"one":"{count} to review","other":"{count} to review"},"SKIPPED":{"one":"{count} skipped","other":"{count} skipped"},"NOT_REACHED":{"one":"{count} not reached","other":"{count} not reached"}},"noStudents":"No students","questionPrefix":"Question {number}:","mixed":{"scoresIntro":"Ranked by total, then fastest completion. Code counts {code} and the quiz {quiz}. A total stays provisional while code is being checked or open answers wait for review.","total":"Total","part":{"CODE":"Code · {percent}","QUIZ":"Quiz · {percent}"},"passed":"{passed}/{total} passed","answersOrder":{"CODE":"Code, then quiz","QUIZ":"Quiz, then code"},"codeCellsLabel":"Code problems by result","codeCell":"Code problem {number}: {state}","codeNotYet":"not submitted yet","codeStates":{"PASSED":"passed","PARTIAL":"partly passed","FAILED":"failed","UNGRADED":"not graded yet","NOT_SUBMITTED":"not submitted"},"codeCounts":{"PASSED":{"one":"{count} passed","other":"{count} passed"},"PARTIAL":{"one":"{count} partly passed","other":"{count} partly passed"},"FAILED":{"one":"{count} failed","other":"{count} failed"},"UNGRADED":{"one":"{count} not graded yet","other":"{count} not graded yet"},"NOT_SUBMITTED":{"one":"{count} not submitted","other":"{count} not submitted"}},"quizQuestionsTitle":"Quiz questions","codeQuestionsTitle":"Code problems","codeQuestionsIntro":"How each code problem went, by each student’s best submission. Open a student to read their code.","codeQuestionPrefix":"Code problem {number}:"}}},"school":{"shared":{"optional":"Optional","you":"(you)"},"errors":{"classNotFound":"Class not found.","alreadyTeaching":"This teacher already teaches this class.","studentAccountRequired":"Class invitations can only be accepted by student accounts.","invitationNotFound":"This class invitation is not valid.","studentInOtherOrganization":"This student account belongs to another organization.","invalidClassDates":"The class end date must be after its start date.","aiNotConfigured":"AI features are not set up on this server.","aiKeyRequired":"Paste the OpenRouter key.","aiKeyUnreadable":"Your organization's OpenRouter key can no longer be read, probably because the server's AI_KEY_SECRET changed. An organization admin can add the key again.","ownKeyOrganizationPlan":"Only the Organization plan can use its own OpenRouter key.","webhookOrganizationPlan":"Sending results to your platform is part of the Organization plan.","webhookNotConfigured":"Webhooks are not set up on this server.","webhookNotSet":"Set your platform's address first.","webhookUnreadable":"The webhook's secret can no longer be read, probably because the server's AI_KEY_SECRET changed. Make a new secret.","webhookCannotSend":"Only a test that has ended can be sent.","aiKeyTooLong":"That key is too long.","aiKeyHasSpaces":"A key has no spaces.","modelRequired":"Enter a model id.","modelTooLong":"That model id is too long.","modelInvalid":"Use an OpenRouter model id, written as provider/model.","teacherNotFound":"Teacher not found in this organization.","lastAdmin":"An organization needs at least one admin. Make someone else an admin first.","roleConflict":"Another admin changed roles at the same time. Reload and try again.","questionUnavailable":"One of these problems is no longer available.","invalidSkill":"Choose skills from your organization's list.","nameTooShort":"Use at least 2 characters.","nameTooLong":"The name is too long.","skillNotFound":"Skill not found.","skillExists":"A skill with that name already exists.","invalidFollowUp":"Choose a class, a difficulty, and at least one skill.","invalidLearner":"Choose learners from this class.","alreadyTeacherHere":"This person is already a teacher in your organization.","alreadyMember":"You are already a teacher in this organization. Sign in instead.","teacherInOtherOrganization":"This address belongs to a teacher at another organization, so it cannot join this one.","retirementNotConfirmed":"Confirm that your existing account will be retired.","choosePassword":"Choose a password of at least 8 characters.","organizationInvitationInvalid":"This invitation is no longer valid. Ask an admin of the organization for a new one.","organizationInvitationOtherAccount":"This invitation is for {email}. Sign out, then open the link again.","organizationInvitationOtherGoogleAccount":"The Google account you chose uses another address. Choose the Google account of the invited address.","organizationInvitationRetry":"This address changed while you were joining. Open the link again.","organizationInvitationNotFound":"Invitation not found.","tooManyInvitations":"Your organization has sent too many invitations today. Try again tomorrow.","tooManyStudentInvitations":"You have added too many students in the last hour. Try again later.","readOnly":"Your organization is read-only, so nothing can be added or changed. You can still see and export classes, results, and Progress.","classLimit":{"one":"Your plan includes {count} class at a time. End the current class before starting another.","other":"Your plan includes {count} classes at a time. End one before starting another."},"classFull":"This class is full. Ask your teacher.","classClosedToNewStudents":"This class is not taking new students. Ask your teacher.","studentLimit":"All {count} student places of your plan are taken, so this student cannot be added.","teachersOnOrganizationPlan":"Inviting teachers is available on the Organization plan.","cannotRemoveYourself":"You cannot remove yourself. Ask another admin.","successorRequired":"Choose the teacher who takes over their work.","successorInvalid":"Choose another active teacher of this organization.","studentNotInClass":"This student is not in the class.","removedStudentNotFound":"This student was not removed from the class.","studentAccountClosed":"This student’s account is closed, so they cannot be added back.","removedFromClass":"You were removed from this class. Ask your teacher to add you back."},"levels":{"NOT_YET":"Not yet","EASY":"Easy","MEDIUM":"Medium","HARD":"Hard"},"failures":{"syntax":{"name":"Syntax errors","meaning":"The code does not run at all.","advice":"Short syntax drills, and read error messages together before fixing."},"crash":{"name":"Crashes","meaning":"The code runs, then throws an error.","advice":"Practise guarding against empty input and undefined values."},"wrong":{"name":"Wrong output","meaning":"The visible examples fail.","advice":"Trace the examples by hand before writing code."},"slow":{"name":"Too slow","meaning":"The code times out.","advice":"Look for nested loops and use maps or sets for lookups."},"edge":{"name":"Misses edge cases","meaning":"Visible examples pass, hidden cases fail.","advice":"Ask for their own test cases (empty, duplicates, limits) before each submit."}},"classes":{"title":"Classes","intro":"Create teaching groups, then invite students by email or a shareable link. New sessions are assigned to everyone enrolled in the selected class.","empty":"No classes yet. Create your first class to organize students and sessions.","newClass":"New class","name":"Name","namePlaceholder":"JavaScript · Group A","starts":"Starts","ends":"Ends","createTitle":"Create a class","createIntro":"Classes organize students and sessions for one or more teachers.","closeBuilder":"Close class builder","inviteStudents":"Invite students","studentsPlaceholder":"student@example.com, another@example.com","studentsHelp":"Separate addresses with commas or spaces. Existing accounts are enrolled immediately; everyone else receives a registration link.","creating":"Creating…","createClass":"Create class","checkEmail":"Check the email address: {email}","createFailed":"Class could not be created.","invitesFailed":{"one":"The class was created, but {count} invitation could not be sent.","other":"The class was created, but {count} invitations could not be sent."},"updateFailed":"Class could not be updated.","deleteFailed":"Class could not be deleted.","studentFailed":"Student could not be added.","editTitle":"Edit class","editIntro":"Renaming a class or changing its dates does not affect enrolled students or existing sessions.","closeEditor":"Close class editor","deleteTitle":"Delete {name}?","deleteIntro":"This removes {enrolments}, {sessions}, and every submission recorded in them. It cannot be undone.","closeDelete":"Close delete confirmation","keepClass":"Keep class","deleting":"Deleting…","deleteClass":"Delete class","enrolments":{"one":"{count} enrolment","other":"{count} enrolments"},"sessionCount":{"one":"{count} session","other":"{count} sessions"},"studentCount":{"one":"{count} student","other":"{count} students"},"studentWord":{"one":"student","other":"students"},"sessionWord":{"one":"session","other":"sessions"},"openClass":"Open class","otherTitle":"Other classes","otherIntro":"Classes of your school that you don’t teach. You can follow them on Progress; only their teachers can change them.","openOnProgress":"Open on Progress","status":{"running":"Running","upcoming":"Upcoming","ended":"Ended"},"noStudentsYet":"No students yet","shareToInvite":"Share the class link to invite the first one.","copyLink":"Copy link","classDetails":"Class details","closeDetails":"Close class details","studentsLabel":"Students","sessionsLabel":"Sessions","roster":"Student roster","rosterEnrolled":{"one":"{count} student enrolled","other":"{count} students enrolled"},"rosterEmpty":"Students will appear here after they join.","noStudentsInClass":"No students in this class","copyOrEmail":"Copy the invitation link or send an email invite.","invitations":"Class invitations","inviteLink":"Invitation link","inviteLinkHelp":"Anyone with the link can sign in or create a student account and join.","inviteByEmail":"Invite by email","emailPlaceholder":"student@example.com","emailHelp":"Existing accounts are enrolled immediately. New students receive a registration link.","sending":"Sending…","sendInvite":"Send invite","copyThisLink":"Copy this link: {url}","added":"{name} was added.","addedEmailed":"{name} was added and emailed.","invitationSent":"Invitation sent to {email}.","invitationSaved":"Invitation saved, but the email could not be sent. Try again later.","teachersTitle":"Teachers","ownerBadge":"Owner","teacherAddLabel":"Add a teacher","teacherAddHelp":"They get the same access as you, except deleting the class.","teacherChoose":"Choose a teacher","teacherAdd":"Add","teacherAdded":"{name} now teaches this class.","teacherAddFailed":"The teacher could not be added.","teacherRemove":"Remove","teacherRemoveLabel":"Remove {name} from this class","teacherLeave":"Leave class","teacherLeaveConfirm":"Leave {name}? You will no longer see it unless its owner adds you again.","teacherRemoveFailed":"The teacher could not be removed.","removeStudent":"Remove {name} from the class","removeTitle":"Remove {name} from {className}?","removeIntro":"They leave the class and its tests that haven’t started, and can’t rejoin through the class link. Their results stay, and you can add them back at any time.","closeRemove":"Close remove confirmation","removeConfirm":"Remove student","removing":"Removing…","removeStudentFailed":"The student could not be removed.","studentRemoved":"{name} was removed from the class.","undo":"Undo","rosterViewLabel":"Roster view","enrolledTab":"Enrolled {count}","removedTab":"Removed {count}","removedIntro":"Removed from this class. Their results stay.","removedOnBy":"Removed {date} by {name}","removedOnByYou":"Removed {date} by you","removedOn":"Removed {date}","addBack":"Add back","addBackLabel":"Add {name} back to the class","addBackFailed":"The student could not be added back.","addedBack":"{name} is back in the class."},"invite":{"notFoundTitle":"Invitation not found.","notFoundBody":"This link is invalid. Ask your teacher for a new class invitation.","goToSignIn":"Go to sign in","studentRequiredTitle":"Student account required.","studentRequiredBody":"Sign out and open this invitation with a student account to join {name}.","returnToDashboard":"Return to teacher dashboard","otherOrganizationTitle":"Different organization.","otherOrganizationBody":"Your account belongs to another organization, so it cannot join {name}. Ask your teacher to invite a different email address.","goToSessions":"Go to your sessions","adding":"Adding you to the class…","failed":"The invitation could not be accepted.","joined":"You are now a member of {name}.","successTitle":"You’re in.","errorTitle":"We couldn’t add you.","joining":"Joining {name}","goToStudent":"Go to student dashboard"},"organizationInvite":{"eyebrow":"Invitation","title":"Join {organization}","asTeacher":"You are invited to join {organization} on Echelio as a teacher.","asAdmin":"You are invited to join {organization} on Echelio as an administrator.","invitedBy":"Invitation from {admin}.","invalidTitle":"This invitation is no longer valid.","invalidBody":"The link has expired, was replaced by a newer one, was revoked, or was already used. Ask an admin of the organization for a new invitation.","goToDashboard":"Go to your dashboard","wrongAccountTitle":"You are signed in with another account.","wrongAccountBody":"This invitation is for <b>{email}</b>, but you are signed in as <b>{current}</b>. Sign out to continue.","signingOut":"Signing out…","memberTitle":"You are already a teacher here.","memberBody":"{email} is already a teacher at {organization}.","otherOrganizationTitle":"This address is used at another organization.","otherOrganizationBody":"{email} is a teacher account at {other}, so it cannot join {organization}. Use another address.","retireStudentTitle":"Your student account will be retired","retireStudentBody":"{email} is used by your student account at {other}. Joining as a teacher closes that account.","retireStudentBodyNoOrganization":"{email} is used by your student account. Joining as a teacher closes that account.","retireTeacherTitle":"Your former account will be retired","retireTeacherBody":"{email} is used by your former teacher account at {other}. Joining {organization} closes that account for good.","openClasses":{"one":"You are still a student in this class, which you will no longer be able to open:","other":"You are still a student in these classes, which you will no longer be able to open:"},"nameHelp":"Students and other teachers see this name.","keepPassword":"You keep your current password.","join":"Join {organization}","retireStudentAndJoin":"Retire my student account and join","retireAccountAndJoin":"Retire my old account and join","leaveTeacherPlanTitle":"Joining ends your Teacher plan","leaveTeacherPlanBody":"Your subscription stops now, with no further charge. Your classes, quizzes, and problems stay in {other}, which becomes read-only and is deleted after 90 days. Within that time, our support can move your work into {organization} if you ask.","leaveTeacherPlanAndJoin":"End my Teacher plan and join","retireWithGoogle":"Retire it and continue with Google","joining":"Joining…","failed":"You could not join. Try again."},"plan":{"readOnlyTitle":"Your organization is read-only","readOnlyBody":"You can still see classes, results, and Progress and export them. Nothing new can be added or changed, and tests already scheduled run to their end.","deletionDate":"Its data will be deleted on {date}.","contractEndedTitle":"Your contract has ended","contractEndedBody":"Its last day was {ended}. Unless it is renewed, your organization becomes read-only after {readOnly}: everything stays visible, but nothing new can be added.","studentsFullTitle":"Every student place is taken","studentsFullBody":"Your plan includes {count} students in classes that have not ended. New students who open a class link are told the class is full.","classesFullTitle":"Your plan's classes are in use","classesFullBody":{"one":"Your plan includes {count} class at a time, and a class counts until its end date. To start a new one, end the current class first.","other":"Your plan includes {count} classes at a time, and a class counts until its end date. To start a new one, end another first."},"contactUs":"Write to us at <a>{email}</a>.","askAdmin":"An admin of your organization can tell you more.","invitationsOnOrganizationPlan":"Inviting teachers is available on the Organization plan."},"organization":{"title":"Organization","classCount":{"one":"{count} class","other":"{count} classes"},"studentCount":{"one":"{count} student","other":"{count} students"},"questionCount":{"one":"{count} organization problem","other":"{count} organization problems"},"teachersTitle":"Teachers","teachersIntro":"Admins manage this page.","tabsLabel":"Organization settings","tabTeachers":"Teachers","tabSkills":"Skills","tabAi":"AI","tabWebhook":"Webhook","productNewsStudentsLabel":"Product news to our students","productNewsStudentsHelp":"Echelio's emails about new features. Teachers choose for themselves.","renameTitle":"Rename organization","inviteTeacher":"Invite teacher","inviteTitle":"Invite a teacher","inviteIntro":"They get an email with a link to join. The link works for 7 days.","inviteEmail":"Email address","inviteEmailPlaceholder":"teacher@school.org","inviteRole":"Role","roleTeacherHint":"Creates classes, tests, quizzes, and problems.","roleAdminHint":"Also manages this page: teachers, skills, and the AI key.","invite":"Send invitation","inviting":"Sending…","invited":"Invitation sent to {email}.","invitedEmailFailed":"Invitation saved, but the email to {email} could not be sent. Try again later from Pending invitations.","inviteFailed":"The invitation could not be sent.","inviteAnother":"Invite another","done":"Done","pendingButton":"Pending invitations","pendingTitle":"Pending invitations","pendingIntro":"Each link works for 7 days and only once. Resend makes a new link and the old one stops working.","sentOn":"Sent <time></time>","emailFailed":"Email failed","expired":"Expired","resend":"Resend","resending":"Sending…","revoke":"Revoke","revoking":"Revoking…","revokeConfirm":"Revoke the invitation to {email}? The link will stop working.","revokeFailed":"The invitation could not be revoked.","remove":"Remove","removeTitle":"Remove {name}?","removeIntro":"{name} loses access to this organization. The tests they gave, with their results and grades, stay here.","removeOwned":"{name} owns {items}. Choose who takes them over.","ownedClasses":{"one":"{count} class","other":"{count} classes"},"ownedQuizzes":{"one":"{count} quiz","other":"{count} quizzes"},"ownedFolders":{"one":"{count} library folder","other":"{count} library folders"},"ownedQuestions":{"one":"{count} problem","other":"{count} problems"},"handOverTo":"Hand over to","removeConfirm":"Remove teacher","removing":"Removing…","removeFailed":"The teacher could not be removed.","colTeacher":"Teacher","colRole":"Role","colActions":"Actions","adminBadge":"Admin","skillsTitle":"Skills","skillsIntro":"The shared list every teacher here tags problems with, so progress can be followed skill by skill. Tags stay on new versions of a problem.","untagged":{"one":"{count} problem has no skills yet, so Progress cannot count it.","other":"{count} problems have no skills yet, so Progress cannot count them."},"reviewTags":"Review suggested tags","aiTitle":"AI","aiIntro":"Teachers here write quiz questions and grade open answers with AI. Echelio includes it, within a monthly allowance shared by the whole organization.","aiIncluded":"Included","aiOwnKey":"Own key","aiGenerations":"Quizzes and problems generated with AI","aiGradings":"Answers graded with AI","aiUsed":"{used} of {limit}","aiResets":"Counts start again on {date}.","aiOwnKeyNotCounted":"AI runs on your organization's own OpenRouter key, so nothing is counted against the allowance. OpenRouter bills your account for each use.","aiOwnKeyTitle":"Your own OpenRouter key","aiOwnKeyIntro":"Optional. With your own key, AI runs on your OpenRouter account with the model you choose, and nothing is counted against the allowance.","aiOff":"Off","nameLabel":"Organization name","nameFailed":"The name could not be saved.","removeOwnAdmin":"Remove your own admin role? You will lose access to this page.","roleFailed":"The role could not be changed.","updating":"Updating…","removeAdmin":"Remove admin","makeAdmin":"Make admin","skillSaveFailed":"The skill could not be saved.","skillAddFailed":"The skill could not be added.","newSkill":"New skill","newSkillPlaceholder":"Recursion","newSkillIntro":"Teachers tag problems with it, and Progress follows each learner's level in it.","addSkill":"Add skill","adding":"Adding…","colSkill":"Skill","colTagged":"Tagged problems","noSkills":"No skills yet. Start from the template, or add your own.","startFromTemplate":"Start from a template","templateIntro":"These are the skills Echelio can grade with code tests. You can rename or delete any of them later. Tagging the library problems comes next.","templateGroups":{"javascript":"JavaScript","sql":"SQL","php":"PHP"},"templateAdded":"Already added","templateAdd":{"one":"Add {count} skill","other":"Add {count} skills"},"templateFailed":"The skills could not be added.","skillName":"Skill name","rename":"Rename","deleting":"Deleting…","deleteSkillConfirm":"Delete the skill \"{name}\"?","removedFromQuestions":{"one":"It will be removed from {count} problem.","other":"It will be removed from {count} problems."},"aiNotConfigured":"AI features need <code>AI_KEY_SECRET</code> set on the server.","aiCurrent":"Key ending in <code>{hint}</code>, model <code>{model}</code>. Saved on <time></time>.","aiCurrentBy":"Key ending in <code>{hint}</code>, model <code>{model}</code>. Saved by {name} on <time></time>.","aiKeyLabel":"OpenRouter key","aiNewKey":"New key","aiKeyKeep":"Leave empty to keep the current key.","aiKeyHelp":"Create one at <link>openrouter.ai/keys</link>. It is stored encrypted and never shown again.","aiModel":"Model","aiModelHelp":"Any model id from <link>openrouter.ai/models</link> that supports structured outputs.","aiChecking":"Checking with OpenRouter…","aiSaveKey":"Save key","aiSaved":"Saved.","aiKeySaved":"Key saved. AI now runs on your key.","aiRemoving":"Removing…","aiRemoveKey":"Remove key","aiKeyRemoved":"Key removed.","aiKeyFailed":"The key could not be saved.","aiRemoveConfirm":"Remove the OpenRouter key? AI goes back to Echelio's, within the monthly allowance.","webhook":{"errors":{"URL_INVALID":"Enter a full address, such as https://platform.example.org/echelio.","URL_NOT_HTTPS":"Use an https:// address.","URL_NOT_ALLOWED":"This address cannot receive results.","ADDRESS_NOT_ALLOWED":"This address is not reachable from the internet.","NAME_NOT_FOUND":"This address's domain was not found.","CONNECTION_FAILED":"Could not connect to your platform.","TLS_FAILED":"Your platform's HTTPS certificate was refused.","TIMEOUT":"Your platform did not answer within 10 seconds.","REDIRECT":"Your platform answered with a redirect, which is not followed.","HTTP_STATUS":"Your platform answered with an error.","INTERNAL_ERROR":"Echelio could not send it. It is tried again.","WEBHOOK_OFF":"The webhook was removed before it was sent."},"title":"Results webhook","intro":"Send the results of each test to your own platform.","badgeOn":"On","badgeOff":"Off","badgePlan":"Organization plan","planOnly":"Sending results to your platform is part of the <link>Organization plan</link>.","notConfigured":"Webhooks need <code>AI_KEY_SECRET</code> set on the server.","how":"When a test ends, Echelio sends its results to your platform: scores, participation, the result of each problem and question, completion time and tab switches. It sends them again when a result changes.","howSigned":"Each request is signed, so your platform can check that it came from Echelio.","docsLink":"How your platform receives it","readOnlyNote":"This organization is read-only, so the webhook cannot be changed. You can still remove it.","urlLabel":"Platform address","urlHelp":"An https:// address that answers within 10 seconds.","saveAddress":"Save address","checking":"Checking the address…","addressSaved":"Address saved.","webhookSet":"Saved. Copy the signing secret to your platform, then send a test event.","saveFailed":"The address could not be saved.","secretLabel":"Signing secret","secretHelp":"Your platform uses it to check that a request came from Echelio.","reveal":"Reveal","hide":"Hide","newSecret":"New secret","newSecretConfirm":"Make a new secret? It replaces the current one at once, so your platform must use the new one from now on.","newSecretDone":"New secret made. Your platform must use it from now on.","secretFailed":"The secret could not be loaded.","newSecretFailed":"The secret could not be replaced.","copyFailed":"Copying failed. Copy it from the field.","testEvent":"Test event","testIntro":"Sends made-up results to your platform and shows how it answered.","testButton":"Send a test event","sending":"Sending…","testDelivered":"Delivered · {status} · {ms} ms","testFailed":"The test event could not be sent.","httpStatus":"HTTP {status}","setByName":"Set by {name} on <time></time>.","setBy":"Set on <time></time>.","removeButton":"Remove webhook","removing":"Removing…","removeConfirm":"Remove the webhook? Tests stop being sent to your platform. The delivery log stays.","removed":"Webhook removed.","removeFailed":"The webhook could not be removed.","logTitle":"Delivery log","logIntro":"What Echelio sent to your platform in the last 30 days.","failedOnly":"Failed only","colWhen":"When","colWhat":"What","colStatus":"Status","colHttp":"HTTP","colActions":"Actions","logEmpty":"No deliveries yet. Send a test event to see one.","logEmptyFailed":"No failed deliveries.","deletedTest":"Deleted test","update":"Update {sequence}","statusDelivered":"Delivered <time></time>","statusRetrying":"Next try <time></time>","statusQueued":"Sends <time></time>","statusSending":"Sending","statusFailed":"Failed","statusSuperseded":"Replaced by a newer update","sendAgain":"Send again","sendAgainFailed":"The results could not be sent again.","details":"Details","detailUrl":"Sent to","detailAttempts":"Attempts","detailDuration":"Duration","detailError":"Error","detailLastAttempt":"Last attempt","detailNextAttempt":"Next attempt","detailDelivered":"Delivered","detailResponse":"Answer from your platform","durationMs":"{ms} ms"}},"suggestions":{"title":"Suggested skill tags","intro":"Progress counts only tagged problems. Uncheck any suggestion that does not fit, then add them.","sectionTitle":"Problems without skills","untaggedQuestions":{"one":"{count} untagged problem","other":"{count} untagged problems"},"usedInTests":{"one":"{count} already used in your tests","other":"{count} already used in your tests"},"showingFirst":"showing the first {count}","allTagged":"Every problem has at least one skill.","tagged":{"one":"Tagged {count} problem.","other":"Tagged {count} problems."},"failed":"The tags could not be added.","adding":"Adding…","addButton":"Add {tags} to {questions}","tagCount":{"one":"{count} tag","other":"{count} tags"},"questionCount":{"one":"{count} problem","other":"{count} problems"},"colQuestion":"Problem","colUsed":"Used in tests","colSkills":"Skills","noTopics":"No topics","legend":"Suggested skills for {title}"},"viewOnly":{"title":"View only","body":"You don't teach this class, so you can see its results but not change them.","taughtBy":"Taught by {names}."},"schoolOverview":{"title":"School overview","intro":"Every class of your school side by side, to see which one needs help first.","open":"School overview","back":"Back to Progress","filtersLabel":"Choose the classes to compare","status":"Class status","statusAll":"All classes","statusRunning":"Running","statusUpcoming":"Upcoming","statusEnded":"Ended","teacher":"Teacher","anyTeacher":"Any teacher","from":"From","to":"To","activeBetween":"Active between","sort":"Sort by","sorts":{"help":"Needs help first","name":"Name","average":"Lowest average first","participation":"Lowest participation first","activity":"Least recent activity first"},"pick":"Classes","pickAllSummary":{"one":"The {count} class","other":"All {count} classes"},"pickNoneMatch":"No class matches","pickSearch":"Search classes","pickNoResult":"No class with this name.","pickApply":"Apply","pickCount":"{picked} of {total} selected","pickAll":"Select all","pickNone":"Clear","reset":"Reset filters","noClasses":"Your school has no classes yet.","noMatch":"No class matches these filters.","truncated":"Showing the first {shown} of {count} classes. Narrow the filters to see the others.","totalsLabel":"School totals","classes":{"one":"class","other":"classes"},"learners":{"one":"learner","other":"learners"},"testsGiven":{"one":"test given","other":"tests given"},"runningSuffix":"{count} running","averageScore":"Average score","participation":"Participation","needAttention":{"one":"learner needs attention","other":"learners need attention"},"helpTitle":"Needs help first","helpIntro":"Ranked by the share of learners on the class's Needs attention list, then by skills where the class has no level, then by the lower average.","helpEmpty":"No class needs attention right now.","helpReasonLearners":"{count} of {total} learners need attention","helpReasonSkills":{"one":"{count} skill with no class level","other":"{count} skills with no class level"},"helpReasonAverage":"average {average}","compareTitle":"Classes side by side","compareIntro":"Tests and quizzes both count in tests given, the average and participation. Needs attention and levels come from code tests, as on each class's Progress page.","colClass":"Class","colLearners":"Learners","colTests":"Tests given","colAverage":"Average","colParticipation":"Participation","colAttention":"Needs attention","colActivity":"Last activity","attentionCell":{"one":"{count} learner","other":"{count} learners"},"skillGapsCell":{"one":"{count} skill","other":"{count} skills"},"notRanked":"No finished code test yet","noActivity":"No work yet","viewProgress":"View Progress","levelsTitle":"Levels by skill","levelsIntro":"Each class's learners by level in every skill assessed in at least one of these classes.","levelsEmpty":"None of these classes has a test with tagged problems yet.","notAssessed":"Not assessed"},"practice":{"title":"Practice","intro":"Problems your students solved on their own. Practice is not graded and never changes levels. You see solves only, never code or failed attempts.","practisedBadge":{"one":"{count} of {total} practised","other":"{count} of {total} practised"},"solves":"Solved","activeThisWeek":"Practised this week","topSkills":"Skills","lastPractised":"Last practised","never":"Never","empty":"No student of this class has solved a practice problem yet."},"student":{"tabsLabel":"Student pages","tabProgress":"Progress","tabTests":"Tests","tabPractice":"Practice","tabQuizzes":"Quizzes","classes":"Classes: {classes}","classRemoved":"{name} (removed)","removedNote":"Removed from {className} on <time></time>. Their results in this class stay here.","colClass":"Class","colStatus":"Status","testsTitle":"Tests","testsIntro":"Every test given to this student in the classes you can see, newest first. Open one for the full results.","quizzesTitle":"Quizzes","quizzesIntro":"The quizzes given to this student as tests, newest first. Open one to read their answers.","resultCount":{"one":"{count} result","other":"{count} results"},"noTests":"No test has been given to this student yet.","noQuizzes":"No quiz has been given to this student yet.","pages":"Results pages","toReview":"{count} to review","pointsOf":"{earned} of {total} points","passedOf":"{passed} of {total} problems passed","practiceIntro":"Which problems this student solved on their own, and when. You never see their code or failed attempts.","practisedToday":"Practised today","notYetToday":"No solve yet today","noStreak":"No streak right now","recentSolves":"Recently solved","noSolves":"This student has not solved a practice problem yet."},"progress":{"title":"Progress","intro":"Where each learner stands, who needs attention, and what to reteach.","noClasses":"Progress follows the classes you teach. <link>Create or join a class</link> to see it here.","learnerBadge":{"one":"{count} learner","other":"{count} learners"},"finishedTests":{"one":"{count} finished test","other":"{count} finished tests"},"runningTests":"{count} running","untaggedNotice":{"one":"<strong>{count} problem in this class's tests has no skill yet,</strong> so it does not count toward any level.","other":"<strong>{count} problems in this class's tests have no skill yet,</strong> so they do not count toward any level."},"reviewTags":"Review suggested tags","tagQuestions":"Tag problems","noStudents":"No students are enrolled in {name} yet.","noTests":"No tests in {name} yet. Levels appear once learners have taken a test.","attentionTitle":"Needs attention","attentionIntro":"Recomputed from finished tests. Each line says why it is here.","attentionBadge":{"one":"{count} item","other":"{count} items"},"attentionEmpty":"Nothing needs attention right now.","wholeClass":"Whole class · {skill}","readyForChallenge":{"one":"{count} learner ready for a challenge","other":"{count} learners ready for a challenge"},"suggestedNext":"Suggested next test","levelsTitle":"Class level by skill","levelsIntro":"A learner reaches a difficulty after fully solving {count} different problems at it in tests.","notAssessedAt":"Not assessed at {levels}","assessedEverywhere":"Assessed at every difficulty","learnersNotAssessed":{"one":"{count} learner not assessed","other":"{count} learners not assessed"},"levelsEmpty":"No tagged problem has been in a test yet.","notInAnyTest":"Not in any test yet: {names}","learnersTitle":"Learners","learnersIntro":"Each skill shows easy, medium, and hard. Select a learner for the evidence behind it.","colLearner":"Learner","colLastTests":"Last tests","colBlocker":"Main blocker","colLastActive":"Last active","activeWhen":"active {when}","noWorkYet":"no submitted work yet","classLabel":"Class","yourClasses":"Your classes","otherClasses":"Other classes","back":"Progress","lastActive":{"never":"never","today":"today","yesterday":"yesterday","daysAgo":{"one":"{count} day ago","other":"{count} days ago"}},"lastActiveWhen":"last active {when}","skillsAssessed":{"one":"{count} skill assessed: {levels}","other":"{count} skills assessed: {levels}"},"withoutLevel":"{count} without a level yet","atLevel":"{count} at {level}","noSkillAssessed":"no skill assessed yet","ladderTitle":"Level by skill","ladderIntro":"A difficulty is reached after fully solving {count} different problems at it in tests, hidden cases included. Weakest skills first.","colSkill":"Skill","levelLine":"Level: {level}","ladderEmpty":"No tagged problem has been in a test for {name} yet.","notInTheirTests":"Not in any of their tests yet: {names}","step":{"notAssessed":"Not assessed","notAssessedDetail":"No problem at this difficulty yet","reached":"Reached","solvedOf":"Solved {solved} of {given}","moreToReach":"{needed} more to reach","moreToReachFew":{"one":"{needed} more to reach · only {count} given so far","other":"{needed} more to reach · only {count} given so far"},"aria":"{difficulty}: {title}. {detail}."},"failuresTitle":"How failed attempts break","failuresIntro":{"one":"From the result of every run and submit in this class's tests. {count} failed attempt.","other":"From the result of every run and submit in this class's tests. {count} failed attempts."},"suggestedFocus":"Suggested focus:","failuresEmpty":"No failed attempts in tests yet.","historyTitle":"Test history","historyIntro":"Tests can mix difficulties freely; the mix is shown so scores are read in context. Newest first.","colTest":"Test","colDate":"Date","colQuestions":"Problems","colScore":"Score","mix":{"EASY":{"one":"{count} easy","other":"{count} easy"},"MEDIUM":{"one":"{count} medium","other":"{count} medium"},"HARD":{"one":"{count} hard","other":"{count} hard"}},"scoreRunning":"{score} · running","missed":"Missed","noGradedWork":"No graded work","running":"Running","noTestsAssigned":"No tests assigned to {name} in this class yet.","meter":{"aria":"{skill}: {level}. {steps}.","step":"{difficulty} {state}","reached":"reached","progress":"in progress","notAssessed":"not assessed"},"sparkline":{"aria":{"one":"Last {count} tests: {scores}","other":"Last {count} tests: {scores}"},"noScore":"no score"},"levelBar":{"aria":"{level} {count}","title":{"one":"{level}: {count} learner","other":"{level}: {count} learners"}},"meterLegend":{"reached":"Reached at easy, medium, hard: {count} different problems fully solved","given":"Given, not reached yet","notInTest":"Not in any test yet"},"failureRow":{"title":{"one":"{name}: {n} of {count} failed attempts","other":"{name}: {n} of {count} failed attempts"}},"followUp":{"text":"{level} test on {skills}","manySkills":"{count} skills","learnerFallback":"Learner","theseLearners":"these learners","names":{"ready":"Challenge · {level}","retest":"{skills} · {level} retest","catchUp":"{skills} · {level} catch-up","catchUpFor":"{skills} · {level} catch-up · {name}"},"pickFailed":"Problems could not be picked.","picking":"Picking problems…","create":"Create test","noMatchOne":"No {level} problems on {skills} that {who} still needs. Choose problems from the list, or tag more problems with this skill.","noMatchMany":"No {level} problems on {skills} that {who} still need. Choose problems from the list, or tag more problems with this skill.","pickedOne":{"one":"Picked {count} {level} problems on {skills} that {who} has not solved yet.","other":"Picked {count} {level} problems on {skills} that {who} has not solved yet."},"pickedMany":{"one":"Picked {count} {level} problems on {skills} that {who} have not solved yet.","other":"Picked {count} {level} problems on {skills} that {who} have not solved yet."},"matchedFew":{"one":"Only {count} matched, and a level needs {wanted}; add more if you can.","other":"Only {count} matched, and a level needs {wanted}; add more if you can."},"swap":"Swap, add, or remove any of them."},"reasons":{"drop":"Latest score {latest}, {drop} points below their earlier average of {average}","stuck":{"one":"No level yet in {notYet} of {assessed} assessed skills after {count} test","other":"No level yet in {notYet} of {assessed} assessed skills after {count} tests"},"missed":"Missed {name}","noGradedWork":"No graded work in {name}","inactive":"No activity for {days} days","noWork":"No submitted work yet","blocker":"Most failed attempts: {kind}","skillNoLevel":"{notYet} of {assessed} learners assessed in it have no level yet","fewQuestions":"Too few problems so far: at most {most} per difficulty, and a level needs {needed} solved","fewEasy":{"one":"Only {count} easy problem given, so learners below medium cannot reach a level","other":"Only {count} easy problems given, so learners below medium cannot reach a level"},"ready":{"one":"{names} reached hard in {skills} or more skills","other":"{names} reached hard in {skills} or more skills"}}}},"admin":{"shell":{"tag":"Super admin","navigation":"Super admin","overview":"Overview","organizations":"Organizations","users":"Users","quizzes":"Quizzes","activity":"Activity log","quotes":"Quote requests","contactMessages":"Contact messages","backToApp":"Back to teaching","accountMenu":"Super admin"},"overview":{"title":"Platform overview","intro":"Every organization on Echelio at a glance. Pages that show a school or its people are recorded in the activity log.","summaryLabel":"Platform summary","organizations":"Organizations","teachers":"Active teachers","students":"Active students","soloStudents":"Students without a school","runningClasses":"Classes running","testsLast30Days":"Tests in the last 30 days","submissionsLast7Days":"Submissions in the last 7 days","aiCostThisMonth":"AI cost this month","newestTitle":"Newest organizations","newestEmpty":"No organizations yet.","allOrganizations":"All organizations","activityTitle":"Recent activity","activityEmpty":"Nothing recorded yet.","allActivity":"Full log"},"organizations":{"title":"Organizations","intro":"Schools using Echelio. Open one to see its teachers, classes, and pending invitations.","new":"New organization","searchLabel":"Search organizations","searchPlaceholder":"Search by name","empty":"No organizations match.","colName":"Organization","colTeachers":"Teachers","colStudents":"Students","colClasses":"Classes","colPlan":"Plan","colCreated":"Created","created":"Created {date}","teachersCount":{"one":"{count} teacher","other":"{count} teachers"},"studentsCount":{"one":"{count} student","other":"{count} students"},"classesCount":{"one":"{count} class","other":"{count} classes"},"deletesOn":"Deletes on {date}"},"organization":{"back":"Organizations","aiOwnKey":"Own AI key","aiPlatform":"Echelio AI","inviteAdmin":"Invite admin","teachersTitle":"Teachers","teachersEmpty":"No active teachers yet. Invite the school's first admin.","colTeacher":"Teacher","colRole":"Role","colJoined":"Joined","admin":"Admin","teacher":"Teacher","invitationsTitle":"Pending invitations","colEmail":"Email","colInvitedBy":"Invited by","colStatus":"Status","invitationSent":"Sent","invitationExpired":"Expired","invitationFailed":"Sending failed","classesTitle":"Classes","classesEmpty":"No classes yet.","colClass":"Class","colDates":"Dates","colOwner":"Owner","colTests":"Tests","running":"Running","ended":"Ended","upcoming":"Upcoming","dates":"{start} – {end}"},"plan":{"title":"Plan","change":"Change plan","plan":"Plan","access":"Access","classes":"Classes that have not ended","students":"Students in those classes","contract":"Contract ends","plans":{"TEACHER":"Teacher","ORGANIZATION":"Organization"},"accessStates":{"PENDING_CHECKOUT":"Waiting for checkout","ACTIVE":"Active","READ_ONLY":"Read-only"},"usage":"{used} of {limit}","usageUnlimited":"{used}, no limit","noEndDate":"No end date","readOnlyFrom":"Read-only after {date} unless extended","readOnlySince":"Read-only since the end of {date}, 30 days after the contract","deletion":"Data deleted on","lastNotice":"Last notice: {notice}, sent {date}","noNotice":"No notice sent yet","notices":{"READ_ONLY":"read-only by contract","DAYS_30":"30 days","DAYS_7":"7 days","DAY_BEFORE":"day before"},"dialogIntro":"Changes apply at once and are logged. A limit below current use keeps everything that exists; only additions stop.","classLimit":"Class limit","studentLimit":"Student limit","limitHelp":"Classes and students count while their class has not ended. Leave empty for no limit.","contractEndsAt":"Contract's last day","contractHelp":"30 days after it, the organization becomes read-only unless you extend it. Leave empty for no end date.","aiGenerations":"AI quizzes and problems a month","aiGradings":"AI-graded answers a month","aiPlanDefault":"Plan default","aiHelp":"Counts only AI on Echelio's key. Leave empty for the plan's default: Teacher 50 and 3,000; Organization 50 per teacher and 100 per student.","timeZone":"Time zone","timeZoneHelp":"An IANA name such as Europe/Paris or America/New_York. Students' practice days and weeks follow it.","timeZoneUse":"Practice days and weeks","teacherDefaults":"The Teacher plan has 1 teacher, 1 class, and 30 students.","save":"Save","saving":"Saving…"},"ai":{"title":"AI this month","generations":"Quizzes and problems generated","gradings":"Answers graded","planDefault":"Plan default","setHere":"Set by a super admin","platformCost":"Cost on Echelio's key","ownKeyCost":"Cost on their own key","calls":{"one":"{count} call","other":"{count} calls"},"ownKeyModel":"Model {model}, not counted","note":"The allowance counts only AI on Echelio's key. Counts start again on {date}."},"create":{"title":"New organization","intro":"Creates the school and emails its first admin an invitation. They set their own password from the link.","name":"School name","namePlaceholder":"e.g. Northside Coding School","adminEmail":"First admin's email","adminEmailHelp":"The link is valid for 7 days. You can send another from the organization's page.","submit":"Create and invite","submitting":"Creating…","createdTitle":"Organization created","createdSent":"{name} is ready. An invitation went to {email}.","createdEmailFailed":"{name} is ready, but the invitation email to {email} could not be sent. Send it again from the organization's page.","open":"Open organization","another":"Create another"},"invite":{"title":"Invite an admin","intro":"Emails an invitation to join {organization} as an administrator. Sending to an address already invited replaces its link.","email":"Email","submit":"Send invitation","submitting":"Sending…","sent":"Invitation sent to {email}.","emailFailed":"The invitation to {email} was saved, but the email could not be sent. Try again."},"users":{"title":"Users","intro":"Every account on Echelio, across organizations. Search by name or email.","searchLabel":"Search users","searchPlaceholder":"Name or email","roleFilter":"Role","allRoles":"All roles","teachers":"Teachers","students":"Students","superAdmins":"Super admins","showRetired":"Include retired accounts","empty":"No users match.","colUser":"User","colRole":"Role","colOrganization":"Organization","colCreated":"Created","colStatus":"Status","noOrganization":"No organization","active":"Active","retired":"Retired","superAdminBadge":"Super admin","orgAdminBadge":"Admin","total":{"one":"{count} user","other":"{count} users"}},"quotes":{"title":"Quote requests","intro":"Schools that asked for an Organization plan quote, newest first. Each one was also emailed to the team; reply from there.","empty":"No quote requests yet.","colWhen":"Received","colWho":"Contact","colSchool":"School","colStudents":"Students a year","colMessage":"Message","emailFailed":"Email not sent"},"messageMore":"Show all","messageLess":"Show less","contactMessages":{"title":"Contact messages","intro":"Messages from the contact form, newest first. Each one was also emailed to the team; reply from there.","empty":"No contact messages yet.","colWhen":"Received","colWho":"Contact","colTopic":"Topic","colMessage":"Message","emailFailed":"Email not sent"},"quizzes":{"title":"Platform quizzes","intro":"Quizzes for every school's students to practise. Students see one once you open it for practice; teachers don't see them, and nobody sees students' answers.","total":{"one":"{count} quiz","other":"{count} quizzes"},"searchLabel":"Search quizzes","searchPlaceholder":"Title","empty":"No platform quiz yet. Create one, add its questions, then open it for practice.","emptySearch":"No quiz matches this search.","pagesLabel":"Quiz pages","colQuiz":"Quiz","colPractice":"Practice","colTries":"Finished tries","colUpdated":"Updated","open":"Open","closed":"Closed","createdBy":"Created by {name}","back":"Platform quizzes","platformBadge":"Platform quiz","newIntro":"Students see it once you open it for practice. You add questions on the next page.","descriptionPlaceholder":"What the quiz covers. Students see it in their list.","practiceOpenHelp":"Students of every school can practise this quiz on their own and see the correct answer and explanation after each question. Nobody sees their answers.","deleteIntro":"The quiz, its questions and every student's tries at it are deleted, in every school."},"activity":{"title":"Activity log","intro":"The school and people pages super admins opened, and every change they made, newest first.","empty":"Nothing recorded yet.","colWhen":"When","colWho":"Who","colAction":"Action","colPage":"Page","colOrganization":"Organization","actions":{"VIEW":"Opened a page","CREATE_ORGANIZATION":"Created an organization","INVITE_ADMIN":"Invited an admin","CHANGE_PLAN":"Changed the plan","CREATE_PLATFORM_QUIZ":"Created a platform quiz","UPDATE_PLATFORM_QUIZ":"Changed a platform quiz","DELETE_PLATFORM_QUIZ":"Deleted a platform quiz"},"removedOrganization":"Removed organization"},"errors":{"nameRequired":"Enter the school's name.","nameTooLong":"The name is too long.","organizationNotFound":"Organization not found.","teacherElsewhere":"This address belongs to an active teacher at another organization.","alreadyTeacherHere":"This person is already a teacher in this organization.","invalidLimit":"Enter a whole number, or leave the field empty.","invalidDate":"Enter a valid date.","invalidTimeZone":"Enter a time zone from the list, such as Europe/Paris."}},"billing":{"price":{"month":"a month","year":"a year","perMonth":"{amount} a month","perYear":"{amount} a year","taxNote":"+ VAT where applicable"},"checkout":{"trialNote":"One free trial per card. Nothing is charged today, and you can cancel any time before the trial ends.","paidNote":"Your subscription starts today. You can cancel any time; it then stops at the end of the period."},"signup":{"metaTitle":"Start your free trial","eyebrow":"Teacher plan","title":"Start your free trial.","intro":"14 days free, then {monthly} or {yearly}. Cancel any time.","submit":"Create my account","creating":"Creating your account…","failed":"Your account could not be created.","haveAccount":"Already have an account? <a>Sign in</a>","student":"A student? <a>Join your class</a> instead.","planTitle":"The Teacher plan","features":{"class":"1 class with up to 30 students","tests":"Code tests graded on hidden test cases","quizzes":"Quizzes, with AI drafting and grading included","progress":"Progress for every student and skill"},"schools":"Buying for a school? <a>Contact us</a> about the Organization plan."},"finish":{"metaTitle":"Finish setting up","eyebrow":"Almost there","codeTitle":"Check your email.","codeIntro":"We sent a 6-digit code to <b>{email}</b>. Enter it to confirm your address.","codeLabel":"Code","confirm":"Confirm","confirming":"Checking…","resend":"Resend code","resendIn":"Resend code in {seconds} s","resent":"A new code is on its way.","notSent":"We could not send the code. Use Resend code.","planTitle":"Choose how you pay.","planIntroTrial":"Your free trial starts today. Nothing is charged before {date}.","planIntroPaid":"Your subscription starts today.","monthly":"Monthly","yearly":"Yearly","yearlySaving":"2 months free","afterTrial":"after the trial","termsTrial":"I accept the <terms>Terms</terms> and the <privacy>Privacy Policy</privacy>.","termsPaid":"I accept the <terms>Terms</terms> and the <privacy>Privacy Policy</privacy>, and I ask for Echelio to start now.","startTrial":"Start my free trial","subscribe":"Continue to payment","opening":"Opening checkout…","failed":"Checkout could not open. Try again.","secure":"Payment is handled by Stripe. Echelio never sees your card.","notYou":"Not {email}? <a>Sign out</a>","cancelled":"Checkout was closed before the end. Nothing was charged."},"tab":{"title":"Billing","intro":"Your plan, its limits, and payments.","plan":"Plan","teacherPlan":"Teacher plan","organizationPlan":"Organization plan","status":{"trialing":"Free trial","active":"Active","past_due":"Payment failed","unpaid":"Ended","canceled":"Ended","incomplete":"Waiting for payment","incomplete_expired":"Ended","paused":"Paused","none":"Not started"},"price":"Price","trialEnds":"Trial ends","nextPayment":"Next payment","endsOn":"Stops on","cancelNote":"Your subscription is cancelled and stops on {date}. Everything works until then.","pastDueNote":"Your last payment did not go through. Stripe will try again; update your card so everything keeps running.","readOnlyNote":"Your subscription has ended, so this account is read-only. Subscribe again to get everything back. Your data is kept until {date}.","manage":"Manage billing","manageHelp":"Change your card, switch between monthly and yearly, see invoices, or cancel. Opens Stripe.","opening":"Opening…","failed":"Stripe could not be opened. Try again.","subscribeAgain":"Subscribe again","limits":"Limits","classes":"Classes that have not ended","students":"Students","used":"{used} of {limit}","unlimited":"{used}, no limit","contractEnds":"Contract ends","noEnd":"No end date","organizationReadOnlyNote":"Your contract has ended, so this organization is read-only. Your data is kept until {date}, then deleted.","organizationHelp":"Your school pays by invoice. To change the plan or the contract, write to <a>{email}</a>.","taxNote":"Prices exclude tax; Stripe adds what applies."},"banner":{"trialStartedTitle":"Your free trial has started","trialStartedBody":"It runs until {date}. Nothing is charged before then.","trialEndsTitle":"Your free trial ends on {date}","trialEndsBody":"Then {price} is charged to your card. <a>Manage billing</a>","pastDueTitle":"Your payment did not go through","pastDueBody":"Everything keeps working while Stripe tries again. <a>Update your card</a>","subscribeAgain":"<a>Subscribe again</a> to get everything back."},"pricing":{"metaTitle":"Pricing","metaDescription":"Echelio’s prices: the Teacher plan, with a 14-day free trial, and the Organization plan for schools. Students never pay.","eyebrow":"Pricing","title":"Simple pricing for teachers and schools.","intro":"Students never pay. Start with a 14-day free trial and cancel any time.","billedMonthly":"Billed monthly","billedYearly":"{amount} billed once a year","orYearly":"or {amount} a year, 2 months free","period":{"label":"Billing period","monthly":"Monthly","yearly":"Yearly","save":"Save {percent}"},"yearlyPerMonth":"That is {amount} a month, billed once a year","yearlyInsteadOf":"instead of {amount}","teacher":{"name":"Teacher","tagline":"For one teacher and one class.","cta":"Start free trial","ctaShort":"Free trial","trial":"14 days free. Card required; nothing is charged before the trial ends.","features":{"class":"1 class with up to 30 students","tests":"Code tests in JavaScript, Java, Python, PHP and SQL, graded on hidden test cases","quizzes":"Quizzes, with AI drafting and grading included","progress":"Progress for every student and skill","live":"Live leaderboard and class display"}},"organization":{"name":"Organization","tagline":"For schools and bootcamps.","from":"From","perStudent":"per student a year","yearlyOnly":"Yearly only","priceNote":"Billed yearly by invoice. Your quote gives the exact price.","cta":"Get a quote","features":{"teachers":"Unlimited teachers and classes","overview":"School overview for admins","webhook":"Results sent to your platform","library":"A shared problem library for your teachers","contract":"Students and AI allowance set in your contract","ownKey":"Option to use your own AI key","support":"Onboarding and support"}},"regional":"Showing the North Africa prices.","sectionTitle":"Pricing","sectionIntro":"Students never pay. A teacher starts with a 14-day free trial; a school gets a quote.","seeAll":"Estimate your school’s price","tax":"Prices exclude VAT and sales tax, which are added at checkout where they apply.","estimator":{"eyebrow":"Organization plan","title":"Estimate your school’s price.","intro":"Set your number of students and teachers to see a yearly estimate. Your quote gives the exact price.","students":"Students a year","studentsHint":"Every student enrolled in a class during the year.","teachers":"Teachers","teachersHint":"Teachers never change the price.","studentsValue":"{count} students","minimumMark":"Minimum","total":"Estimated price a year","perStudentMonth":"about {amount} per student a month","breakdown":"{count} students × {price}","minimumApplies":"Below {count} students, the yearly minimum of {amount} applies.","includedTitle":"Included for your school","includedTeachers":"Unlimited teachers and classes","includedGenerations":"{count} quizzes and problems generated with AI a month","includedGradings":"{count} answers graded with AI a month","includedNote":"The AI allowance is shared by the whole school. Your contract can set more, or you can use your own AI key.","cta":"Get a quote for {count} students","estimateNote":"An estimate before VAT, not an offer.","teacherFits":"One teacher with up to 30 students? The Teacher plan costs {amount} a year.","teacherFitsLink":"Start a free trial"},"compare":{"title":"Compare the plans","intro":"Both plans include every feature for students: code tests, quizzes, Progress, and the live class display.","feature":"Feature","rows":{"who":{"label":"Who it is for","teacher":"A teacher on their own","organization":"A school or bootcamp"},"teachers":{"label":"Teachers","teacher":"1","organization":"Unlimited"},"classes":{"label":"Classes","teacher":"1 at a time","organization":"Unlimited"},"students":{"label":"Students","teacher":"Up to 30","organization":"Set in your contract"},"overview":{"label":"School overview","teacher":"No","organization":"Included"},"webhook":{"label":"Results to your platform","teacher":"No","organization":"Included"},"library":{"label":"Problem library","teacher":"Your own","organization":"Shared by your teachers"},"ai":{"label":"AI each month","teacher":"{generations} quizzes and problems generated, {gradings} answers graded","organization":"{generations} quizzes and problems generated per teacher, {gradings} answers graded per student"},"ownKey":{"label":"Your own AI key","teacher":"No","organization":"Optional"},"trial":{"label":"Free trial","teacher":"14 days","organization":"No, a quote instead"},"payment":{"label":"Payment","teacher":"Card, monthly or yearly","organization":"Invoice, usually yearly"}}},"faq":{"title":"Billing questions","intro":"Anything else? Write to <a>{email}</a>.","items":{"students":{"question":"Do students pay?","answer":"Never. Students join a class with a link or a code and use Echelio for free. Only the teacher or the school pays."},"trial":{"question":"How does the free trial work?","answer":"The Teacher plan starts with 14 days free, one trial per card. Checkout takes your card, nothing is charged before the trial ends, and we email you before it does. Cancel before the end and you pay nothing."},"cancel":{"question":"Can I cancel or switch between monthly and yearly?","answer":"Yes, any time from the billing settings in Echelio. Cancelling stops the renewal at the end of the period you have paid for; a period already started is not refunded."},"schools":{"question":"How do schools pay?","answer":"By invoice, usually once a year. Tell us about your school and we send a quote based on your number of students, then set up your organization with you."},"move":{"question":"I’m on the Teacher plan. Can my school take over?","answer":"Yes. Your school invites you to its organization, and joining ends your Teacher plan with no further charge. Your classes and problems stay in your old account; support can move them for you on request."},"regional":{"question":"Why are prices lower in North Africa?","answer":"Teachers and schools in Morocco, Algeria, Tunisia, Egypt, Libya, and Mauritania get a lower price. It follows the country you visit from, and Morocco pays in dirhams."},"tax":{"question":"Is VAT included?","answer":"No. Prices exclude VAT and sales tax, which are added at checkout or on the invoice where they apply."}}}},"quote":{"cta":"Get a quote","metaTitle":"Get a quote","metaDescription":"Ask for an Organization plan quote for your school or bootcamp: unlimited teachers and classes, priced per student.","eyebrow":"Get a quote","title":"Talk to us about your school.","helpTitle":"Before you write","cards":{"plan":{"title":"The Organization plan","body":"Unlimited teachers and classes, a school overview, a shared problem library, and an AI allowance set for your school. From {price} per student a year.","link":"See pricing"},"teacher":{"title":"Teaching on your own?","body":"The Teacher plan covers one class of up to 30 students, with a 14-day free trial.","link":"Start a free trial"},"support":{"title":"Already using Echelio?","body":"For help with your account or a test, write to <a>{email}</a>."},"privacy":{"title":"Privacy requests","body":"To see, correct, or delete your data, write to <a>{email}</a>."}},"name":"Full name","namePlaceholder":"Ada Lovelace","email":"Work email","emailPlaceholder":"ada@school.edu","organization":"School or organization","organizationPlaceholder":"Analytical Academy","role":"Your role","roles":{"director":"Director or founder","program":"Head of a program","teacher":"Teacher","other":"Other"},"country":"Country","students":"Students a year","studentRanges":{"under50":"Fewer than 50","50to200":"50 to 200","200to500":"200 to 500","500to1000":"500 to 1,000","over1000":"More than 1,000"},"choose":"Choose…","message":"Tell us about your classes","optional":"optional","messagePlaceholder":"How many classes, which languages, when you would like to start, how you assess students today…","required":"required","consent":"By sending this form, you agree that we use these details to answer your request, as our <a>privacy policy</a> describes.","submit":"Send my request","sending":"Sending…","successTitle":"Thank you, your request is in.","successBody":"We will reply to {email} with a quote.","successBack":"Back to the home page","failed":"Your request could not be sent. Try again, or write to {email}.","errors":{"required":"Fill in this field.","organization":"Enter your school’s name.","country":"Choose a country.","choose":"Choose an option.","message":"Keep the message under 1,000 characters.","tooMany":"Too many requests from this network. Try again in an hour."}},"errors":{"emailInUse":"An account already uses this email address. Sign in instead.","organizationPlan":"Your school pays Echelio by invoice. Contact us about billing.","alreadySubscribed":"Your subscription is already running.","confirmEmailFirst":"Confirm your email address first.","noCustomer":"There is no billing account yet.","acceptTerms":"Accept the terms to continue.","codeWait":"Wait a few seconds before asking for another code.","tooManyCodes":"Too many codes were sent. Try again in an hour.","codeNotSent":"The code could not be sent. Try again in a moment.","codeExpired":"This code has expired. Ask for a new one.","codeWrong":{"one":"Wrong code. {count} try left.","other":"Wrong code. {count} tries left."},"tooManySignUps":"Too many sign-ups from this network. Try again later.","unavailable":"Teacher sign-up is not open right now.","notPending":"This account has already finished setting up.","finishSetUp":"Finish setting up your account to continue."}},"contact":{"cta":"Contact","metaTitle":"Contact","metaDescription":"Write to the Echelio team about support, a partnership, press, or anything else. For a price for your school, ask for a quote.","eyebrow":"Contact","title":"Write to us.","helpTitle":"Before you write","cards":{"quote":{"title":"Need a price for your school?","body":"The Organization plan is priced per student. Tell us about your classes and we will send a quote.","link":"Get a quote"},"support":{"title":"Already using Echelio?","body":"Choose Support in the form, and tell us the email address of your account and what you see on screen."},"privacy":{"title":"Privacy requests","body":"To see, correct, or delete your data, write to <a>{email}</a>."}},"name":"Full name","namePlaceholder":"Ada Lovelace","email":"Email","emailPlaceholder":"ada@example.com","topic":"Topic","topics":{"SUPPORT":"Support","PARTNERSHIP":"Partnership","PRESS":"Press","OTHER":"Something else"},"choose":"Choose…","message":"Your message","messagePlaceholder":"How can we help?","required":"required","consent":"By sending this form, you agree that we use these details to answer you, as our <a>privacy policy</a> describes.","submit":"Send my message","sending":"Sending…","successTitle":"Thank you, your message is in.","successBody":"We will reply to {email}.","successBack":"Back to the home page","failed":"Your message could not be sent. Try again, or write to {email}.","errors":{"required":"Fill in this field.","choose":"Choose an option.","message":"Keep the message under 2,000 characters.","tooMany":"Too many messages from this network. Try again in an hour."}},"email":{"fallbackLink":"If the button does not work, open:","assignment":{"subject":"You have been assigned: {session}","heading":"You have a new assessment","hello":"Hello {name},","body":"You have been assigned <b>{session}</b> in {className}.","starts":"Starts","ends":"Ends","joinCode":"Join code","open":"Open {app}"},"classInvitation":{"subject":"{teacher} invited you to {className}","heading":"You are invited to a class","hello":"Hello,","body":"<b>{teacher}</b> invited you to join <b>{className}</b> on {app}.","hasAccount":"Your student account has already been added. Sign in to see your class.","noAccount":"Create a free student account with this email address to join the class.","signInToJoin":"You already have an account with this email address. Sign in to join the class.","openClass":"Open your class","joinClass":"Join the class","createAccount":"Create your student account"},"folderInvitation":{"subject":"{owner} invited you to collaborate on {folder}","heading":"Folder collaboration invite","hello":"Hello {name},","body":"<b>{owner}</b> invited you to collaborate on the <b>{folder}</b> problem folder on {app}.","signIn":"Sign in with {email} and accept the invitation to see the folder in your library.","signInShort":"Sign in with {email} and accept to see it in your library.","review":"Review invitation","reviewWithExpiry":"Review invitation (expires in 7 days)","expires":"This link expires in 7 days. If you were not expecting it, you can ignore this email."},"organizationInvitation":{"subject":"{admin} invited you to join {organization} on {app}","heading":"Join your school on {app}","hello":"Hello,","bodyTeacher":"<b>{admin}</b> invited you to join <b>{organization}</b> on {app} as a teacher.","bodyAdmin":"<b>{admin}</b> invited you to join <b>{organization}</b> on {app} as an administrator.","next":"Open the link to choose your name and password. If you already have an account with this address, the page explains what happens to it.","join":"Join {organization}","expires":"This link works for 7 days and only once. If you were not expecting it, you can ignore this email."},"passwordReset":{"subject":"Reset your {app} password","heading":"Reset your password","hello":"Hello,","body":"We received a request to reset your {app} password. This link expires in 1 hour.","button":"Reset your password","ignore":"If you did not request this, you can safely ignore this email."},"emailCode":{"subject":"{code} is your {app} code","heading":"Confirm your email address","hello":"Hello {name},","body":"Enter this code in {app} to confirm your address. It works for 10 minutes.","ignore":"If you did not sign up for {app}, you can ignore this email."},"billing":{"hello":"Hello {name},","perMonth":"a month","perYear":"a year","trialEnding":{"subject":"Your {app} trial ends on {date}","heading":"Your free trial ends soon","body":"Your free trial ends on <b>{date}</b>. Your card will then be charged <b>{amount}</b> {per}, plus any tax that applies.","change":"To switch between monthly and yearly, or to cancel before then, open Manage billing."},"trialConverted":{"subject":"Your {app} subscription has started","heading":"Your subscription has started","body":"Your free trial has ended and your Teacher plan continues. Your next payment is on <b>{date}</b>."},"paymentFailed":{"subject":"We could not take your {app} payment","heading":"Your payment did not go through","body":"We could not charge your card for {app}. We will try again over the next few days, and everything keeps working meanwhile. Update your card so the next try works."},"readOnly":{"subject":"{organization} is now read-only on {app}","heading":"Your account is now read-only","body":"Your subscription has ended, so <b>{organization}</b> is read-only: you can sign in, see your classes, results, and Progress, and export them, but nothing new can be created.","keep":"Subscribe again to get everything back. Your data is kept for 90 days, then deleted.","button":"Subscribe again"},"contractReadOnly":{"subject":"{organization} is now read-only on {app}","heading":"Your organization is now read-only","body":"Your contract has ended, so <b>{organization}</b> is read-only: you can sign in, see your classes, results, and Progress, and export them, but nothing new can be created.","keep":"Your data is kept for 90 days, then deleted. To continue, write to us at <b>{contact}</b>."},"deletion":{"subject":"Your {app} data will be deleted on {date}","heading":"Your data will be deleted soon","body":"<b>{organization}</b> is read-only, and all its data will be deleted on <b>{date}</b>.","goes":"This includes its classes, students’ accounts and results, problems, and quizzes.","audience":{"TEACHER_PLAN":"Until then you can still sign in and export your results. To keep everything, subscribe again before then.","ORGANIZATION":"Until then you can still sign in and export your results. To keep your data, write to us at <b>{contact}</b> before then.","FORMER_ADMIN":"You joined a school with another account, so you can no longer sign in to this one. To get your classes, quizzes, and problems into your school account, ask us to move them before then: write to <b>{contact}</b>."},"moveButton":"Ask us to move your work into your school"},"deletionTomorrow":{"subject":"Your {app} data will be deleted tomorrow","heading":"Your data will be deleted tomorrow","body":"<b>{organization}</b> is read-only, and all its data will be deleted tomorrow, <b>{date}</b>."},"contactButton":"Contact us","manage":"Manage billing","updateCard":"Update your card","open":"Open {app}"},"webhookFailed":{"subject":"Results of {session} were not sent to your platform","heading":"Results not delivered","hello":"Hello {name},","body":"{app} could not send the results of <b>{session}</b> to your platform, after trying for two days. The last answer: {error}","next":"Check your platform, then open the delivery log and press Send again. Other failures today are not emailed.","button":"Open the delivery log"}},"landing":{"metaTitle":"Coding assessment platform for schools · Echelio","metaDescription":"Echelio is a coding assessment platform for schools: auto-graded coding exams in several programming languages, quizzes, and skill levels for every learner.","socialImageAlt":"The Echelio logo above a pixel staircase in the logo’s colours","skipToContent":"Skip to content","nav":{"label":"Sections","product":"Product","how":"How it works","fair":"Fair testing","schools":"For schools","faq":"Questions"},"hero":{"titleStart":"Precise coding tests.","titleEnd":"Less grading.","intro":"Echelio gives your classes online coding exams and quizzes, grades every submission automatically against your test cases, and shows each learner’s level, skill by skill.","badge":"New: PHP problems"},"caps":{"label":"What Echelio covers","code":{"title":"Code tests","meta":"Checked against your test cases"},"quizzes":{"title":"Quizzes","meta":"Five question types"},"sandbox":{"title":"Isolated sandbox","meta":"Time and memory limits"},"progress":{"title":"Progress by skill","meta":"A level for every learner"},"display":{"title":"Live class display","meta":"Leaderboard and podium"},"languages":{"title":"English · Français","meta":"Per person"}},"evidence":{"title":"Every grade, backed by evidence.","intro":"Echelio keeps what happened during every test, so a score always comes with the reasons behind it.","chips":{"hidden":"Hidden test cases","history":"Run history","kinds":"Failed attempts by kind","timeouts":"Timeouts","edge":"Missed edge cases","syntax":"Syntax errors","wrong":"Wrong output","crashes":"Crashes","tabs":"Tab switches","away":"Time away","paste":"Copy and paste blocked","drops":"Dropped text blocked","versions":"Problem versions","scores":"Student scores","compile":"Compile errors","verified":"Verified reference solutions","levels":"Skill levels","attention":"Learners needing attention","followUp":"Follow-up tests","csv":"CSV export","aiGrading":"AI-graded open answers","review":"Teacher review","skillTags":"Skill tags","reasons":"Reasons for AI grades"}},"product":{"title":"From the first problem to the next lesson.","intro":"Coding tests, quizzes, progress tracking and a live class screen, in one online platform for teachers and students.","navLabel":"Features","code":{"title":"Code tests","beatOne":"You write the cases.","beatTwo":"We run every one.","text":"Functions, methods or complete programs, in JavaScript, Java, Python, PHP or SQL today and more languages soon. Every submission is graded automatically, and a problem is published only once its reference solution passes every public and hidden case.","meta":"Public · hidden cases","link":"More about code tests"},"quiz":{"title":"Quizzes","beatOne":"Draft with AI.","beatTwo":"Keep the last word.","text":"Single and multiple choice, true or false, short and open answers, for what code can’t grade. Draft questions with AI and let it grade open answers, while you keep the last word. Give a quiz on its own, or in the same test as code problems, for one score.","meta":"Five question types","link":"More about quizzes"},"progress":{"title":"Progress","beatOne":"Every attempt counts.","beatTwo":"Every skill gets a level.","text":"A level per skill for every learner, the learners who need attention, and a follow-up test built from problems they haven’t solved yet.","meta":"Easy · Medium · Hard","link":"More about Progress"},"practice":{"title":"Practice","beatOne":"Between tests,","beatTwo":"they keep coding.","text":"About 945 code challenges in JavaScript, Java, Python, PHP and SQL, free for every student, with or without a school, with a daily challenge, streaks and, in a class, the school leaderboard. Practice is never graded and never changes Progress levels.","meta":"Free for students","link":"More about practice"},"display":{"title":"Class display","beatOne":"Put the class on screen.","beatTwo":"End on a podium.","text":"Project a live leaderboard: the join code, the time left, and every student’s progress as it happens, ending on a podium.","meta":"Live in class","link":"More about the class display"}},"mock":{"quiz":{"type":"Single choice","draft":"Drafted with AI","question":"What does [1, 2, 3].map(x => x * 2) return?"},"progress":{"title":"Skill levels","attention":"Needs attention","skills":{"loops":"Loops","arrays":"Arrays","functions":"Functions"},"levels":{"none":"Not yet","easy":"Easy","medium":"Medium","hard":"Hard"}},"display":{"joinCode":"Join code","timeLeft":"Time left"}},"how":{"title":"An auto-graded test in three steps.","write":{"title":"Write the problem","text":"Give a prompt, starter code, public examples and hidden cases. Echelio runs your reference solution against every case before you publish."},"code":{"title":"Students code in the browser","text":"They write and run code in a full editor, then submit. Every submission is checked against all the cases, hidden ones included."},"evidence":{"title":"Read the evidence","text":"Every run and submission is kept. Failed attempts are sorted into syntax errors, crashes, wrong output, timeouts and missed edge cases, then feed each learner’s levels."},"example":{"resultsLabel":"Results","wrongAnswer":"Wrong answer","pattern":"Missed edge case","patternText":"The public examples pass, a hidden case fails."}},"fair":{"title":"Fair coding exams, by design.","intro":"You decide what students can run, see and do during a test, and you can see what happened.","sandbox":{"title":"Code runs in a sandbox","text":"Student code never runs in the app. Each case gets a fresh, isolated execution with time and memory limits."},"hidden":{"title":"Hidden cases stay hidden","text":"Students never receive hidden inputs, expected results or the raw output of hidden cases."},"verified":{"title":"Every problem is verified","text":"A problem can’t be published until its reference solution passes all of its cases."},"paste":{"title":"Copy and paste blocked","text":"During a test, the editor blocks copy, cut, paste and dropped text."},"tabs":{"title":"Tab switches recorded","text":"Each time a student leaves the test, you see when and for how long."},"versions":{"title":"Reports match the test","text":"A test keeps the problem versions it used, so every report shows exactly what students answered."}},"schools":{"title":"Made for schools that teach coding.","intro":"Each school is an organization, with its teachers, classes, problems and one shared skill list.","tabsLabel":"School features","bank":{"title":"A shared problem bank","text":"Problems your teachers write stay in your organization, next to a platform library every school can use. Save favourites and share folders."},"skills":{"title":"One skill list","text":"Admins keep the list, teachers tag problems, and progress follows those skills across classes and languages."},"invitations":{"title":"Invite by email or link","text":"Students join a class from an email invitation or a shareable link, and hear about each test assigned to them."},"languages":{"title":"English and French","text":"Each person picks their language, and the emails they receive follow it."},"export":{"title":"Results you can take with you","text":"Export a test’s results to CSV, tab switches and time away included."}},"faq":{"title":"Questions, answered.","intro":"What schools usually ask before their first test.","what":{"question":"What is Echelio?","answer":"Echelio is a coding assessment platform for schools. Teachers publish code tests and quizzes, students take them online in the browser, every code submission is graded automatically against the teacher’s test cases, and teachers see what each learner can do, skill by skill. Between tests, students practise code challenges for free."},"audience":{"question":"Who is Echelio for?","answer":"Schools and programs that teach programming: coding schools and bootcamps, colleges and universities, and secondary schools. Teachers write and run the tests, and students take them in the browser, with nothing to install."},"students":{"question":"Is Echelio free for students?","answer":"Yes. Students never pay: the teacher or the school does. Any student can sign up and practise for free, with or without a school, and every student in a class takes their tests for free, in the browser, with nothing to install."},"practice":{"question":"Can students practise outside tests?","answer":"Yes. Any student, in a class or learning alone, can solve about 945 code challenges in JavaScript, Java, Python, PHP and SQL at their own pace, with a daily challenge, streaks and a weekly goal, and their school’s leaderboard once they are in a class. Practice is never graded, never changes Progress levels, and teachers see only which problems each student solved and when."},"languages":{"question":"Which programming languages does Echelio support?","answer":"JavaScript, Java, Python, PHP and SQL today, with more languages on the way. In JavaScript, run on Node.js 24, students write a function. In Java, they write a method or a complete program that reads standard input and prints its answer. In Python 3.14, they write a function or a complete program that reads standard input and prints its answer. In PHP 8.5, they write a function, a complete program, or a function that reads and changes a database through PDO. In SQL, they write a query, a data change or a table design, and the result is compared row by row. Each problem is written for one language, and the school’s skill list follows learners across all of them."},"mixed":{"question":"Can one test have code problems and a quiz?","answer":"Yes. A Code and quiz test holds code problems and one of the teacher’s quizzes, in two parts, in the order the teacher picks. Code is graded against public and hidden cases, the quiz grades itself except open answers, which wait for the teacher’s review, and the two parts make one score: the teacher sets how much the code part counts, from 10% to 90%."},"cheating":{"question":"How does Echelio limit cheating?","answer":"During a test, the editor blocks copy, cut and paste, and each tab switch is recorded with the time away. Hidden cases never reach the browser. After a code test, each student’s code is compared with their classmates’, and the teacher sees the answers most alike side by side. No browser-based test can rule cheating out entirely: these controls make it harder and make it visible."},"sandbox":{"question":"Where does student code run?","answer":"In an isolated Judge0 sandbox, never inside Echelio itself. Each case runs in a fresh execution with time and memory limits, and results are compared with the expected ones on the server."},"hosting":{"question":"Where is Echelio hosted?","answer":"On servers in Germany (Hetzner, in Nuremberg), where student code runs too. A few providers are outside the EU, such as the email service and, when teachers use AI, OpenRouter. The privacy policy lists each one."},"evidence":{"question":"What do teachers see after a test?","answer":"Every run and submission, failed attempts sorted by kind, tab switches and time away, and each student’s score, with a CSV export. Progress turns the results into a level per skill for every learner."},"ai":{"question":"Can AI grade quiz answers?","answer":"Yes. AI drafts quiz questions and grades open answers, with a reason for each grade, within a monthly allowance included in your plan. Teachers can change any grade. Student answers are not used to train models. Schools on the Organization plan can use their own OpenRouter key instead."}},"cta":{"title":"Your next test starts here.","teachersTitle":"Teachers","teachersText":"Try Echelio free for 14 days: write problems, build a test and follow your class.","studentsTitle":"Students","studentsText":"Students never pay. Create your account and start practising, with or without a school. With your teacher’s class link, you take your tests here too.","studentsLink":"What students get"},"footer":{"explore":"Explore","account":"Account","copyright":"© {year} Echelio","theme":{"label":"Theme","system":"System","light":"Light","dark":"Dark"}}},"legal":{"nav":{"label":"Legal","privacy":"Privacy policy","terms":"Terms of use","notice":"Legal notice","privacyShort":"Privacy","termsShort":"Terms","shortLabel":"Legal pages"},"updated":"Last updated {updated}","contents":"On this page","subprocessors":{"line":"<b>{name}</b> ({location}): {purpose}","worldwide":"served worldwide","hosting":"Hosts the application, its database, its job queue, and the server that runs students’ code. Holds all the data described above.","email":"Delivers the emails Echelio sends: class invitations, test assignments, folder invitations, password reset links, and product news. Receives the recipient’s email address and the content of the message. For product news, it also keeps the address’s list (teachers or students), its language, and whether it unsubscribed.","ai":"When a teacher uses an AI feature, and to translate problems. Receives the text described below and forwards each request to the model provider it selects.","network":"Carries all traffic to Echelio (protection against attacks, redirects) and, on the public pages only, counts visits without cookies. Sees each request’s network address, the page, and the browser.","payments":"Takes payment for the Teacher plan: the card, the billing address, and tax details are entered on Stripe’s page. Receives the teacher’s email address and tells Echelio the subscription’s status."},"privacy":{"metaTitle":"Privacy policy","metaDescription":"How Echelio handles personal data: what it collects, why, who processes it, how long it is kept, and how to exercise your rights.","title":"Privacy policy","intro":"This policy explains what personal data Echelio handles when schools, teachers, and students use it, and what your rights are.","who":{"title":"Who we are","intro":"Echelio is a coding assessment platform for schools. In this policy, “we” means Echelio.","scope":"It covers the Echelio website and application. For questions about your data, write to <email>{privacyEmail}</email>."},"roles":{"title":"Our role: controller and processor","school":"Echelio is used by schools and other training organizations. For the data of its teachers and students (classes, questions, answers, results), <b>the organization is the data controller</b>: it decides why and how the data is used. Echelio acts as its <b>processor</b>, handling that data on the organization’s behalf and following its instructions. Its administrators can stop Echelio’s product news to its students.","echelio":"For its own website and for the accounts needed to sign in and keep the service secure, <b>Echelio is the controller</b>. That covers account and sign-in data, security records, and the emails the service sends, including product news.","students":"If you are a student, your school is your first contact for questions about your results and about how your data is used in your course. You can also write to us."},"data":{"title":"What we collect and why","intro":"We collect only what the service needs. This list comes from what the application stores.","account":"<b>Account:</b> your name, email address, and a hash of your password if you have one (never the password itself), your role (teacher or student), whether the account is active, and whether your email address is confirmed, with, until it is entered, a hash of the 6-digit code that confirms it. If you sign in with Google: your Google account’s identifier and the address it had when you linked it.","classes":"<b>Organization and classes:</b> the organization you belong to and your role in it, the classes you are in, and each class’s name and dates.","invitations":"<b>Invitations:</b> the email addresses teachers invite to a class or share a folder with, and whether and when the invitation email was sent.","content":"<b>What teachers write:</b> questions, test cases, solutions, quizzes, folders, skills, and the tests they schedule.","work":"<b>What students produce in code tests:</b> the code they write, which is saved as they type, each run and submission with its time, the result of every test case (including run time and memory), the score, and the output of visible test cases.","quizzes":"<b>Quiz answers:</b> each answer, the automatic result, the final result, and who set it.","activity":"<b>Test activity:</b> when a student joined, finished, ran examples, or submitted, and, only when the teacher turned the option on for that test, each time the student left the test page and for how long.","grading":"<b>Grading and progress:</b> teachers’ corrections, the verdict and short reason of an AI grading when a teacher asked for one (the reason is for the teacher only), and the skill levels Echelio calculates from a learner’s results.","technical":"<b>Security records:</b> to limit guessing of passwords and join codes, we keep for 24 hours the email address and network address of failed sign-in attempts and password reset requests, and a hash of the network address and browser identifier of join-code attempts.","visits":"<b>Visits to the public site:</b> on the public pages only, never inside the application, Cloudflare Web Analytics counts visits: the page, the site you came from, your country, your browser and device type, and how fast the page loaded. It sets no cookie, stores nothing on your device, and does not follow you from one visit or site to another.","language":"<b>Preferences:</b> the language you choose for the interface, and whether you want product news.","quotes":"<b>Quote requests:</b> when a school asks for a quote, the name, work email, and role of the person asking, and the school’s name, country, type, size, languages, start date, and message entered in the form.","contact":"<b>Contact messages:</b> when you write to us from the contact form, your name, email address, the topic you choose, the message you write, and the language of the page.","billing":"<b>Billing (Teacher plan):</b> Stripe’s identifiers for the customer and the subscription, the plan, price, and status, the trial and renewal dates, a fingerprint of the card that started a free trial (so each card gets one trial), and when the terms were accepted. The card number and billing address stay with Stripe; Echelio never sees the card number.","never":"We do not run advertising, we do not sell personal data, and we do not track people: the visit counts above use no cookie or identifier. Echelio does not profile people for marketing."},"bases":{"title":"Legal bases","intro":"Under the GDPR and similar laws, we rely on these bases.","contract":"<b>Performance of a contract</b> (providing the service to the organization and its members), for account data and for the data processed on the organization’s behalf.","interests":"<b>Legitimate interests</b>, for keeping the service secure, preventing abuse and cheating on tests, fixing faults, counting visits to the public site, and sending product news about the service to people who have an account, which they can stop in their account settings or from any of those emails.","obligation":"<b>Legal obligations</b>, when the law requires us to keep or hand over information.","school":"For the data it controls, the organization chooses its own legal basis, for example its teaching mission or its contract with the student. We do not rely on consent for ordinary use of Echelio."},"recipients":{"title":"Who sees your data","intro":"Access depends on role, and an organization never sees another organization’s members or results.","teachers":"<b>Teachers</b> see the classes they teach, and their students’ code, answers, results, and test activity. They see questions and quizzes shared with them.","similarity":"When a teacher turns it on for a code test, they can see, once the test ends, which of their students’ answers are alike, side by side. Students are told while they take the test. The comparison runs on Echelio’s servers and sends code nowhere.","admins":"<b>Organization administrators</b> manage members and settings of their own organization.","webhook":"An organization can have Echelio send its tests’ results to its own systems, such as its learning platform: each student’s name, email, scores, how each question ended, finish time, and tab switches. Echelio sends them only to the address the organization’s administrators set, never code or answers.","students":"<b>Students</b> see their own work and results.","display":"A teacher can open a <b>live class display</b> on a screen. It shows participants’ names and scores to the people in the room.","staff":"A small number of <b>Echelio staff</b> can access organizations’ data to run the service and give support, only as far as the task needs. What they open in Echelio’s staff pages is recorded."},"providers":{"title":"Service providers","intro":"We use the providers below to run Echelio. Each handles personal data only to provide its service.","execution":"<b>Code execution.</b> Echelio runs students’ code itself, on its own server at {hostName}, in {hostPlace}. When a student runs or submits code, the code and the test input go to that server, which runs it in an isolated sandbox with time and memory limits and returns the output. No other company receives it, and nothing that identifies the student is sent with it.","ai":"<b>AI features.</b> Drafting and grading run only when a teacher uses them. AI quiz drafting sends the teacher’s request (topic, level, question types, language) and the beginning of the quiz’s existing questions, so the model does not repeat them. AI problem drafting sends the teacher’s request (what the problem should practise, its programming language and kind, its difficulty, and the language to write in) and the titles of problems the teacher can already see in that programming language, for the same reason. AI grading sends, for each open answer a teacher chose to grade, the question, any code shown with it, the grading notes, the explanation, and the student’s answer. Problem translation runs on its own: when a problem is published, used in a test, or opened by someone who reads the other language, its title, statement and constraints are sent to be translated between English and French, and the translation is kept with the problem; no student’s code or answer is sent. Quiz translation runs only for a quiz whose author switched it on: then, and after each change to the quiz, its title, description, and each question’s prompt, options, explanation, and accepted short answers are sent to be translated, and the translation is kept with the quiz; grading notes and students’ answers are not sent. None of these sends a name, email address, or account number. If a student writes personal data in an answer, that text is sent too. OpenRouter forwards each request to the model provider it selects for the chosen model. Echelio sends these requests through its own OpenRouter account, set to use only providers that do not train on the text, so student answers are not used to train models. An organization on the Organization plan may add its own OpenRouter key instead; then that organization’s account and the model provider handle the text under their own terms.","email":"<b>Email.</b> Echelio sends service emails (invitations, test assignments, password resets) and, a few times a year, product news about new features to people who have an account. Every product news email has an unsubscribe link, and product news can also be turned off in the account settings. For product news, Brevo also keeps each address’s list (teachers or students), its language, and whether it unsubscribed. Echelio sends no advertising for other companies.","payments":"<b>Payments.</b> A teacher who buys the Teacher plan pays on Stripe’s checkout page. Stripe handles the card, the billing address, and tax details under its own privacy policy, and sends Echelio the subscription’s status, never the card number. Schools on the Organization plan are invoiced through Stripe.","google":"<b>Sign in with Google.</b> If you choose Continue with Google, Google tells Echelio your Google account’s identifier, your name, your email address, and whether Google has verified that address. Echelio asks for nothing else (no contacts, files, or calendar) and tells Google nothing about what you do in Echelio. Google handles the sign-in itself under its own privacy policy."},"transfers":{"title":"International transfers","intro":"Echelio’s servers, including the one that runs code, are in {hostPlace}. OpenRouter, Stripe, and Cloudflare are in the United States, outside the European Economic Area, and the model providers OpenRouter forwards requests to may be elsewhere too.","safeguards":"These transfers rely on the contractual safeguards those providers offer."},"retention":{"title":"How long we keep data","intro":"Some records expire on their own; the rest stays while the organization uses Echelio.","sessions":"Sign-in sessions last 7 days at most and are then deleted.","reset":"Password reset links are valid for one hour and are deleted once expired.","google":"A Google sign-up left before choosing student or teacher is deleted after 15 minutes.","security":"Failed-attempt records are deleted after 24 hours.","school":"Accounts, classes, questions, and results are kept while the organization uses Echelio. When an organization stops paying or its contract ends, it becomes read-only and its data is kept for 90 days, so it can pay again and get everything back. Its admins are emailed 30 days, 7 days, and the day before; then the data is deleted. We keep only a short record that the organization was deleted (its identifier, plan, and dates, no names) for support and accounting, and the fingerprint of any card that started a free trial, so each card still gets one trial. A student’s data is deleted immediately when their account is deleted.","signup":"A teacher sign-up that never finishes checkout, and a student sign-up that never confirms its email address, are deleted after 7 days. The code that confirms an email address works for 10 minutes.","billing":"Invoices and payment records are kept, by Stripe and by us, as long as tax and accounting law requires.","quotes":"A quote request is kept while we discuss it with the school and for up to 2 years after, then deleted.","contact":"A contact message is kept while we answer it and for up to 2 years after, then deleted.","news":"An address is removed from Brevo when its account is deleted. While the account exists, an address that unsubscribed from product news stays marked as unsubscribed, so it is not emailed again.","backups":"Backup copies are kept for up to {backupDays} days and then permanently deleted. Until then they are used only to restore the service after an incident."},"security":{"title":"How we protect data","intro":"These measures are part of the application.","passwords":"Passwords are stored only as bcrypt hashes. Sign-in session tokens and password reset tokens are stored only as hashes.","sessions":"The sign-in cookie cannot be read by page scripts and is sent only over secure connections in production.","sandbox":"Students’ code runs on a separate execution server, in a sandbox with time, memory, and output limits.","keys":"An organization’s AI key is encrypted before it is stored, and only its last four characters are ever shown again.","limits":"Sign-in attempts, password resets, and join-code attempts are rate-limited.","access":"Each person sees only what their role and organization allow, and hidden test cases are never sent to students’ browsers."},"rights":{"title":"Your rights","intro":"You have the right to:","access":"access the personal data we hold about you and get a copy;","rectification":"have inaccurate data corrected;","erasure":"have your data erased, where the law provides for it;","objection":"object to processing based on legitimate interests, and ask us to restrict processing;","portability":"receive the data you provided in a portable format, where the law provides for it;","complaint":"lodge a complaint with the data protection authority of your country.","how":"To use these rights, write to <email>{privacyEmail}</email>. We may ask you to prove who you are, and we answer within one month.","school":"For data an organization controls, we pass your request to it or point you to it, because it decides what happens to that data."},"children":{"title":"Children and students","school":"The organization decides who uses Echelio. It is responsible for informing students and for any parental consent its law requires.","age":"Echelio sets no minimum age. Students use it through their school or training organization, and whether they are under 18 depends on the school."},"cookies":{"title":"Cookies and local storage","intro":"Echelio uses only what it needs to work.","session":"<b>Sign-in cookie:</b> keeps you signed in, for 7 days at most. Not readable by page scripts.","google":"<b>Google sign-in cookies:</b> one protects a Google sign-in while it is in progress (10 minutes at most), the other holds a new account while you choose student or teacher (15 minutes at most). Not readable by page scripts.","language":"<b>Language cookie:</b> remembers your language for one year. Visiting a page in a language sets it.","theme":"<b>Theme cookie:</b> remembers the theme you pick (system, light or dark) at the bottom of the public pages, for one year. It is set only when you pick one.","storage":"<b>Browser storage:</b> a copy of the code you are writing, so a lost connection does not lose your work, and the language last chosen for AI quiz and problem drafting. These stay on your device.","none":"These are essential, so no consent banner is needed. There are no advertising, analytics, or third-party cookies."},"changes":{"title":"Changes to this policy","text":"When we change this policy, we update the date at the top. For a significant change, we also tell organization administrators in the application or by email."},"contact":{"title":"Contact","text":"For any question about this policy or your data, write to <email>{privacyEmail}</email>. The publisher’s details are in the <notice>legal notice</notice>."}},"terms":{"metaTitle":"Terms of use","metaDescription":"The terms for using Echelio: accounts, responsibilities of schools, acceptable use, content, AI features, and liability.","title":"Terms of use","intro":"These terms apply to everyone who uses Echelio. By creating an account or signing in, you accept them.","service":{"title":"The service","what":"Echelio is a coding assessment platform for schools and teachers. Teachers build code tests and quizzes, students take them, and Echelio runs and grades the answers and shows the results. Who publishes it is stated in the <notice>legal notice</notice>.","accept":"If you use Echelio for an organization, you confirm that you may accept these terms on its behalf. How we handle personal data is described in the <privacy>privacy policy</privacy>."},"subscription":{"title":"Plans, payment, and cancellation","plans":"Students never pay. A teacher can buy the Teacher plan (one teacher, one class, up to 30 students) on Echelio. Schools buy the Organization plan from us under a separate agreement, usually paid by invoice.","trial":"The Teacher plan starts with a 14-day free trial, once per organization and once per card. A card is required. Unless you cancel before the trial ends, it becomes a paid subscription, monthly or yearly as you chose, and your card is charged then. We email you 3 days before the trial ends.","renewal":"A subscription renews automatically at the end of each period, at the price you subscribed at, until you cancel. Prices exclude VAT and sales tax, which are added at checkout where they apply. If we change the price, we tell you at least 30 days before your next renewal at the new price.","cancel":"You can cancel at any time in Manage billing, on your organization’s Billing tab. The subscription then stops at the end of the period already paid, and nothing more is charged.","refunds":"Payments are not refunded, including for the rest of a period you cancel during, except where the law requires a refund. Joining a school on the Organization plan ends your Teacher plan at once, with no further charge and no refund for the rest of the period.","withdrawal":"If you are a consumer in the European Union, you can withdraw within 14 days of subscribing by writing to us. With the free trial, this period ends before your first payment. If you subscribe without a trial, you ask us to start at once, and if you withdraw within 14 days we refund what you paid, minus the days already used.","lapse":"If a payment fails, our payment provider tries again for up to two weeks, and everything keeps working meanwhile. If it still fails, or the subscription ends, your organization becomes read-only: you can sign in, see your classes and results, and export them, but nothing new can be created. Its data is kept for 90 days, then deleted; we email your organization’s admins 30 days, 7 days, and the day before.","payments":"Payments are processed by Stripe. We never see your card number."},"accounts":{"title":"Accounts and roles","roles":"There are teacher accounts, student accounts, and organization administrators. Students usually join through a class invitation and take tests with a join code; teachers belong to an organization. What you can see and do depends on your role.","duties":"Give accurate information and keep your password secret. You are responsible for what happens under your account. Tell us at once if you think someone else has used it."},"schools":{"title":"Responsibilities of schools","intro":"An organization that uses Echelio is responsible for how its members use it. It must:","lawful":"have the right to process its students’ and teachers’ personal data in Echelio, and a lawful basis for doing so;","inform":"inform students, and their parents where the law requires it, about how their data is used;","rules":"set clear rules for each test, and decide what happens when those rules are broken;","questions":"make sure it may use the questions and material it adds."},"use":{"title":"Acceptable use","intro":"You must not:","attacks":"attack, probe, overload, or try to escape the code sandbox or any other part of the service;","access":"get into accounts, classes, or data that are not yours, or get around limits and rate limits;","cheating":"use tools, scripts, or other people to cheat in a test, or share answers when the teacher has not allowed it;","content":"upload or write content, including code, that is unlawful, infringes someone’s rights, or is meant to harm people or systems;","automation":"scrape the application or use it to build a competing service.","action":"We may remove content, suspend access, or close an account that breaks these rules, and an organization may do the same for its members."},"content":{"title":"Content and ownership","ownership":"Schools and teachers own the questions, quizzes, and class material they add. Students own the code and answers they write.","licence":"You give Echelio and your organization the right to store, process, display, and run your content, only as far as needed to provide the service: for example, to run students’ code, show results to teachers, and export a class’s results.","echelio":"Echelio’s software, name, logo, and design belong to the publisher. These terms give you the right to use the service, not to copy or resell it."},"ai":{"title":"AI features","optional":"AI quiz and problem drafting and AI grading are optional and included in each plan up to a monthly allowance; problem and quiz translation is included without counting against it. An organization on the Organization plan may connect its own OpenRouter account instead; it then pays for that use and answers for its choice of model.","wrong":"AI output can be wrong, incomplete, or unfair. Drafted questions may contain mistakes, a translation may misword a problem or a quiz question, and a grade may misjudge an answer.","teacher":"Teachers keep the final word: they review drafted questions before using them, and they can change any AI grade. An AI grade counts until a teacher changes it, so teachers should check them."},"availability":{"title":"Availability","service":"We work to keep Echelio running, but we provide it as it is and do not promise it will always be available or free of errors. We may change or remove features, and we try to give notice of significant changes.","execution":"Running code depends on an execution server that can be unavailable. Teachers should plan for that when they schedule an important test."},"termination":{"title":"Ending your use","you":"You can stop using Echelio at any time. An organization can close its members’ accounts.","us":"We may suspend or close an account that breaks these terms or puts the service or others at risk, and we try to tell the organization first when we can.","after":"When access ends, data is handled as the <privacy>privacy policy</privacy> describes. Clauses that are meant to continue, such as ownership and liability, do."},"liability":{"title":"Liability","law":"Nothing in these terms limits liability that cannot be limited by law, including liability for death or personal injury and for fraud.","limits":"Otherwise, to the extent the law allows, our liability is limited, and we are not liable for indirect damage, loss of data, loss of profit, or a test result affected by an outage or by an AI grade. Organizations should keep their own copy of important results; results can be exported."},"changes":{"title":"Changes to these terms","text":"We may update these terms. The date at the top shows the latest version. For a significant change, we tell organization administrators in the application or by email. If you keep using Echelio after a change takes effect, you accept it."},"contact":{"title":"Contact","text":"Questions about these terms: <email>{contactEmail}</email>."}},"notice":{"metaTitle":"Legal notice","metaDescription":"Who publishes Echelio, who hosts it, and how to contact the publisher.","title":"Legal notice","intro":"The information the law requires about the publisher and host of this website.","publisher":{"title":"Publisher","name":"<b>Name:</b> {publisher}","email":"<b>Email:</b> <email>{contactEmail}</email>"},"host":{"title":"Host","text":"The website and application are hosted by {hostName}, {hostAddress}. The servers are in {hostPlace}."},"property":{"title":"Intellectual property","echelio":"The Echelio name and logo, the design of the website and application, and its texts and illustrations belong to the publisher. Copying or reusing them without written permission is not allowed.","content":"Questions, quizzes, code, and answers added by users belong to their authors, as the <terms>terms of use</terms> describe.","software":"Echelio uses open-source components, which remain under their own licences."},"data":{"title":"Personal data","text":"How we handle personal data, and how to exercise your rights, is explained in the <privacy>privacy policy</privacy>."},"contact":{"title":"Contact","text":"To reach the publisher, write to <email>{contactEmail}</email>."}}},"site":{"nav":{"product":"Product","students":"Students","breadcrumb":"Breadcrumb"},"explore":{"title":"Keep exploring.","label":"Other pages","link":"Learn more"},"footer":{"product":"Product","allFeatures":"All features","webhookDocs":"Results webhook for developers"},"webhooks":{"metaTitle":"Results webhook for developers","metaDescription":"How Echelio sends a school’s test results to its own platform: the signed request, the JSON it carries, checking the signature, and retries.","eyebrow":"For developers","title":"Receive test results on your platform","intro":"When a test ends, Echelio can send its results to your school’s platform: a learning platform, student records, or a script of your own. This page is for the developer who sets up the receiving end.","updated":"Last updated {date}","contents":"On this page","sections":{"overview":{"title":"How it works","body":"An administrator of your school sets an address under <b>Organization → Webhook</b> in Echelio. From then on, each test that ends is sent to that address as an HTTPS <code>POST</code> with a JSON body. It is part of the Organization plan.","points":{"every":"<b>Every test</b> of the school: code tests, quizzes and mixed tests. Practice is never sent.","full":"<b>A full copy each time</b>: every student’s results, not only what changed. Keep the latest copy.","signed":"<b>Signed</b> as the Standard Webhooks specification describes, so you can check each request came from Echelio.","private":"<b>No code and no answers</b>: scores, participation, how each question ended, finish times and tab switches."}},"when":{"title":"When it is sent","body":"A test is sent about a minute after it ends, when its end time passes or a teacher stops it. It is sent again, as a new full copy, whenever a result changes after that:","points":{"late":"a submission made before the end finishes grading;","graded":"a teacher grades an answer, or accepts an answer for every student who gave it;","ai":"the AI grades an open answer;","removed":"a student is removed from the class, or added back."},"group":"Changes within a minute of each other go in one copy, so a teacher grading 30 answers sends one or two copies, not thirty.","final":"Each copy of a test has a <code>sequence</code> one higher than the last. While answers still wait for grading, <code>session.final</code> is <code>false</code>; a later copy brings the settled results.","past":"Tests that ended before the address was set are not sent by themselves; an administrator can send one from its page. To try your side, use <b>Send a test event</b> under Organization → Webhook: it sends made-up results with <code>\"type\": \"test\"</code>."},"request":{"title":"The request","body":"Echelio sends a <code>POST</code> to your address with these headers:","headers":{"content-type":"always <code>application/json</code>;","user-agent":"<code>Echelio-Webhooks/1</code>;","webhook-id":"the delivery’s id, the same on every retry of it;","webhook-timestamp":"when it was sent, in seconds since 1 January 1970 (UTC);","webhook-signature":"<code>v1,</code> followed by the signature, explained below."},"answer":"Answer with any 2xx status within 10 seconds. Anything else counts as a failure and is tried again, a redirect included: redirects are not followed. The address must use HTTPS and be reachable from the internet."},"payload":{"title":"What it contains","body":"A mixed test, sent while one answer still waits for grading:","topLevel":"The top level","scores":"Scores are percentages from 0 to 100, rounded to one decimal, and times are in minutes, as in Echelio’s CSV export.","participationValues":"<code>participation</code> is one of {values}.","outcomeValues":"A quiz question’s <code>outcome</code> is one of {values}; <code>TO_REVIEW</code> waits for a teacher."},"signature":{"title":"Checking the signature","body":"Your administrator finds the signing secret under Organization → Webhook. It starts with <code>whsec_</code>; keep it on your server only. Check each request against its raw body, before parsing the JSON: the signature covers the exact bytes Echelio sent.","libraryTitle":"With a library","library":"Standard Webhooks offers libraries for many languages, listed on <link>standardwebhooks.com</link>. In JavaScript:","nodeTitle":"Without a library","node":"The signature is the HMAC-SHA256 of <code>webhook-id</code>, <code>webhook-timestamp</code> and the body, joined by dots, keyed with the secret’s bytes after <code>whsec_</code> (base64), and written in base64. In Node.js:","rotate":"When an administrator makes a new secret, the old one stops working at once; deliveries that fail meanwhile are tried again, signed with the new one."},"handling":{"title":"Handling deliveries","points":{"fast":"<b>Answer first, then work.</b> Store the body and answer 200, then process it, so slow work never makes a delivery fail.","sequence":"<b>Keep the highest sequence.</b> For each <code>session.id</code>, keep the copy with the highest <code>sequence</code> and ignore a lower one.","duplicate":"<b>Skip what you have seen.</b> A delivery can arrive twice, for example when your answer was lost; skip a <code>webhook-id</code> you have already handled.","test":"<b>Leave test events out.</b> Requests with <code>\"type\": \"test\"</code> carry made-up students.","match":"<b>Match students</b> by <code>email</code>, the address they sign in with, or by Echelio’s <code>id</code>."}},"retries":{"title":"When delivery fails","body":"Echelio tries a delivery eight times over about two days: at once, then after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 12 hours and 24 hours. A newer copy of the same test takes the place of one still waiting to be tried again.","email":"If every attempt fails, the school’s administrators get an email, at most one a day. The delivery log under Organization → Webhook shows each delivery, its attempts and your platform’s answer for 30 days. Fix your side, then press <b>Send again</b>."}},"fields":{"top":{"type":"<code>session.results</code>, or <code>test</code> for a test event.","sequence":"Grows by one with each copy of the same test, from 1. A test event has 0.","sentAt":"When this copy was built, in ISO 8601 (UTC).","organization":"Your school: <code>id</code> and <code>name</code>.","class":"The class the test was given to: <code>id</code> and <code>name</code>."},"session":{"id":"The test’s id in Echelio, the same in every copy.","name":"The test’s name, as the teacher wrote it.","format":"<code>CODE</code>, <code>QUIZ</code> or <code>MIXED</code>.","dates":"The test’s scheduled start and end.","closedAt":"When it ended: its end time, or when a teacher stopped it.","stoppedEarly":"Whether a teacher stopped it before its end time.","final":"True once no student’s result can still change by grading.","codeWeight":"Mixed tests: the code part’s share of the score, in percent. Null otherwise.","resultsUrl":"The test’s results page in Echelio, for teachers.","questions":"The questions and problems, in the order students meet them."},"question":{"key":"<code>q1</code>, <code>q2</code>… for quiz questions, <code>c1</code>, <code>c2</code>… for code problems. Students’ results use the same keys.","part":"<code>QUIZ</code> or <code>CODE</code>.","points":"Quiz questions: what the question is worth.","code":"Code problems: the problem’s title, its programming language, and its weight in the score."},"student":{"id":"The student’s id in Echelio.","identity":"The student’s name, and the email they sign in with.","removed":"True when a teacher removed the student from the class after the test; their results stay.","participation":"How the student took part (values below).","provisional":"True while one of the student’s answers or submissions still waits for grading.","rank":"The student’s place in the class; null without a score.","score":"The student’s score on the whole test; null when they did not take it.","quiz":"Quizzes and mixed tests: <code>points</code>, <code>totalPoints</code> and the quiz part’s <code>score</code>. Null in a code test.","code":"Code and mixed tests: the code part’s <code>score</code> and how many problems were <code>passed</code> in full. Null in a quiz.","completed":"When the student finished, and how long after the start, in minutes; null if they never finished.","tabs":"How often the student left the test’s tab, and for how long in all; null when the test does not record tab switches.","questions":"Each question’s <code>outcome</code> (quiz) or best <code>score</code> (code), by key."}}},"hub":{"metaTitle":"Features: code tests, quizzes, progress and practice","metaDescription":"Everything Echelio does for coding classes: auto-graded code tests, quizzes with AI grading, progress by skill, free practice for students, fair testing and a live class display.","eyebrow":"Features","title":"Everything a coding class needs.","statement":"Write a test, let students code in the browser, and read what each one can do, skill by skill. Between tests, students keep practising, for free.","cardsTitle":"One platform, from the first problem to the next lesson.","cardsIntro":"Each part works on its own and feeds the others: tests feed Progress, Progress suggests practice, practice keeps students coding until the next test.","cta":"Start with one class."},"pages":{"codeTests":{"metaTitle":"Auto-graded coding tests for classes","metaDescription":"Online coding exams graded automatically against your test cases, hidden ones included. Students write real code in the browser, in JavaScript, Java, Python, PHP or SQL, and every attempt is kept.","name":"Code tests","title":"Coding tests that grade themselves.","statement":"Write the problem and its test cases once. Students code in the browser, and every submission is checked against every case, hidden ones included, the moment they submit.","card":"Auto-graded coding exams with public and hidden test cases.","points":{"title":"Real code, graded the same way for everyone.","intro":"A code test is a timed session your class joins with a code. Every answer is real code, run in a sandbox and compared with the expected results.","one":{"title":"Public examples, hidden cases","text":"Students run the public examples as often as they like. Hidden cases run only on submit, and their data never reaches the browser."},"two":{"title":"Problems checked before you publish","text":"Echelio runs your reference solution against every case. A problem is published only once it passes all of them."},"three":{"title":"Every attempt kept","text":"Runs and submissions are saved with their results, so a score always comes with the code and the cases behind it."}},"steps":{"title":"From a problem to a graded test.","one":{"title":"Write or pick problems","text":"Give a prompt, starter code, examples and hidden cases, or pick problems from the platform library and your school’s problem bank."},"two":{"title":"Schedule the test","text":"Choose the class, the time window and the problems. Students hear about the test and join it with its code."},"three":{"title":"Read the results","text":"Scores arrive as students submit. Failed attempts are sorted by kind, and the results feed each learner’s Progress."}},"details":{"title":"The details.","intro":"What a code test supports today.","one":{"term":"Languages","text":"JavaScript on Node.js 24, Java 21, Python 3.14, PHP 8.5 and SQL on SQLite, with more languages on the way. Each problem is written for one language."},"two":{"term":"Problem formats","text":"In JavaScript, students write a function. In Java, they write a method or a complete program that reads standard input and prints its answer. In Python, they write a function or a complete program that reads standard input and prints its answer. In PHP, they write a function, a complete program, or a function that reads and changes a database through PDO. In SQL, they write a query, a data change or a table design, and the result is compared row by row."},"three":{"term":"Difficulty","text":"Each problem is easy, medium or hard. A test runs from easy to hard and can shuffle the problems within each level."},"four":{"term":"Failed attempts","text":"Sorted into syntax and compile errors, crashes, wrong output, timeouts and missed edge cases."},"five":{"term":"Problem library","text":"A platform library of about 945 problems that every school can use, next to the problems your teachers write. Save favourites and share folders."},"six":{"term":"Export","text":"Export a test’s results to CSV, with each student’s score, tab switches and time away."}},"faq":{"title":"Questions about code tests.","intro":"What teachers ask before their first auto-graded test.","one":{"question":"How are coding tests graded?","answer":"Automatically. Each submission runs in an isolated sandbox against every test case of the problem, public and hidden, and the teacher sees which cases passed and how the others failed."},"two":{"question":"Can students see the hidden test cases?","answer":"No. Hidden inputs, expected results and raw output never reach the browser. Students see only whether each hidden case passed, so they cannot write code that fits the examples alone."},"three":{"question":"Do students need to install anything?","answer":"No. Students write, run and submit code in a full editor in the browser. Their code runs on Echelio’s servers, never on their computer."},"four":{"question":"Which programming languages can a test use?","answer":"JavaScript, Java, Python, PHP and SQL today, with more languages on the way. JavaScript runs on Node.js 24, Java on Java 21, Python on Python 3.14, PHP on PHP 8.5 and SQL on SQLite."},"five":{"question":"Can I reuse problems written by other teachers?","answer":"Yes. Problems your teachers write stay in your school’s problem bank, and the platform library is open to every school. Teachers can also share folders with each other."},"six":{"question":"What happens if a student’s code never stops?","answer":"Each case runs with time and memory limits. Code that runs too long is stopped with a timeout, which is recorded as its own kind of failure."}},"cta":"Give your first auto-graded test."},"quizzes":{"metaTitle":"Online quizzes with AI drafting and AI grading","metaDescription":"Quizzes for what code can’t grade: single and multiple choice, true or false, short and open answers. Draft questions with AI and let it grade open answers, while teachers keep the last word.","name":"Quizzes","title":"Quizzes for everything code can’t test.","statement":"HTML and CSS, Git, framework concepts, reading code: give a quiz as a test, grade choices automatically, and let AI grade open answers, with a reason for each grade.","card":"Five question types, AI drafts, and AI grading you can override.","points":{"title":"Five question types, graded fairly.","intro":"A quiz is given as a test, like a code test: one class, one time window, one join code.","one":{"title":"Graded on submit","text":"Single and multiple choice, true or false and short answers are graded automatically. Multiple choice is all or nothing."},"two":{"title":"Drafted with AI","text":"Describe the topic and AI drafts the questions, in English or French. You edit every question before it reaches a class."},"three":{"title":"Open answers graded by AI","text":"When you ask, AI grades open answers, with a reason for each grade that only teachers see. You can change any grade."}},"steps":{"title":"From a quiz to its results.","one":{"title":"Write the quiz","text":"Add questions by hand or draft them with AI. Any question can carry a code snippet, points and an explanation."},"two":{"title":"Give it as a test","text":"Pick the class and the time window. Students answer one question at a time and move forward only."},"three":{"title":"Review and export","text":"Choices are graded at once. Review open answers yourself or with AI, accept a common answer for everyone, then export to CSV."}},"details":{"title":"The details.","intro":"What a quiz supports today.","one":{"term":"Question types","text":"Single choice, multiple choice, true or false, short answer and open answer. Each can show a read-only code snippet."},"two":{"term":"Short answers","text":"Compared with each accepted answer after trimming and collapsing spaces, with case sensitivity when you want it."},"three":{"term":"Anti-cheating","text":"Questions and answer options shuffled per student, copy and paste blocked, and tab switches recorded."},"four":{"term":"Results for students","text":"You choose whether students see their score and the correct answers. Correct answers appear only once the test closes."},"five":{"term":"AI allowance","text":"AI drafting and grading use a monthly allowance included in your plan. Student answers are not used to train models."},"six":{"term":"Sharing","text":"Share a quiz with teachers of your school, duplicate it, or copy one of Echelio’s own quizzes and make it yours."}},"faq":{"title":"Questions about quizzes.","intro":"What teachers ask about quizzes and AI.","one":{"question":"Can AI grade open answers?","answer":"Yes, when the teacher asks. AI marks each open answer correct or wrong and gives a reason that only teachers see. Teachers can change any grade, and every change is recorded as theirs."},"two":{"question":"Do quiz results change a student’s Progress levels?","answer":"No. Quiz answers are easy to guess or copy, so Progress levels come from code tests only. Quiz results stay in the test’s results and its CSV export."},"three":{"question":"Can students practise with a quiz?","answer":"Yes. A teacher can open a quiz for practice. Students then take it on their own, see the answer and its explanation after each question, and try again as often as they like. Echelio also publishes practice quizzes of its own."},"four":{"question":"In which languages can AI draft a quiz?","answer":"English and French. The questions are yours to edit before you give the quiz."},"five":{"question":"Can I project a quiz’s leaderboard?","answer":"Yes. Every test, quizzes included, has a class display for the projector: the join code, the time left and a live leaderboard that ends on a podium."},"six":{"question":"Are student answers used to train AI models?","answer":"No. Answers go to the AI only when a teacher asks for AI grading, and they are not used to train models."}},"cta":"Give your first quiz."},"progress":{"metaTitle":"Student progress tracking by skill","metaDescription":"Echelio turns coding test results into a level per skill for every learner, lists the learners who need attention and why, and builds a follow-up test from problems they haven’t solved yet.","name":"Progress","title":"Know what every learner can do.","statement":"Progress turns test results into a level per skill for each learner, says who needs attention and why, and prepares the follow-up test. Nobody fills in a skill grid by hand.","card":"A level per skill for every learner, built from test results.","points":{"title":"From results to the next lesson.","intro":"Every problem is tagged with skills from your school’s list, and every problem solved in a test counts toward a level in those skills.","one":{"title":"A level per skill","text":"Not yet, easy, medium or hard. A level is reached once three different problems of that difficulty are fully solved in tests."},"two":{"title":"Who needs attention, and why","text":"A falling score, skills with no level yet, a missed test or a week without work: each learner on the list comes with the reason."},"three":{"title":"A follow-up test in one click","text":"Create test picks problems at the right difficulty that those learners haven’t solved yet, and opens the test builder for them."}},"steps":{"title":"How Progress builds itself.","one":{"title":"Tag problems with skills","text":"Admins keep one skill list for the school. Teachers tag problems, and Echelio suggests tags from each problem’s topics."},"two":{"title":"Give tests","text":"Every problem fully solved in a test counts toward the learner’s level at its difficulty, across classes and languages."},"three":{"title":"Act on what you see","text":"Open a learner’s page for their levels, tests, practice and quizzes, or follow up with a test for the learners who need it."}},"details":{"title":"The details.","intro":"How levels and attention are worked out.","one":{"term":"Levels","text":"Not yet, easy, medium and hard, per skill. Three fully solved problems at a difficulty reach that level."},"two":{"term":"What counts","text":"Code test solves only. Practice and quizzes never change levels, so a level always reflects work done in a test."},"three":{"term":"Skill list","text":"One list per school, kept by its admins. Skills follow learners across classes and programming languages."},"four":{"term":"Needs attention","text":"A latest score 20 points below the learner’s average, three skills with no level, a missed test, or seven days without work."},"five":{"term":"Student page","text":"One page per student, with tabs for Progress, Tests, Practice and Quizzes."},"six":{"term":"Practice panel","text":"Practice solves per student, by difficulty and skill, and when they last practised. No code and no failed attempts."}},"faq":{"title":"Questions about Progress.","intro":"What teachers ask about levels.","one":{"question":"How does Echelio work out a student’s level?","answer":"For each skill, Echelio counts the different problems tagged with it that the student fully solved in tests. Three solved at a difficulty reach that difficulty’s level: easy, medium or hard."},"two":{"question":"Does practice change Progress levels?","answer":"No. Only tests count, so every learner’s level rests on the same kind of work. Teachers see practice separately: which problems each student solved and when."},"three":{"question":"Who decides the skills?","answer":"The school’s admins keep one skill list. Teachers tag problems with those skills, and Echelio suggests tags from each problem’s topics for admins to review."},"four":{"question":"Why is a learner listed as needing attention?","answer":"Each line gives the reason: a latest score well below their average, several skills with no level yet, a missed test, or no work for a week. The main kind of mistake they make is shown too."},"five":{"question":"Can I see one student’s whole history?","answer":"Yes. Each student has a page with their level in each skill, every test result, their practice and their quiz results."},"six":{"question":"Does Progress follow a student across classes?","answer":"Yes. Skills belong to the school, not to a class, so a learner’s levels add up across every class and programming language."}},"cta":"See your class, skill by skill."},"practice":{"metaTitle":"Coding practice for students, free in every class","metaDescription":"About 945 code challenges in JavaScript, Java, Python, PHP and SQL that students solve at their own pace, with a daily challenge, streaks, a school leaderboard and practice quizzes. Free for students.","name":"Practice","title":"Practice that keeps students coding.","statement":"Between tests, students solve code challenges at their own pace. A daily challenge, streaks and a school leaderboard bring them back, and practice never touches their grades.","card":"About 945 code challenges, a daily challenge, streaks and a leaderboard.","points":{"title":"Built for practice, not for grades.","intro":"Practice is free for every student, in a class or learning alone. It opens the whole platform library and keeps score in points, never in grades.","one":{"title":"About 945 code challenges","text":"JavaScript, Java, Python, PHP and SQL, easy to hard, in English or French, filtered by language, difficulty, skill and status. Each one is checked against public and hidden cases."},"two":{"title":"Reasons to come back","text":"A daily challenge for the whole school, a streak of days, a weekly goal, tiers from Bronze to Diamond and a school leaderboard."},"three":{"title":"Private by design","text":"Teachers see which problems a student solved and when, never their code or failed attempts. Practice never changes Progress levels."}},"steps":{"title":"How practice works.","one":{"title":"Pick a challenge","text":"Start from Suggested for you, today’s challenge or the full list. Each challenge shows its difficulty and its points."},"two":{"title":"Code and submit","text":"Run the public examples, then submit. A challenge is solved only when every case passes, hidden ones included."},"three":{"title":"Earn points","text":"1 point for easy, 3 for medium and 5 for hard on the first solve, plus a bonus point for the daily challenge."}},"details":{"title":"The details.","intro":"What students find in practice today.","one":{"term":"Daily challenge","text":"The same problem each day for the whole school, or for everyone practising without one, easier early in the week and harder at the weekend. Solving it on the day earns a bonus point."},"two":{"term":"Streak and weekly goal","text":"The streak counts days in a row with a solve. Each student sets a weekly goal of 1, 3, 5 or 10 problems."},"three":{"term":"Leaderboard","text":"Students of the same school, ranked all time, this month and by most improved. At most 20 points a day count, so nobody climbs by rushing."},"four":{"term":"Tiers and skill sets","text":"Bronze from 10 points, then Silver, Gold, Platinum and Diamond at 600. A skill set is complete once every problem of the skill is solved."},"five":{"term":"Suggested for you","text":"Problems one difficulty above where the student’s tests put them, in their weakest skills first. Before any test, the ones they started, then new ones at their level."},"six":{"term":"Practice quizzes","text":"Quizzes a teacher opens for practice, and Echelio’s own, with the answer and its explanation after each question and unlimited tries."}},"faq":{"title":"Questions about practice.","intro":"What teachers and students ask.","one":{"question":"Is practice free for students?","answer":"Yes. Students never pay. Any student can sign up and practise for free, with or without a school, and practice comes with every class, whether it belongs to a school or to a teacher on their own."},"two":{"question":"What do teachers see from practice?","answer":"Which problems each student solved, by difficulty and skill, and when they last practised. Never their code, their failed attempts or a grade."},"three":{"question":"Does practice affect grades or Progress levels?","answer":"No. Practice is never graded and never changes Progress levels. It only earns practice points."},"four":{"question":"How do students earn points?","answer":"1 point for an easy problem, 3 for medium and 5 for hard, on each problem’s first solve, plus 1 for the daily challenge. Up to 20 points a day count on the leaderboard."},"five":{"question":"Can students paste code into practice?","answer":"No. As in tests, the editor blocks paste and dropped text, so every solve is typed by the student."},"six":{"question":"Which languages can students practise?","answer":"JavaScript, Java, Python, PHP and SQL today, with more on the way. Students can filter the challenges by language."}},"cta":"Give your class a reason to code every day."},"fairTesting":{"metaTitle":"Fair online coding exams: anti-cheating and sandboxing","metaDescription":"How Echelio keeps online coding exams fair: sandboxed code, hidden test cases, blocked copy and paste, recorded tab switches, shuffled problems and similar code across the class, side by side.","name":"Fair testing","title":"Online exams you can stand behind.","statement":"You decide what students can run, see and do during a test, and every result comes with what happened. No browser test rules cheating out: Echelio makes it harder, and makes it visible.","card":"Sandboxed code, hidden cases, blocked paste, recorded tab switches and similar code side by side.","points":{"title":"Harder to cheat, easy to see.","intro":"Each control is on by default, and what it records is in the test’s results.","one":{"title":"Copy and paste blocked","text":"During a test, the editor blocks copy, cut, paste and dropped text."},"two":{"title":"Tab switches recorded","text":"Each time a student leaves the test, you see when and for how long."},"three":{"title":"Similar code side by side","text":"After a code test, you see the answers most alike in the class, side by side."}},"steps":{"title":"Fair from the problem to the report.","one":{"title":"Before the test","text":"A problem’s reference solution must pass all of its cases before it can be published, so a failed case is the student’s, not the problem’s."},"two":{"title":"During the test","text":"Code runs in an isolated sandbox with time and memory limits. Problems are shuffled per student, and leaving the page is recorded."},"three":{"title":"After the test","text":"The report keeps the problem versions students answered, every submission and each tab switch with the time away. Each student’s final code is compared with their classmates’, and the closest answers show side by side."}},"details":{"title":"The details.","intro":"Every control, and what it does.","one":{"term":"Sandbox","text":"Student code runs in an isolated Judge0 sandbox, never inside Echelio. Each case gets a fresh execution with time and memory limits."},"two":{"term":"Hidden cases","text":"Students see only whether each hidden case passed, never its input, its expected result or the output."},"three":{"term":"Shuffling","text":"Code tests run from easy to hard and shuffle the problems within each level. Quizzes shuffle questions and answer options per student."},"four":{"term":"Clipboard","text":"Copy, cut, paste and dropped text are blocked in the editor during tests, and paste in practice too."},"five":{"term":"Similar code","text":"Once a test with code problems ends, each student’s final code is compared with their classmates’ answers to the same problem, in JavaScript, Java, Python, PHP and SQL. Renaming, reformatting and comments don’t hide shared code. The starter code, and code most of the class writes, never make two answers alike, and problems with very short answers aren’t compared."},"six":{"term":"Quiz answers","text":"Students move forward only, and correct answers appear only once the test closes, so a finished student can’t pass them on."}},"faq":{"title":"Questions about fair testing.","intro":"What schools ask before giving exams online.","one":{"question":"Can Echelio stop all cheating?","answer":"No browser-based test can. Echelio blocks copy and paste, records every tab switch with the time away, keeps hidden cases out of the browser, shuffles problems and, after a code test, shows you the answers most alike in the class, so cheating is harder and what happened is visible."},"two":{"question":"Is it safe to run student code?","answer":"Yes. Student code never runs inside Echelio. Each case runs in an isolated sandbox, in a fresh execution with time and memory limits, and the results are compared on the server."},"three":{"question":"What does a tab switch record show?","answer":"For each switch, when the student left the test and how long they were away. It appears in the test’s results and in the CSV export."},"four":{"question":"Does Echelio use webcam proctoring?","answer":"No. Echelio does not use the camera, the microphone or screen recording."},"five":{"question":"Can I turn the controls off for a test?","answer":"Yes. Blocking copy and paste, recording tab switches, shuffling and comparing code across the class are settings of each test, all on by default."},"six":{"question":"Does Echelio check whether students’ code is alike?","answer":"Yes, once a code test ends. You see only the few pairs or groups of answers most alike, or that nothing stands out, and can open any of them side by side: shared code is highlighted in matching colours, and cases both students fail the same way are pointed out. Answers can be alike by chance, so it is a signal for you to look at: it never flags anyone or changes a score. Students are told while they take the test, and the comparison runs on Echelio’s servers, without sending code anywhere."}},"cta":"Give a test you can stand behind."},"classDisplay":{"metaTitle":"Live class leaderboard for the projector","metaDescription":"Project a live leaderboard during a coding test or a quiz: the join code, the time left and every student’s progress as it happens, ending on a podium.","name":"Class display","title":"Put the test on the big screen.","statement":"Open the class display on the projector: the class sees the join code, the time left and the leaderboard moving as answers come in. When the test ends, the top three stand on a podium.","card":"A live leaderboard for the projector, ending on a podium.","points":{"title":"Made for the projector.","intro":"The display is its own page, built for a room: big type, a dark stage, and only what the class should see.","one":{"title":"Join code first","text":"Before anyone joins, the display shows the join code in large type, with where to enter it."},"two":{"title":"Live progress","text":"While the test runs, each student’s row shows their rank, a progress track and their score, and slides when they move up."},"three":{"title":"A podium at the end","text":"When the test closes, the top three stand on a podium above the rest of the top ten."}},"steps":{"title":"Three moments of a test.","one":{"title":"Students join","text":"Press Show to class on the test page. The class reads the join code from the screen."},"two":{"title":"The race is on","text":"Rows move as students answer or submit, and the top of the screen counts down the time left."},"three":{"title":"The podium","text":"Once the test ends, the podium rises. Answers still waiting for review keep the board open until they are graded."}},"details":{"title":"The details.","intro":"What the display shows, and what it keeps off the screen.","one":{"term":"Works with","text":"Every test: code tests and quizzes, even quizzes that hide results from students."},"two":{"term":"What it shows","text":"The first ten students, with their rank, name, a progress track, a tick once finished, and their score."},"three":{"term":"What it hides","text":"Per-problem and per-question results, answers, tab switches and anything waiting for review. Those stay on the teacher’s page."},"four":{"term":"Screen","text":"A dark stage scaled to the screen, so ten rows fit a 1080p projector without scrolling."},"five":{"term":"Updates","text":"The board follows the test live, a few seconds behind each answer, with no reload."},"six":{"term":"Who opens it","text":"The teacher, signed in, in a new tab without the app’s navigation."}},"faq":{"title":"Questions about the class display.","intro":"What teachers ask before projecting a test.","one":{"question":"Do students see the leaderboard on their own screens?","answer":"No. The ranking is only on the class display, which the teacher chooses to project. Each student’s screen shows their test, not a ranking."},"two":{"question":"Does the display show students’ answers?","answer":"No. It shows rank, name, progress and score. Answers, per-problem and per-question results and tab switches stay on the teacher’s page."},"three":{"question":"Does it work for quizzes?","answer":"Yes, for every test, code tests and quizzes alike."},"four":{"question":"How many students does it show?","answer":"The first ten, ranked. The full results stay on the test page for the teacher."},"five":{"question":"What about open answers waiting for review?","answer":"They count for nothing until graded. The display says so and keeps following the test until every answer is graded, so the final podium is right."},"six":{"question":"Is there a leaderboard outside tests?","answer":"Yes, for practice: students see their school’s practice leaderboard by points, all time, this month and most improved."}},"cta":"Bring your next test to the big screen."},"students":{"metaTitle":"Echelio for students: free coding tests and practice","metaDescription":"Echelio is free for students, with or without a school. Practise about 945 code challenges in JavaScript, Java, Python, PHP and SQL, with a daily challenge and streaks, and take your class’s coding tests in the browser.","name":"For students","title":"Free for students. Made to make you better.","statement":"Sign up and practise about 945 code challenges, with points and streaks, on your own or with your class. When your teacher or school adds you to a class, you take your tests in the browser and join your school’s leaderboard. You never pay.","card":"Free tests and practice: challenges, streaks, a leaderboard and quizzes.","points":{"title":"Everything you get, for free.","intro":"Students never pay for Echelio: only the teacher or the school does.","one":{"title":"Tests in the browser","text":"Join with a code, write and run real code in a full editor, and see which cases pass. Nothing to install."},"two":{"title":"Practice at your own pace","text":"About 945 code challenges in JavaScript, Java, Python, PHP and SQL, from easy to hard, in English or French. Practice is never graded."},"three":{"title":"A reason to come back","text":"A daily challenge, a streak, a weekly goal, tiers from Bronze to Diamond and your school’s leaderboard."}},"steps":{"title":"How to get started.","one":{"title":"Create your account","text":"Sign up with your email or your Google account, in English or French. Nothing to install."},"two":{"title":"Start practising","text":"Practice opens right away, with or without a school: today’s challenge, suggestions and every code challenge."},"three":{"title":"Join your class","text":"Open the class link or email invitation your teacher sends. Your tests then appear on your home page, and your practice stays with you."}},"details":{"title":"What’s inside.","intro":"Everything a student account includes.","one":{"term":"Code challenges","text":"About 945 in JavaScript, Java, Python, PHP and SQL, each one in English or French: the language of your account. Filter by language, difficulty, skill and status, and find your attempts on each one."},"two":{"term":"Points","text":"1 for easy, 3 for medium and 5 for hard on the first solve, plus a bonus point for the daily challenge."},"three":{"term":"Streak and weekly goal","text":"Keep your streak with one solve a day, and pick a weekly goal of 1, 3, 5 or 10 problems."},"four":{"term":"Leaderboard and tiers","text":"Climb from Bronze to Diamond and, once you are in a class, rank among your school’s students all time, this month and by most improved."},"five":{"term":"Suggested for you","text":"Challenges one level above where your tests put you, in your weakest skills first. Before your first test, the ones you started, then new ones at your level."},"six":{"term":"Your profile","text":"Your stats, an activity calendar, completed skill sets, and milestone cards to share on LinkedIn or Instagram."}},"faq":{"title":"Questions from students.","intro":"What students ask before their first class.","one":{"question":"Is Echelio free for students?","answer":"Yes, always. Students never pay. Anyone can sign up and practise for free, and a teacher or a school pays for the classes and tests."},"two":{"question":"Do I need a teacher or a school to use Echelio?","answer":"No. You can sign up and practise the code challenges and Echelio’s quizzes on your own, for free. Tests come from a teacher: when one adds you to a class, everything you practised stays on your profile."},"three":{"question":"What can my teacher see from my practice?","answer":"Which problems you solved and when, including before you joined their class. Never your code, your failed attempts or a grade."},"four":{"question":"Does practice count toward my grades?","answer":"No. Practice is never graded and never changes your Progress levels. Only the tests your teacher gives count."},"five":{"question":"Which programming languages can I practise?","answer":"JavaScript, Java, Python, PHP and SQL today, with more languages on the way."},"six":{"question":"Can I practise quizzes too?","answer":"Yes. Quizzes your teachers open for practice and Echelio’s own quizzes, with the answer and its explanation after each question, as many tries as you like."}},"cta":"Create your account and start practising."}},"compare":{"metaTitle":"Echelio vs HackerRank, Moodle CodeRunner and Google Forms","metaDescription":"Echelio next to grading by hand or in Google Forms, Moodle with CodeRunner, and hiring platforms like HackerRank, CodeSignal and Codility: progress by skill, who needs attention, practice for each student, hidden tests, multiple choice and code in one test, French and price, for coding schools.","name":"Compare","title":"Less grading. More progress.","statement":"Echelio grades real code on its own, turns every test into a level per skill for each learner, and gives every student their next exercise. Here is how that compares with grading by hand or in Google Forms, Moodle with CodeRunner, and the hiring platforms.","edge":{"title":"Where Echelio goes further.","intro":"Every result becomes the student’s next exercise and the teacher’s next step, without anyone filling in a grid.","one":{"title":"Students get better on their own","text":"Suggested for you picks practice one difficulty above where their tests put them, weakest skills first. A daily challenge, a streak and a weekly goal keep them coding between tests, with nothing for the teacher to prepare."},"two":{"title":"Every learner, skill by skill","text":"Each code test updates every student’s level per skill, across classes and languages. One page per student holds their levels, tests, practice and quizzes."},"three":{"title":"The next step, already prepared","text":"Progress lists who needs attention and why: a falling score, a missed test, skills with no level yet. One click prepares a follow-up test from problems they haven’t solved."}},"table":{"title":"What a school decides on.","intro":"Facts about the other options come from their own websites, checked on {date}. The links are at the bottom of the page.","caption":"Echelio, grading by hand or in Google Forms, Moodle with CodeRunner, and hiring platforms, compared on what a coding school decides on.","corner":"What you need","verdicts":{"yes":"Yes","partly":"Partly","no":"No","notYet":"Not yet"},"details":"Each row in full","options":{"echelio":{"name":"Echelio","kind":"For coding schools"},"manual":{"name":"By hand or Google Forms","kind":"Forms, Classroom, a spreadsheet"},"moodle":{"name":"Moodle + CodeRunner","kind":"Open-source LMS and plugin"},"hiring":{"name":"HackerRank, CodeSignal, Codility","kind":"Hiring platforms"}},"rows":{"skills":{"label":"Level per skill, built automatically","echelio":"Every code test updates each learner’s level per skill. No grid to fill in.","manual":"Classroom’s learning goals score the work you tag and grade.","moodle":"Competency frameworks, rated by teachers or by activity completion.","hiring":"A report per candidate and per test, for hiring decisions.","detail":{"echelio":"Yes, automatically. Every code test updates each learner’s level per skill, across classes and programming languages, with no grid to fill in by hand.","manual":"Classroom’s learning goals turn the work you tag and grade into a score per goal. The code itself is graded by hand.","moodle":"Possible with competency frameworks: teachers rate each competency, or link it to activity completion.","hiring":"A report per candidate and per test, built for hiring decisions."}},"attention":{"label":"Who needs attention, and why","echelio":"A list of learners with the reason for each, and a follow-up test in one click.","manual":"Classroom analytics flags missed work and grade changes, in paid editions.","moodle":"An at-risk model built on course activity, once enabled and trained.","hiring":"Reports per candidate and per test, made for hiring decisions.","detail":{"echelio":"Yes. Progress lists the learners who need attention, each with the reason: a latest score well below their average, skills with no level yet, a missed test or a week without work. Create test then picks problems they haven’t solved, at the right difficulty.","manual":"In part. Classroom analytics, with Education Plus or the Teaching and Learning Upgrade, highlights students who might need support, such as missed assignments or changes in grades.","moodle":"In part. Moodle’s analytics can predict students at risk of dropping out, from their activity in the course. The model needs course dates and finished courses to learn from.","hiring":"In part. Reports per candidate and per test, built for hiring decisions. CodeSignal also offers universities program-level reporting."}},"practice":{"label":"Practice picked for each student","echelio":"Suggested from their weakest skills, with a daily challenge and streaks. Free.","manual":"What the teacher shares. Classroom practice sets need a paid edition.","moodle":"Practice quizzes the teacher builds, with the attempts they allow.","hiring":"Separate sites for developers, apart from the school’s tests.","detail":{"echelio":"Yes. Suggested for you picks challenges one difficulty above where the student’s tests put them, weakest skills first, from about 945 code challenges. A daily challenge, a streak and a weekly goal bring them back. Free for every student, with or without a school.","manual":"In part. The exercises the teacher shares. Classroom practice sets come with paid editions.","moodle":"In part. Practice quizzes the teacher builds in the course, with as many attempts as they allow.","hiring":"In part. Separate sites for developers: CodeSignal Learn, HackerRank’s practice and Codility’s lessons, apart from the school’s own tests."}},"hiddenTests":{"label":"Real code, graded by hidden tests","echelio":"Public and hidden cases; hidden data never reaches the browser.","manual":"Forms grades choices and short answers. Code is graded by hand.","moodle":"CodeRunner runs each answer against tests, which can be hidden.","hiring":"All three let test cases stay hidden from candidates.","detail":{"echelio":"Yes. Every submission runs against public and hidden cases, and hidden data never reaches the browser.","manual":"No. Forms grades choices and short answers against a key; code is read and graded by hand.","moodle":"Yes. CodeRunner runs each answer against the question’s tests, and its guide recommends at least one hidden case.","hiring":"Yes. All three let test cases stay hidden from candidates."}},"mixedTests":{"label":"Multiple choice and code in one test","echelio":"Code problems and a quiz in two parts, with one score. You set the split.","manual":"One form can hold both, but code is graded by hand.","moodle":"CodeRunner questions sit in a quiz with any other question type.","hiring":"A test can mix coding and multiple-choice questions.","detail":{"echelio":"Yes. A Code and quiz test holds code problems and one of the teacher’s quizzes, in two parts, in the order the teacher picks. Code is graded against public and hidden cases, and the quiz grades itself except open answers, which wait for the teacher’s review. The two parts make one score: the teacher sets how much the code part counts, from 10% to 90% (50% by default). One time window covers both parts, and one setting shows or hides the results.","manual":"In one form, yes, but only choices and short answers grade themselves.","moodle":"Yes. CodeRunner questions sit in a Moodle quiz next to multiple choice, short answer and the other question types.","hiring":"Yes. A test can mix coding and multiple-choice questions."}},"french":{"label":"French interface","echelio":"The whole app, for teachers and students, AI included.","manual":"Google Classroom is available in French.","moodle":"Moodle fully; CodeRunner’s own screens about half.","hiring":"HackerRank offers Canadian French; Codility translates some task text.","detail":{"echelio":"Yes, the whole app, for teachers and students. Each person picks their language, and AI drafts quizzes in French.","manual":"Yes. Google Classroom is available in French.","moodle":"Yes for Moodle, whose French pack is complete. CodeRunner’s own screens are about half translated.","hiring":"In part. HackerRank can show its test screens in Canadian French; Codility translates some task descriptions."}},"price":{"label":"Price model","echelio":"{teacherMonthly} a month per teacher, for one class, after a 14-day free trial. Schools pay per student a year, from {perStudent}. Students never pay.","manual":"No charge in Google Workspace for Education Fundamentals, for qualifying institutions. The cost is teacher time.","moodle":"Free, open-source software. You pay for hosting, and code runs on a Jobe server you install and run yourself.","hiring":"Per candidate. HackerRank and CodeSignal start at $79 a month, billed yearly, for 60 attempts or credits a year; Codility at $1,200 a year for 120 invites."},"audience":{"label":"Built for","echelio":"Coding schools, bootcamps and teachers who test and follow classes.","manual":"Every subject and every school, not code in particular.","moodle":"Schools, universities and companies that run their courses in Moodle.","hiring":"Companies hiring developers. CodeSignal also sells career-readiness programs to academic institutions."}}},"bestFor":{"title":"Which one fits.","intro":"Each option is the right choice for someone. Here is who.","label":"Best for","echelio":"Coding schools and bootcamps that test code every few weeks and want every student to improve between tests: a level per skill for each learner, a list of who needs help, and practice picked for each student. Theory and code can share one test, with one score. Hosted, in English or French, with nothing to install.","manual":"Theory quizzes, a few small classes, or schools already set on Google Workspace. It costs nothing extra and every teacher knows it, but each code answer is read and graded by a teacher, and skills are scored only on the work they tag and grade.","moodle":"Universities and schools that already run Moodle, with someone to host it and a Jobe server, and teachers who write or import their own questions and tests. CodeRunner supports more languages, including C, C++ and Pascal, and has no licence fee.","hiring":"Companies screening job candidates, and career services preparing students for those tests. Large question libraries and strong proctoring, priced per candidate, so every student in every test counts against the plan."},"faq":{"title":"Questions schools ask.","intro":"What schools type when they look for another way to test code.","one":{"question":"What is a good HackerRank alternative for schools?","answer":"Echelio is made for coding schools rather than hiring. A class joins a test with a code, students write real code in the browser, and each submission is graded against hidden test cases. Results become a level per skill for every learner, the price is per teacher or per student a year rather than per candidate, and students practise for free between tests, starting with their weakest skills."},"two":{"question":"Is Echelio an alternative to Moodle CodeRunner?","answer":"Yes, for schools that want auto-graded code tests without running Moodle and a Jobe server. Echelio is hosted, comes with about 945 ready problems, and turns every result into a level per skill and a list of who needs attention, without rating each competency by hand. As in a Moodle quiz, code problems and multiple choice can share one test, here with one score whose split the teacher sets. CodeRunner suits schools that already run Moodle and need languages other than JavaScript, Java, Python, PHP and SQL today."},"three":{"question":"Can Google Forms grade code?","answer":"No. Google Forms grades multiple choice, checkboxes, dropdowns, grids and short answers against an answer key. Code typed into a form is graded by hand. Echelio runs each submission against the problem’s test cases instead, hidden ones included."},"four":{"question":"How does Echelio’s price compare with HackerRank or Codility?","answer":"HackerRank and CodeSignal start at $79 a month, billed yearly, for 60 candidate attempts or credits a year, and Codility’s Starter plan costs $1,200 a year for 120 invites. Echelio’s Teacher plan is {teacherMonthly} a month for one class of up to 30 students, and schools pay per student a year, however many tests they give. Students never pay."},"five":{"question":"Is there a coding test platform in French?","answer":"Yes. Echelio’s whole interface is in French as well as English, for teachers and students, and its AI drafts quizzes in either language. Each person picks their own language, so one class can use both."},"six":{"question":"Can students get better without a teacher?","answer":"Yes. From their test results, Suggested for you picks practice one difficulty above their level, in their weakest skills first. Every submission is checked against public and hidden cases, and a daily challenge, a streak and a weekly goal keep them coding. Teachers see which problems each student solved and when, with nothing to prepare."}},"sources":{"title":"Sources.","intro":"Checked on {date}, on each product’s own website. Prices are in US dollars, before tax. Seen something out of date? <a>Tell us</a>."},"cta":"Try Echelio with one class."},"mock":{"practice":{"streak":"day streak","days":{"mon":"M","tue":"T","wed":"W","thu":"T","fri":"F","sat":"S","sun":"S"},"challenge":"Today’s challenge","challengeTitle":"Reverse each word","bonus":"+1 bonus","points":"points"},"fair":{"title":"Test events","paste":"Paste blocked","tab":"Left the test","back":"Back after {time}","hidden":"Hidden case 3 · data not sent","submitted":"Submitted · 7 of 8 cases"},"leaderboard":{"title":"Leaderboard · This month","you":"You"}}}}