users: separate login and register pages + restyle

This commit is contained in:
Samantaz Fox 2022-10-13 18:26:27 +02:00
parent 542a60e599
commit 42fe574652
No known key found for this signature in database
GPG key ID: F42821059186176E
52 changed files with 648 additions and 455 deletions

View file

@ -9,6 +9,76 @@
* Licensed under AGPLv3 * Licensed under AGPLv3
*/ */
/*
* login/Register pages
*/
.login-container,
.register-container {
width: max-content;
margin: 12vh auto;
text-align: end;
padding: 2em;
border: 1px solid;
}
.login-container label,
.register-container label {
width: max-content !important;
margin-right: 1.5em !important;
}
.login-container .login-submit-button,
.register-container .register-submit-button {
width: max-content;
margin: 1.75em auto 1em auto;
}
.login-container p,
.register-container p {
margin: 0 auto;
text-align: center;
}
.login-container .username-pass,
.register-container .username-pass {
width: max-content;
margin: auto;
padding: 0 2em;
}
.captcha {
margin: 2em 0.5em;
text-align: center;
padding: 1em;
}
/* Background color accent using transparency */
/* TODO: handle themes better, ffs */
.light-theme .captcha { background-color: #0002; }
.dark-theme .captcha { background-color: #fff2; }
@media (prefers-color-scheme: light) { .no-theme .captcha { background-color: #0002; } }
@media (prefers-color-scheme: dark) { .no-theme .captcha { background-color: #fff2; } }
.captcha div {
padding: 0.5em;
}
.captcha img {
width: 10.5em;
height: auto;
}
.captcha label {
width: auto !important;
margin: .4em 0 !important;;
}
.captcha a {
color: #335d7a;
}
/* /*
* User menu * User menu
*/ */

View file

@ -162,11 +162,8 @@
"Show replies": "عرض الردود", "Show replies": "عرض الردود",
"Incorrect password": "كلمة السر غير صحيحة", "Incorrect password": "كلمة السر غير صحيحة",
"Wrong answer": "إجابة خاطئة", "Wrong answer": "إجابة خاطئة",
"Erroneous CAPTCHA": "الكابتشا CAPTCHA غير صاحلة",
"CAPTCHA is a required field": "مكان الكابتشا CAPTCHA مطلوب",
"User ID is a required field": "مكان اسم المستخدم مطلوب", "User ID is a required field": "مكان اسم المستخدم مطلوب",
"Password is a required field": "مكان كلمة السر مطلوب", "Password is a required field": "مكان كلمة السر مطلوب",
"Wrong username or password": "اسم المستخدم او كلمة السر غير صحيح",
"Password cannot be empty": "لا يمكن أن تكون كلمة السر فارغة", "Password cannot be empty": "لا يمكن أن تكون كلمة السر فارغة",
"Password cannot be longer than 55 characters": "يجب أن لا تتعدى كلمة السر 55 حرفًا", "Password cannot be longer than 55 characters": "يجب أن لا تتعدى كلمة السر 55 حرفًا",
"Please log in": "الرجاء تسجيل الدخول", "Please log in": "الرجاء تسجيل الدخول",
@ -185,7 +182,6 @@
"Could not pull trending pages.": "لم يستطع عرض الصفحات الراجئة.", "Could not pull trending pages.": "لم يستطع عرض الصفحات الراجئة.",
"Hidden field \"challenge\" is a required field": "مكان مخفي \"تحدي\" مكان مطلوب", "Hidden field \"challenge\" is a required field": "مكان مخفي \"تحدي\" مكان مطلوب",
"Hidden field \"token\" is a required field": "مكان مخفي \"رمز\" مكان مطلوب", "Hidden field \"token\" is a required field": "مكان مخفي \"رمز\" مكان مطلوب",
"Erroneous challenge": "تحدي غير صالح",
"Erroneous token": "رمز مميز خاطئ", "Erroneous token": "رمز مميز خاطئ",
"No such user": "مستخدم غير صالح", "No such user": "مستخدم غير صالح",
"Token is expired, please try again": "الرمز منتهى الصلاحية، الرجاء المحاولة مرة اخرى", "Token is expired, please try again": "الرمز منتهى الصلاحية، الرجاء المحاولة مرة اخرى",

View file

@ -419,7 +419,6 @@
"Playlist privacy": "Soukromí playlistu", "Playlist privacy": "Soukromí playlistu",
"Wrong answer": "Špatná odpověď", "Wrong answer": "Špatná odpověď",
"Could not pull trending pages.": "Nepodařilo se získat trendy stránky.", "Could not pull trending pages.": "Nepodařilo se získat trendy stránky.",
"Erroneous CAPTCHA": "Chybná CAPTCHA",
"Password is a required field": "Heslo je vyžadované pole", "Password is a required field": "Heslo je vyžadované pole",
"preferences_automatic_instance_redirect_label": "Automatické přesměrování instance (fallback na redirect.invidious.io): ", "preferences_automatic_instance_redirect_label": "Automatické přesměrování instance (fallback na redirect.invidious.io): ",
"Switch Invidious Instance": "Přepnout instanci Invidious", "Switch Invidious Instance": "Přepnout instanci Invidious",
@ -427,7 +426,7 @@
"footer_source_code": "Zdrojový kód", "footer_source_code": "Zdrojový kód",
"View YouTube comments": "Zobrazit YouTube komentáře", "View YouTube comments": "Zobrazit YouTube komentáře",
"Blacklisted regions: ": "Oblasti na černé listině: ", "Blacklisted regions: ": "Oblasti na černé listině: ",
"Wrong username or password": "Nesprávné uživatelské jméno nebo heslo", "error_invalid_username_or_password": "Nesprávné uživatelské jméno nebo heslo",
"Please sign in using 'Log in with Google'": "Přihlaste se prosím pomocí Googlu", "Please sign in using 'Log in with Google'": "Přihlaste se prosím pomocí Googlu",
"Password cannot be empty": "Heslo nemůže být prázné", "Password cannot be empty": "Heslo nemůže být prázné",
"preferences_category_misc": "Různá nastavení", "preferences_category_misc": "Různá nastavení",
@ -457,9 +456,7 @@
"Load more": "Načíst další", "Load more": "Načíst další",
"Not a playlist.": "Není playlist.", "Not a playlist.": "Není playlist.",
"Playlist does not exist.": "Playlist neexistuje.", "Playlist does not exist.": "Playlist neexistuje.",
"Erroneous challenge": "Chybná výzva",
"Premieres `x`": "Premiéra `x`", "Premieres `x`": "Premiéra `x`",
"CAPTCHA is a required field": "CAPTCHA je vyžadované pole",
"`x` ago": "Před `x`", "`x` ago": "Před `x`",
"search_message_change_filters_or_query": "Zkuste rozšířit vyhledávaný dotaz a/nebo změnit filtry.", "search_message_change_filters_or_query": "Zkuste rozšířit vyhledávaný dotaz a/nebo změnit filtry.",
"search_filters_date_option_none": "Jakékoli datum", "search_filters_date_option_none": "Jakékoli datum",

View file

@ -157,11 +157,9 @@
"Show replies": "Vis svar", "Show replies": "Vis svar",
"Incorrect password": "Forkert adgangskode", "Incorrect password": "Forkert adgangskode",
"Wrong answer": "Forkert svar", "Wrong answer": "Forkert svar",
"Erroneous CAPTCHA": "Fejlagtig CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA er et obligatorisk felt",
"User ID is a required field": "Bruger ID er et krævet felt", "User ID is a required field": "Bruger ID er et krævet felt",
"Password is a required field": "Adgangskode er et obligatorisk felt", "Password is a required field": "Adgangskode er et obligatorisk felt",
"Wrong username or password": "Forkert brugernavn eller adgangskode", "error_invalid_username_or_password": "Forkert brugernavn eller adgangskode",
"Please sign in using 'Log in with Google'": "Log ind via 'Log ind med Google'", "Please sign in using 'Log in with Google'": "Log ind via 'Log ind med Google'",
"Password cannot be empty": "Adgangskoden må ikke være tom", "Password cannot be empty": "Adgangskoden må ikke være tom",
"Password cannot be longer than 55 characters": "Adgangskoden må ikke være længere end 55 tegn", "Password cannot be longer than 55 characters": "Adgangskoden må ikke være længere end 55 tegn",
@ -306,7 +304,6 @@
"Marathi": "Marathi", "Marathi": "Marathi",
"Sindhi": "Sindhi", "Sindhi": "Sindhi",
"preferences_category_misc": "Diverse indstillinger", "preferences_category_misc": "Diverse indstillinger",
"Erroneous challenge": "Fejlagtig udfordring",
"Hindi": "Hindi", "Hindi": "Hindi",
"Igbo": "Igbo", "Igbo": "Igbo",
"Javanese": "Javanesisk", "Javanese": "Javanesisk",

View file

@ -162,11 +162,9 @@
"Show replies": "Antworten anzeigen", "Show replies": "Antworten anzeigen",
"Incorrect password": "Falsches Passwort", "Incorrect password": "Falsches Passwort",
"Wrong answer": "Ungültige Antwort", "Wrong answer": "Ungültige Antwort",
"Erroneous CAPTCHA": "Ungültiges CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA ist eine erforderliche Eingabe",
"User ID is a required field": "Benutzer ID ist eine erforderliche Eingabe", "User ID is a required field": "Benutzer ID ist eine erforderliche Eingabe",
"Password is a required field": "Passwort ist eine erforderliche Eingabe", "Password is a required field": "Passwort ist eine erforderliche Eingabe",
"Wrong username or password": "Ungültiger Benutzername oder Passwort", "error_invalid_username_or_password": "Ungültiger Benutzername oder Passwort",
"Password cannot be empty": "Passwort darf nicht leer sein", "Password cannot be empty": "Passwort darf nicht leer sein",
"Password cannot be longer than 55 characters": "Passwort darf nicht länger als 55 Zeichen sein", "Password cannot be longer than 55 characters": "Passwort darf nicht länger als 55 Zeichen sein",
"Please log in": "Bitte anmelden", "Please log in": "Bitte anmelden",
@ -185,7 +183,6 @@
"Could not pull trending pages.": "Trendenz-Seiten konnten nicht geladen werden.", "Could not pull trending pages.": "Trendenz-Seiten konnten nicht geladen werden.",
"Hidden field \"challenge\" is a required field": "Verstecktes Feld „challenge“ ist eine erforderliche Eingabe", "Hidden field \"challenge\" is a required field": "Verstecktes Feld „challenge“ ist eine erforderliche Eingabe",
"Hidden field \"token\" is a required field": "Verstecktes Feld „token“ ist eine erforderliche Eingabe", "Hidden field \"token\" is a required field": "Verstecktes Feld „token“ ist eine erforderliche Eingabe",
"Erroneous challenge": "Ungültiger Test",
"Erroneous token": "Ungültiger Token", "Erroneous token": "Ungültiger Token",
"No such user": "Ungültiger Benutzer", "No such user": "Ungültiger Benutzer",
"Token is expired, please try again": "Token ist abgelaufen, bitte erneut versuchen", "Token is expired, please try again": "Token ist abgelaufen, bitte erneut versuchen",

View file

@ -153,11 +153,9 @@
"Show replies": "Προβολή απαντήσεων", "Show replies": "Προβολή απαντήσεων",
"Incorrect password": "Λανθασμένος κωδικός πρόσβασης", "Incorrect password": "Λανθασμένος κωδικός πρόσβασης",
"Wrong answer": "Λανθασμένη απάντηση", "Wrong answer": "Λανθασμένη απάντηση",
"Erroneous CAPTCHA": "Λανθασμένο CAPTCHA",
"CAPTCHA is a required field": "Το CAPTCHA είναι απαιτούμενο πεδίο",
"User ID is a required field": "Η ταυτότητα χρήστη είναι απαιτούμενο πεδίο", "User ID is a required field": "Η ταυτότητα χρήστη είναι απαιτούμενο πεδίο",
"Password is a required field": "Ο κωδικός πρόσβασης είναι απαιτούμενο πεδίο", "Password is a required field": "Ο κωδικός πρόσβασης είναι απαιτούμενο πεδίο",
"Wrong username or password": "Λανθασμένο όνομα χρήστη ή κωδικός πρόσβασης", "error_invalid_username_or_password": "Λανθασμένο όνομα χρήστη ή κωδικός πρόσβασης",
"Password cannot be empty": "Ο κωδικός πρόσβασης δεν γίνεται να είναι κενός", "Password cannot be empty": "Ο κωδικός πρόσβασης δεν γίνεται να είναι κενός",
"Password cannot be longer than 55 characters": "Ο κωδικός πρόσβασης δεν γίνεται να υπερβαίνει τους 55 χαρακτήρες", "Password cannot be longer than 55 characters": "Ο κωδικός πρόσβασης δεν γίνεται να υπερβαίνει τους 55 χαρακτήρες",
"Please log in": "Συνδεθείτε", "Please log in": "Συνδεθείτε",
@ -176,7 +174,6 @@
"Could not pull trending pages.": "Αδυναμία λήψης σελίδας τάσεων.", "Could not pull trending pages.": "Αδυναμία λήψης σελίδας τάσεων.",
"Hidden field \"challenge\" is a required field": "Το Κρυφό πεδίο \"δοκιμασία\" είναι απαραίτητο", "Hidden field \"challenge\" is a required field": "Το Κρυφό πεδίο \"δοκιμασία\" είναι απαραίτητο",
"Hidden field \"token\" is a required field": "Το κρυφό πεδίο \"αναγνωριστικό διασύνδεσης\" είναι απαραίτητο", "Hidden field \"token\" is a required field": "Το κρυφό πεδίο \"αναγνωριστικό διασύνδεσης\" είναι απαραίτητο",
"Erroneous challenge": "Λανθασμένη δοκιμασία",
"Erroneous token": "Λανθασμένο αναγνωριστικό διασύνδεσης", "Erroneous token": "Λανθασμένο αναγνωριστικό διασύνδεσης",
"No such user": "Μη υπαρκτός χρήστης", "No such user": "Μη υπαρκτός χρήστης",
"Token is expired, please try again": "Το αναγνωριστικό διασύνδεσης έχει λήξει, παρακαλώ ξαναπροσπαθήστε", "Token is expired, please try again": "Το αναγνωριστικό διασύνδεσης έχει λήξει, παρακαλώ ξαναπροσπαθήστε",

View file

@ -44,15 +44,6 @@
"An alternative front-end to YouTube": "An alternative front-end to YouTube", "An alternative front-end to YouTube": "An alternative front-end to YouTube",
"JavaScript license information": "JavaScript license information", "JavaScript license information": "JavaScript license information",
"source": "source", "source": "source",
"Log in": "Log in",
"Log in/register": "Log in/register",
"User ID": "User ID",
"Password": "Password",
"Time (h:mm:ss):": "Time (h:mm:ss):",
"Text CAPTCHA": "Text CAPTCHA",
"Image CAPTCHA": "Image CAPTCHA",
"Sign In": "Sign In",
"Register": "Register",
"E-mail": "E-mail", "E-mail": "E-mail",
"Preferences": "Preferences", "Preferences": "Preferences",
"preferences_category_player": "Player preferences", "preferences_category_player": "Player preferences",
@ -200,11 +191,6 @@
"Show replies": "Show replies", "Show replies": "Show replies",
"Incorrect password": "Incorrect password", "Incorrect password": "Incorrect password",
"Wrong answer": "Wrong answer", "Wrong answer": "Wrong answer",
"Erroneous CAPTCHA": "Erroneous CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA is a required field",
"User ID is a required field": "User ID is a required field",
"Password is a required field": "Password is a required field",
"Wrong username or password": "Wrong username or password",
"Password cannot be empty": "Password cannot be empty", "Password cannot be empty": "Password cannot be empty",
"Password cannot be longer than 55 characters": "Password cannot be longer than 55 characters", "Password cannot be longer than 55 characters": "Password cannot be longer than 55 characters",
"Please log in": "Please log in", "Please log in": "Please log in",
@ -225,9 +211,7 @@
"Not a playlist.": "Not a playlist.", "Not a playlist.": "Not a playlist.",
"Playlist does not exist.": "Playlist does not exist.", "Playlist does not exist.": "Playlist does not exist.",
"Could not pull trending pages.": "Could not pull trending pages.", "Could not pull trending pages.": "Could not pull trending pages.",
"Hidden field \"challenge\" is a required field": "Hidden field \"challenge\" is a required field",
"Hidden field \"token\" is a required field": "Hidden field \"token\" is a required field", "Hidden field \"token\" is a required field": "Hidden field \"token\" is a required field",
"Erroneous challenge": "Erroneous challenge",
"Erroneous token": "Erroneous token", "Erroneous token": "Erroneous token",
"No such user": "No such user", "No such user": "No such user",
"Token is expired, please try again": "Token is expired, please try again", "Token is expired, please try again": "Token is expired, please try again",
@ -464,5 +448,26 @@
"crash_page_read_the_faq": "read the <a href=\"`x`\">Frequently Asked Questions (FAQ)</a>", "crash_page_read_the_faq": "read the <a href=\"`x`\">Frequently Asked Questions (FAQ)</a>",
"crash_page_search_issue": "searched for <a href=\"`x`\">existing issues on GitHub</a>", "crash_page_search_issue": "searched for <a href=\"`x`\">existing issues on GitHub</a>",
"crash_page_report_issue": "If none of the above helped, please <a href=\"`x`\">open a new issue on GitHub</a> (preferably in English) and include the following text in your message (do NOT translate that text):", "crash_page_report_issue": "If none of the above helped, please <a href=\"`x`\">open a new issue on GitHub</a> (preferably in English) and include the following text in your message (do NOT translate that text):",
"error_video_not_in_playlist": "The requested video doesn't exist in this playlist. <a href=\"`x`\">Click here for the playlist home page.</a>" "error_video_not_in_playlist": "The requested video doesn't exist in this playlist. <a href=\"`x`\">Click here for the playlist home page.</a>",
"error_required_field_username": "Username is a required field",
"error_required_field_password": "Password is a required field",
"error_login_disabled": "Login has been disabled by the administrator",
"error_registration_disabled": "Registration has been disabled by the administrator",
"error_invalid_username_or_password": "Invalid username or password",
"error_invalid_captcha": "Invalid CAPTCHA",
"error_passwords_dont_match": "Passwords don't match",
"error_username_already_registered": "Username is already in use. Please try a different one.",
"error_database_unavailable": "Database unavailable, please try again later.<br/>\nIf the problem persist, please contact the instance admin.",
"login_page_title_login": "Sign in",
"login_page_title_register": "Register",
"login_page_login_button": "Sign in",
"login_page_register_button": "Register",
"login_page_username_label": "Username",
"login_page_password_label": "Password",
"login_page_confirm_label": "Confirm password",
"login_page_goto_register_prompt": "Don't have an account yet? <a href=\"`x`\">Register here!</a>",
"login_page_goto_login_prompt": "Already have an account? <a href=\"`x`\">Log in</a>",
"Time (h:mm:ss):": "Time (h:mm:ss):",
"login_page_request_text_captcha": "Text CAPTCHA",
"login_page_request_image_captcha": "Image CAPTCHA"
} }

View file

@ -162,11 +162,9 @@
"Show replies": "Montri respondojn", "Show replies": "Montri respondojn",
"Incorrect password": "Malbona pasvorto", "Incorrect password": "Malbona pasvorto",
"Wrong answer": "Nevalida respondo", "Wrong answer": "Nevalida respondo",
"Erroneous CAPTCHA": "Nevalida CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA estas deviga kampo",
"User ID is a required field": "Uzula identigilo estas deviga kampo", "User ID is a required field": "Uzula identigilo estas deviga kampo",
"Password is a required field": "Pasvorto estas deviga kampo", "Password is a required field": "Pasvorto estas deviga kampo",
"Wrong username or password": "Nevalida uzantnomo aŭ pasvorto", "error_invalid_username_or_password": "Nevalida uzantnomo aŭ pasvorto",
"Please sign in using 'Log in with Google'": "Bonvolu ensaluti per 'Ensaluti per Google'", "Please sign in using 'Log in with Google'": "Bonvolu ensaluti per 'Ensaluti per Google'",
"Password cannot be empty": "Pasvorto ne povas esti malplena", "Password cannot be empty": "Pasvorto ne povas esti malplena",
"Password cannot be longer than 55 characters": "Pasvorto ne povas esti pli longa ol 55 signoj", "Password cannot be longer than 55 characters": "Pasvorto ne povas esti pli longa ol 55 signoj",
@ -186,7 +184,6 @@
"Could not pull trending pages.": "Ne povis venigi tendencajn paĝojn.", "Could not pull trending pages.": "Ne povis venigi tendencajn paĝojn.",
"Hidden field \"challenge\" is a required field": "Kaŝita kampo \"challenge\" estas deviga kampo", "Hidden field \"challenge\" is a required field": "Kaŝita kampo \"challenge\" estas deviga kampo",
"Hidden field \"token\" is a required field": "Kaŝita kampo \"token\" estas deviga kampo", "Hidden field \"token\" is a required field": "Kaŝita kampo \"token\" estas deviga kampo",
"Erroneous challenge": "Nevalida defio",
"Erroneous token": "Nevalida ĵetono", "Erroneous token": "Nevalida ĵetono",
"No such user": "Nevalida uzanto", "No such user": "Nevalida uzanto",
"Token is expired, please try again": "Ĵetono senvalidiĝis, bonvolu provi denove", "Token is expired, please try again": "Ĵetono senvalidiĝis, bonvolu provi denove",

View file

@ -162,11 +162,9 @@
"Show replies": "Mostrar las respuestas", "Show replies": "Mostrar las respuestas",
"Incorrect password": "Contraseña incorrecta", "Incorrect password": "Contraseña incorrecta",
"Wrong answer": "Respuesta no válida", "Wrong answer": "Respuesta no válida",
"Erroneous CAPTCHA": "CAPTCHA no válido",
"CAPTCHA is a required field": "El CAPTCHA es un campo obligatorio",
"User ID is a required field": "El nombre es un campo obligatorio", "User ID is a required field": "El nombre es un campo obligatorio",
"Password is a required field": "La contraseña es un campo obligatorio", "Password is a required field": "La contraseña es un campo obligatorio",
"Wrong username or password": "Nombre o contraseña incorrecto", "error_invalid_username_or_password": "Nombre o contraseña incorrecto",
"Please sign in using 'Log in with Google'": "Inicie sesión con «Iniciar sesión con Google»", "Please sign in using 'Log in with Google'": "Inicie sesión con «Iniciar sesión con Google»",
"Password cannot be empty": "La contraseña no puede estar en blanco", "Password cannot be empty": "La contraseña no puede estar en blanco",
"Password cannot be longer than 55 characters": "La contraseña no puede tener más de 55 caracteres", "Password cannot be longer than 55 characters": "La contraseña no puede tener más de 55 caracteres",
@ -186,7 +184,6 @@
"Could not pull trending pages.": "No se han podido obtener las páginas de tendencias.", "Could not pull trending pages.": "No se han podido obtener las páginas de tendencias.",
"Hidden field \"challenge\" is a required field": "El campo oculto «desafío» es un campo obligatorio", "Hidden field \"challenge\" is a required field": "El campo oculto «desafío» es un campo obligatorio",
"Hidden field \"token\" is a required field": "El campo oculto «símbolo» es un campo obligatorio", "Hidden field \"token\" is a required field": "El campo oculto «símbolo» es un campo obligatorio",
"Erroneous challenge": "Desafío no válido",
"Erroneous token": "Símbolo no válido", "Erroneous token": "Símbolo no válido",
"No such user": "Usuario no existe", "No such user": "Usuario no existe",
"Token is expired, please try again": "El símbolo ha caducado, inténtelo de nuevo", "Token is expired, please try again": "El símbolo ha caducado, inténtelo de nuevo",

View file

@ -119,7 +119,7 @@
"Wrong answer": "Vale vastus", "Wrong answer": "Vale vastus",
"User ID is a required field": "Kasutaja ID on kohustuslik väli", "User ID is a required field": "Kasutaja ID on kohustuslik väli",
"Password is a required field": "Salasõna on kohustuslik väli", "Password is a required field": "Salasõna on kohustuslik väli",
"Wrong username or password": "Vale kasutajanimi või salasõna", "error_invalid_username_or_password": "Vale kasutajanimi või salasõna",
"Please sign in using 'Log in with Google'": "Palun kasutage 'Logi sisse Google'iga'", "Please sign in using 'Log in with Google'": "Palun kasutage 'Logi sisse Google'iga'",
"Password cannot be longer than 55 characters": "Salasõna ei tohi olla pikem kui 55 tähemärki", "Password cannot be longer than 55 characters": "Salasõna ei tohi olla pikem kui 55 tähemärki",
"Password cannot be empty": "Salasõna ei tohi olla tühi", "Password cannot be empty": "Salasõna ei tohi olla tühi",
@ -293,7 +293,6 @@
"Lithuanian": "Leedu", "Lithuanian": "Leedu",
"Videos": "Videod", "Videos": "Videod",
"Community": "Kogukond", "Community": "Kogukond",
"CAPTCHA is a required field": "CAPTCHA on kohustuslik väli",
"comments_points_count": "{{count}} punkt", "comments_points_count": "{{count}} punkt",
"comments_points_count_plural": "{{count}} punkti", "comments_points_count_plural": "{{count}} punkti",
"Chinese": "Hiina", "Chinese": "Hiina",

View file

@ -164,7 +164,7 @@
"Premieres `x`": "'x' estrenaldiak", "Premieres `x`": "'x' estrenaldiak",
"Wrong answer": "Erantzun ez zuzena", "Wrong answer": "Erantzun ez zuzena",
"Password is a required field": "Pasahitza beharrezkoa da", "Password is a required field": "Pasahitza beharrezkoa da",
"Wrong username or password": "Pasahitza edo ezizena gaizki", "error_invalid_username_or_password": "Pasahitza edo ezizena gaizki",
"Password cannot be longer than 55 characters": "Pasahitza 55 karaktere baino luzeagoa ezin da izan", "Password cannot be longer than 55 characters": "Pasahitza 55 karaktere baino luzeagoa ezin da izan",
"This channel does not exist.": "Kanal hau ez dago.", "This channel does not exist.": "Kanal hau ez dago.",
"`x` ago": "duela 'x'", "`x` ago": "duela 'x'",
@ -191,12 +191,10 @@
"Danish": "Daniera", "Danish": "Daniera",
"Dutch": "Alemaniera", "Dutch": "Alemaniera",
"Esperanto": "Esperanto", "Esperanto": "Esperanto",
"Erroneous challenge": "Erronka okerra",
"View all playlists": "Zerrenda guztiak ikusi", "View all playlists": "Zerrenda guztiak ikusi",
"Show annotations": "Oharrak erakutsi", "Show annotations": "Oharrak erakutsi",
"Empty playlist": "Zerrenda hutsik", "Empty playlist": "Zerrenda hutsik",
"Please log in": "Sartu, mesedez", "Please log in": "Sartu, mesedez",
"CAPTCHA is a required field": "CAPTCHA beharrezko eremua da",
"preferences_category_data": "Dataren lehentasunak", "preferences_category_data": "Dataren lehentasunak",
"preferences_default_home_label": "Homepage lehenetsia: ", "preferences_default_home_label": "Homepage lehenetsia: ",
"preferences_automatic_instance_redirect_label": "berbideratze adibide automatikoa (atzera egin berbideratzeko: invidious.io) ", "preferences_automatic_instance_redirect_label": "berbideratze adibide automatikoa (atzera egin berbideratzeko: invidious.io) ",
@ -246,7 +244,6 @@
"revoke": "ukatu", "revoke": "ukatu",
"preferences_continue_label": "Hurrengo lehenetsia jo: ", "preferences_continue_label": "Hurrengo lehenetsia jo: ",
"Whitelisted regions: ": "Zuri zerrendaren zonaldeak: ", "Whitelisted regions: ": "Zuri zerrendaren zonaldeak: ",
"Erroneous CAPTCHA": "CAPTCHA gaizki",
"Deleted or invalid channel": "Ezgai edota ezabatutako kanala", "Deleted or invalid channel": "Ezgai edota ezabatutako kanala",
"Could not create mix.": "Nahastea ezin sortu.", "Could not create mix.": "Nahastea ezin sortu.",
"Not a playlist.": "Ez da zerrenda.", "Not a playlist.": "Ez da zerrenda.",

View file

@ -169,11 +169,9 @@
"Show replies": "نمایش پاسخ ها", "Show replies": "نمایش پاسخ ها",
"Incorrect password": "گذرواژه نا درست", "Incorrect password": "گذرواژه نا درست",
"Wrong answer": "پاسخ غلط", "Wrong answer": "پاسخ غلط",
"Erroneous CAPTCHA": "CAPTCHA نا درست",
"CAPTCHA is a required field": "CAPTCHA یک فیلد ضروری است",
"User ID is a required field": "شناسه کاربری یک فیلد ضروری است", "User ID is a required field": "شناسه کاربری یک فیلد ضروری است",
"Password is a required field": "گذرواژه یک فیلد ضروری است", "Password is a required field": "گذرواژه یک فیلد ضروری است",
"Wrong username or password": "نام کاربری یا گذرواژه غلط است", "error_invalid_username_or_password": "نام کاربری یا گذرواژه غلط است",
"Please sign in using 'Log in with Google'": "لطفا با استفاده از 'ورود توسط گوگل' وارد شوید", "Please sign in using 'Log in with Google'": "لطفا با استفاده از 'ورود توسط گوگل' وارد شوید",
"Password cannot be empty": "گذرواژه نمیتواند خالی باشد", "Password cannot be empty": "گذرواژه نمیتواند خالی باشد",
"Password cannot be longer than 55 characters": "گذر واژه نمیتواند از ۵۵ کاراکتر بیشتر باشد", "Password cannot be longer than 55 characters": "گذر واژه نمیتواند از ۵۵ کاراکتر بیشتر باشد",
@ -195,7 +193,6 @@
"Could not pull trending pages.": "نمیتوان صفحه های پر طرفدار را بکشد.", "Could not pull trending pages.": "نمیتوان صفحه های پر طرفدار را بکشد.",
"Hidden field \"challenge\" is a required field": "فیلد مخفی \"چالش\" یک فیلد ضروری است", "Hidden field \"challenge\" is a required field": "فیلد مخفی \"چالش\" یک فیلد ضروری است",
"Hidden field \"token\" is a required field": "فیلد مخفی \"توکن\" یک فیلد ضروری است", "Hidden field \"token\" is a required field": "فیلد مخفی \"توکن\" یک فیلد ضروری است",
"Erroneous challenge": "چالش غلط",
"Erroneous token": "توکن غلط", "Erroneous token": "توکن غلط",
"No such user": "چنین کاربری وجود ندارد", "No such user": "چنین کاربری وجود ندارد",
"Token is expired, please try again": "توکن ضروری است، لطفا دوباره تلاش کنید", "Token is expired, please try again": "توکن ضروری است، لطفا دوباره تلاش کنید",

View file

@ -161,11 +161,9 @@
"Show replies": "Näytä vastaukset", "Show replies": "Näytä vastaukset",
"Incorrect password": "Väärä salasana", "Incorrect password": "Väärä salasana",
"Wrong answer": "Väärä vastaus", "Wrong answer": "Väärä vastaus",
"Erroneous CAPTCHA": "Virheellinen CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA-kenttä vaaditaan",
"User ID is a required field": "Käyttäjätunnus vaaditaan", "User ID is a required field": "Käyttäjätunnus vaaditaan",
"Password is a required field": "Salasana vaaditaan", "Password is a required field": "Salasana vaaditaan",
"Wrong username or password": "Väärä käyttäjänimi tai salasana", "error_invalid_username_or_password": "Väärä käyttäjänimi tai salasana",
"Password cannot be empty": "Salasana ei voi olla tyhjä", "Password cannot be empty": "Salasana ei voi olla tyhjä",
"Password cannot be longer than 55 characters": "Salasana ei voi olla yli 55 merkkiä pitkä", "Password cannot be longer than 55 characters": "Salasana ei voi olla yli 55 merkkiä pitkä",
"Please log in": "Kirjaudu sisään, ole hyvä", "Please log in": "Kirjaudu sisään, ole hyvä",
@ -184,7 +182,6 @@
"Could not pull trending pages.": "Nousussa olevien sivujen lataus epäonnistui.", "Could not pull trending pages.": "Nousussa olevien sivujen lataus epäonnistui.",
"Hidden field \"challenge\" is a required field": "Piilotettu kenttä \"challenge\" vaaditaan", "Hidden field \"challenge\" is a required field": "Piilotettu kenttä \"challenge\" vaaditaan",
"Hidden field \"token\" is a required field": "Piilotettu kenttä \"tunnus\" vaaditaan", "Hidden field \"token\" is a required field": "Piilotettu kenttä \"tunnus\" vaaditaan",
"Erroneous challenge": "Virheellinen haaste",
"Erroneous token": "Virheellinen tunnus", "Erroneous token": "Virheellinen tunnus",
"No such user": "Käyttäjää ei ole olemassa", "No such user": "Käyttäjää ei ole olemassa",
"Token is expired, please try again": "Tunnus on vanhentunut, yritä uudestaan", "Token is expired, please try again": "Tunnus on vanhentunut, yritä uudestaan",

View file

@ -44,15 +44,6 @@
"An alternative front-end to YouTube": "Un front-end alternatif à YouTube", "An alternative front-end to YouTube": "Un front-end alternatif à YouTube",
"JavaScript license information": "Informations sur les licences JavaScript", "JavaScript license information": "Informations sur les licences JavaScript",
"source": "source", "source": "source",
"Log in": "Se connecter",
"Log in/register": "Se connecter/S'inscrire",
"User ID": "Identifiant utilisateur",
"Password": "Mot de passe",
"Time (h:mm:ss):": "Heure (h:mm:ss) :",
"Text CAPTCHA": "CAPTCHA textuel",
"Image CAPTCHA": "CAPTCHA graphique",
"Sign In": "Se connecter",
"Register": "S'inscrire",
"E-mail": "E-mail", "E-mail": "E-mail",
"Preferences": "Préférences", "Preferences": "Préférences",
"preferences_category_player": "Préférences du lecteur", "preferences_category_player": "Préférences du lecteur",
@ -177,11 +168,9 @@
"Show replies": "Afficher les réponses", "Show replies": "Afficher les réponses",
"Incorrect password": "Mot de passe incorrect", "Incorrect password": "Mot de passe incorrect",
"Wrong answer": "Réponse invalide", "Wrong answer": "Réponse invalide",
"Erroneous CAPTCHA": "CAPTCHA invalide",
"CAPTCHA is a required field": "Veuillez entrer un CAPTCHA",
"User ID is a required field": "Veuillez entrer un Identifiant Utilisateur", "User ID is a required field": "Veuillez entrer un Identifiant Utilisateur",
"Password is a required field": "Veuillez entrer un Mot de passe", "Password is a required field": "Veuillez entrer un Mot de passe",
"Wrong username or password": "Nom d'utilisateur ou mot de passe invalide", "error_invalid_username_or_password": "Nom d'utilisateur ou mot de passe invalide",
"Password cannot be empty": "Le mot de passe ne peut pas être vide", "Password cannot be empty": "Le mot de passe ne peut pas être vide",
"Password cannot be longer than 55 characters": "Le mot de passe ne doit pas comporter plus de 55 caractères", "Password cannot be longer than 55 characters": "Le mot de passe ne doit pas comporter plus de 55 caractères",
"Please log in": "Veuillez vous connecter", "Please log in": "Veuillez vous connecter",
@ -204,7 +193,6 @@
"Could not pull trending pages.": "Impossible de charger les pages de tendances.", "Could not pull trending pages.": "Impossible de charger les pages de tendances.",
"Hidden field \"challenge\" is a required field": "Le champ masqué \"challenge\" est un champ obligatoire", "Hidden field \"challenge\" is a required field": "Le champ masqué \"challenge\" est un champ obligatoire",
"Hidden field \"token\" is a required field": "Le champ caché « token » est requis", "Hidden field \"token\" is a required field": "Le champ caché « token » est requis",
"Erroneous challenge": "Challenge invalide",
"Erroneous token": "Token invalide", "Erroneous token": "Token invalide",
"No such user": "Cet utilisateur n'existe pas", "No such user": "Cet utilisateur n'existe pas",
"Token is expired, please try again": "Le token est expiré, veuillez réessayer", "Token is expired, please try again": "Le token est expiré, veuillez réessayer",
@ -464,5 +452,26 @@
"search_filters_date_label": "Date d'ajout", "search_filters_date_label": "Date d'ajout",
"search_filters_features_option_vr180": "VR180", "search_filters_features_option_vr180": "VR180",
"search_filters_duration_option_none": "Toutes les durées", "search_filters_duration_option_none": "Toutes les durées",
"error_video_not_in_playlist": "La vidéo demandée n'existe pas dans cette liste de lecture. <a href=\"`x`\">Cliquez ici pour retourner à la liste de lecture.</a>" "error_video_not_in_playlist": "La vidéo demandée n'existe pas dans cette liste de lecture. <a href=\"`x`\">Cliquez ici pour retourner à la liste de lecture.</a>",
"error_required_field_username": "Le champ \"nom d'utilisateur\" est requis",
"error_required_field_password": "Le champ \"mot de passe\" est requis",
"error_login_disabled": "L'administrateur a interdit l'utilisation des comptes utilisateur",
"error_registration_disabled": "L'administrateur a interdit la création de comptes utilisateur",
"error_invalid_username_or_password": "Mot de passe ou nom d'utilisateur invalide",
"error_invalid_captcha": "CAPTCHA invalide",
"error_passwords_dont_match": "Les mots de passe ne correspondent pas",
"error_username_already_registered": "Ce nom d'utilisateur n'est pas disponible. Merci d'en utiliser un autre.",
"error_database_unavailable": "Base de données indisponible, merci de réessayer plus tard.<br/>\nSi le problèm persiste, merci de contacter l'administrateur de cette instance.",
"login_page_title_login": "Connexion",
"login_page_title_register": "Créer un compte",
"login_page_login_button": "Connexion",
"login_page_register_button": "Créer un compte",
"login_page_username_label": "Nom d'utilisateur",
"login_page_password_label": "Mot de passe",
"login_page_confirm_label": "Confirmer le mot de passe",
"login_page_goto_register_prompt": "Pas encore de compte? <a href=\"`x`\">S'enregistrer</a>",
"login_page_goto_login_prompt": "Déjà un compte? <a href=\"`x`\">Se connecter</a>",
"Time (h:mm:ss):": "Time (h:mm:ss):",
"login_page_request_text_captcha": "Changer pour un CAPTCHA textuel",
"login_page_request_image_captcha": "Changer pour un CAPTCHA visuel"
} }

View file

@ -130,10 +130,9 @@
"Show replies": "הצגת תגובות", "Show replies": "הצגת תגובות",
"Incorrect password": "סיסמה שגויה", "Incorrect password": "סיסמה שגויה",
"Wrong answer": "תשובה שגויה", "Wrong answer": "תשובה שגויה",
"CAPTCHA is a required field": "שדה CAPTCHA הוא שדה חובה",
"User ID is a required field": "חובה למלא את שדה שם המשתמש", "User ID is a required field": "חובה למלא את שדה שם המשתמש",
"Password is a required field": "חובה למלא את שדה הסיסמה", "Password is a required field": "חובה למלא את שדה הסיסמה",
"Wrong username or password": "שם משתמש שגוי או סיסמה שגויה", "error_invalid_username_or_password": "שם משתמש שגוי או סיסמה שגויה",
"Please sign in using 'Log in with Google'": "נא להתחבר בעזרת \"התחברות עם Google\"", "Please sign in using 'Log in with Google'": "נא להתחבר בעזרת \"התחברות עם Google\"",
"Password cannot be longer than 55 characters": "על אורך הסיסמה להיות 55 תווים לכל היותר", "Password cannot be longer than 55 characters": "על אורך הסיסמה להיות 55 תווים לכל היותר",
"Please log in": "נא להתחבר", "Please log in": "נא להתחבר",

View file

@ -14,7 +14,6 @@
"License: ": "लाइसेंस: ", "License: ": "लाइसेंस: ",
"Wilson score: ": "Wilson स्कोर: ", "Wilson score: ": "Wilson स्कोर: ",
"Wrong answer": "गलत जवाब", "Wrong answer": "गलत जवाब",
"Erroneous CAPTCHA": "गलत CAPTCHA",
"Please log in": "कृपया लॉग-इन करें", "Please log in": "कृपया लॉग-इन करें",
"Bosnian": "बोस्नियाई", "Bosnian": "बोस्नियाई",
"Bulgarian": "बुल्गारियाई", "Bulgarian": "बुल्गारियाई",
@ -221,10 +220,9 @@
"Hide replies": "जवाब छिपाएँ", "Hide replies": "जवाब छिपाएँ",
"Show replies": "जवाब दिखाएँ", "Show replies": "जवाब दिखाएँ",
"Incorrect password": "गलत पासवर्ड", "Incorrect password": "गलत पासवर्ड",
"CAPTCHA is a required field": "CAPTCHA एक ज़रूरी फ़ील्ड है",
"User ID is a required field": "सदस्य ID एक ज़रूरी फ़ील्ड है", "User ID is a required field": "सदस्य ID एक ज़रूरी फ़ील्ड है",
"Password is a required field": "पासवर्ड एक ज़रूरी फ़ील्ड है", "Password is a required field": "पासवर्ड एक ज़रूरी फ़ील्ड है",
"Wrong username or password": "गलत सदस्यनाम या पासवर्ड", "error_invalid_username_or_password": "गलत सदस्यनाम या पासवर्ड",
"Please sign in using 'Log in with Google'": "कृपया 'Google के साथ लॉग-इन करें' के साथ साइन-इन करें", "Please sign in using 'Log in with Google'": "कृपया 'Google के साथ लॉग-इन करें' के साथ साइन-इन करें",
"Password cannot be empty": "पासवर्ड खाली नहीं हो सकता", "Password cannot be empty": "पासवर्ड खाली नहीं हो सकता",
"Password cannot be longer than 55 characters": "पासवर्ड में अधिकतम 55 अक्षर हो सकते हैं", "Password cannot be longer than 55 characters": "पासवर्ड में अधिकतम 55 अक्षर हो सकते हैं",
@ -244,7 +242,6 @@
"Could not pull trending pages.": "रुझान के पृष्ठ प्राप्त न किए जा सके।", "Could not pull trending pages.": "रुझान के पृष्ठ प्राप्त न किए जा सके।",
"Hidden field \"challenge\" is a required field": "छिपाया गया फ़ील्ड \"चुनौती\" एक आवश्यक फ़ील्ड है", "Hidden field \"challenge\" is a required field": "छिपाया गया फ़ील्ड \"चुनौती\" एक आवश्यक फ़ील्ड है",
"Hidden field \"token\" is a required field": "छिपाया गया फ़ील्ड \"टोकन\" एक आवश्यक फ़ील्ड है", "Hidden field \"token\" is a required field": "छिपाया गया फ़ील्ड \"टोकन\" एक आवश्यक फ़ील्ड है",
"Erroneous challenge": "त्रुटिपूर्ण चुनौती",
"Erroneous token": "त्रुटिपूर्ण टोकन", "Erroneous token": "त्रुटिपूर्ण टोकन",
"No such user": "यह सदस्य मौजूद नहीं हैं", "No such user": "यह सदस्य मौजूद नहीं हैं",
"Token is expired, please try again": "टोकन की समय-सीमा समाप्त हो चुकी है, कृपया दोबारा कोशिश करें", "Token is expired, please try again": "टोकन की समय-सीमा समाप्त हो चुकी है, कृपया दोबारा कोशिश करें",

View file

@ -162,11 +162,9 @@
"Show replies": "Prikaži odgovore", "Show replies": "Prikaži odgovore",
"Incorrect password": "Neispravna lozinka", "Incorrect password": "Neispravna lozinka",
"Wrong answer": "Krivi odgovor", "Wrong answer": "Krivi odgovor",
"Erroneous CAPTCHA": "Neispravan CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA je obavezno polje",
"User ID is a required field": "Korisnički ID je obavezno polje", "User ID is a required field": "Korisnički ID je obavezno polje",
"Password is a required field": "Polje lozinke je obavezno polje", "Password is a required field": "Polje lozinke je obavezno polje",
"Wrong username or password": "Krivo korisničko ime ili lozinka", "error_invalid_username_or_password": "Krivo korisničko ime ili lozinka",
"Password cannot be empty": "Polje lozinke ne smije ostati prazno", "Password cannot be empty": "Polje lozinke ne smije ostati prazno",
"Password cannot be longer than 55 characters": "Lozinka ne može biti duža od 55 znakova", "Password cannot be longer than 55 characters": "Lozinka ne može biti duža od 55 znakova",
"Please log in": "Prijavi se", "Please log in": "Prijavi se",
@ -185,7 +183,6 @@
"Could not pull trending pages.": "Neuspjelo preuzimanje stranica u trendu.", "Could not pull trending pages.": "Neuspjelo preuzimanje stranica u trendu.",
"Hidden field \"challenge\" is a required field": "Skriveno polje „izazov” je obavezno polje", "Hidden field \"challenge\" is a required field": "Skriveno polje „izazov” je obavezno polje",
"Hidden field \"token\" is a required field": "Skriveno polje „token” je obavezno polje", "Hidden field \"token\" is a required field": "Skriveno polje „token” je obavezno polje",
"Erroneous challenge": "Neispravan izazov",
"Erroneous token": "Neispravan token", "Erroneous token": "Neispravan token",
"No such user": "Takav korisnik ne postoji", "No such user": "Takav korisnik ne postoji",
"Token is expired, please try again": "Token je istekao, pokušaj ponovo", "Token is expired, please try again": "Token je istekao, pokušaj ponovo",

View file

@ -171,11 +171,9 @@
"Show replies": "Válaszok mutatása", "Show replies": "Válaszok mutatása",
"Incorrect password": "A jelszó nem megfelelő", "Incorrect password": "A jelszó nem megfelelő",
"Wrong answer": "Nem jól válaszoltál.", "Wrong answer": "Nem jól válaszoltál.",
"Erroneous CAPTCHA": "A CAPTCHA hibás.",
"CAPTCHA is a required field": "A CAPTCHA-mezőt ki kell tölteni.",
"User ID is a required field": "A felhasználói azonosítót meg kell adni.", "User ID is a required field": "A felhasználói azonosítót meg kell adni.",
"Password is a required field": "Meg kell adni egy jelszót.", "Password is a required field": "Meg kell adni egy jelszót.",
"Wrong username or password": "Vagy a felhasználói név, vagy pedig a jelszó nem megfelelő.", "error_invalid_username_or_password": "Vagy a felhasználói név, vagy pedig a jelszó nem megfelelő.",
"Password cannot be empty": "A jelszót nem lehet kihagyni.", "Password cannot be empty": "A jelszót nem lehet kihagyni.",
"Password cannot be longer than 55 characters": "A jelszó nem lehet hosszabb 55 karakternél.", "Password cannot be longer than 55 characters": "A jelszó nem lehet hosszabb 55 karakternél.",
"Please log in": "Kérjük, jelentkezz be.", "Please log in": "Kérjük, jelentkezz be.",
@ -198,7 +196,6 @@
"Could not pull trending pages.": "Nem lehetett betölteni a felkapott videók oldalát.", "Could not pull trending pages.": "Nem lehetett betölteni a felkapott videók oldalát.",
"Hidden field \"challenge\" is a required field": "A rejtett „challenge” mezőt ki kell tölteni.", "Hidden field \"challenge\" is a required field": "A rejtett „challenge” mezőt ki kell tölteni.",
"Hidden field \"token\" is a required field": "A rejtett „token” mezőt ki kell tölteni.", "Hidden field \"token\" is a required field": "A rejtett „token” mezőt ki kell tölteni.",
"Erroneous challenge": "Hibás challenge",
"Erroneous token": "Hibás token", "Erroneous token": "Hibás token",
"No such user": "Nincs ilyen felhasználó", "No such user": "Nincs ilyen felhasználó",
"Token is expired, please try again": "A token lejárt. Kérjük, próbáld meg újból.", "Token is expired, please try again": "A token lejárt. Kérjük, próbáld meg újból.",

View file

@ -169,11 +169,9 @@
"Show replies": "Lihat balasan", "Show replies": "Lihat balasan",
"Incorrect password": "Kata sandi salah", "Incorrect password": "Kata sandi salah",
"Wrong answer": "Jawaban salah", "Wrong answer": "Jawaban salah",
"Erroneous CAPTCHA": "CAPTCHA salah",
"CAPTCHA is a required field": "CAPTCHA perlu diisi",
"User ID is a required field": "ID pengguna perlu diisi", "User ID is a required field": "ID pengguna perlu diisi",
"Password is a required field": "Kata sandi perlu diisi", "Password is a required field": "Kata sandi perlu diisi",
"Wrong username or password": "Nama pengguna atau kata sandi salah", "error_invalid_username_or_password": "Nama pengguna atau kata sandi salah",
"Password cannot be empty": "Kata sandi tidak boleh kosong", "Password cannot be empty": "Kata sandi tidak boleh kosong",
"Password cannot be longer than 55 characters": "Kata sandi tidak boleh lebih dari 55 karakter", "Password cannot be longer than 55 characters": "Kata sandi tidak boleh lebih dari 55 karakter",
"Please log in": "Harap masuk", "Please log in": "Harap masuk",
@ -194,7 +192,6 @@
"Could not pull trending pages.": "Tidak bisa mendapatkan laman tren.", "Could not pull trending pages.": "Tidak bisa mendapatkan laman tren.",
"Hidden field \"challenge\" is a required field": "Bidang \"tantangan\" tersembunyi wajib diisi", "Hidden field \"challenge\" is a required field": "Bidang \"tantangan\" tersembunyi wajib diisi",
"Hidden field \"token\" is a required field": "Bidang \"token\" tersembunyi wajib diisi", "Hidden field \"token\" is a required field": "Bidang \"token\" tersembunyi wajib diisi",
"Erroneous challenge": "Tantangan salah",
"Erroneous token": "Token salah", "Erroneous token": "Token salah",
"No such user": "Tidak ada pengguna demikian", "No such user": "Tidak ada pengguna demikian",
"Token is expired, please try again": "Token kadaluwarsa, harap coba lagi", "Token is expired, please try again": "Token kadaluwarsa, harap coba lagi",

View file

@ -153,11 +153,9 @@
"Show replies": "Sýna svör", "Show replies": "Sýna svör",
"Incorrect password": "Rangt lykilorð", "Incorrect password": "Rangt lykilorð",
"Wrong answer": "Rangt svar", "Wrong answer": "Rangt svar",
"Erroneous CAPTCHA": "Rangt CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA er nauðsynlegur reitur",
"User ID is a required field": "Notandakenni er nauðsynlegur reitur", "User ID is a required field": "Notandakenni er nauðsynlegur reitur",
"Password is a required field": "Lykilorð er nauðsynlegur reitur", "Password is a required field": "Lykilorð er nauðsynlegur reitur",
"Wrong username or password": "Rangt notandanafn eða lykilorð", "error_invalid_username_or_password": "Rangt notandanafn eða lykilorð",
"Password cannot be empty": "Lykilorð má ekki vera autt", "Password cannot be empty": "Lykilorð má ekki vera autt",
"Password cannot be longer than 55 characters": "Lykilorð má ekki vera lengra en 55 stafir", "Password cannot be longer than 55 characters": "Lykilorð má ekki vera lengra en 55 stafir",
"Please log in": "Vinsamlegast skráðu þig inn", "Please log in": "Vinsamlegast skráðu þig inn",
@ -176,7 +174,6 @@
"Could not pull trending pages.": "Ekki tókst að draga vinsælar síður.", "Could not pull trending pages.": "Ekki tókst að draga vinsælar síður.",
"Hidden field \"challenge\" is a required field": "Falinn reitur \"áskorun\" er nauðsynlegur reitur", "Hidden field \"challenge\" is a required field": "Falinn reitur \"áskorun\" er nauðsynlegur reitur",
"Hidden field \"token\" is a required field": "Falinn reitur \"tákn\" er nauðsynlegur reitur", "Hidden field \"token\" is a required field": "Falinn reitur \"tákn\" er nauðsynlegur reitur",
"Erroneous challenge": "Röng áskorun",
"Erroneous token": "Rangt tákn", "Erroneous token": "Rangt tákn",
"No such user": "Enginn slíkur notandi", "No such user": "Enginn slíkur notandi",
"Token is expired, please try again": "Tákn er útrunnið, vinsamlegast reyndu aftur", "Token is expired, please try again": "Tákn er útrunnið, vinsamlegast reyndu aftur",

View file

@ -167,11 +167,9 @@
"Show replies": "Mostra le risposte", "Show replies": "Mostra le risposte",
"Incorrect password": "Password sbagliata", "Incorrect password": "Password sbagliata",
"Wrong answer": "Risposta errata", "Wrong answer": "Risposta errata",
"Erroneous CAPTCHA": "CAPTCHA errato",
"CAPTCHA is a required field": "Il CAPTCHA è un campo obbligatorio",
"User ID is a required field": "L'ID utente è obbligatorio", "User ID is a required field": "L'ID utente è obbligatorio",
"Password is a required field": "La password è un campo obbligatorio", "Password is a required field": "La password è un campo obbligatorio",
"Wrong username or password": "Nome utente o password errati", "error_invalid_username_or_password": "Nome utente o password errati",
"Password cannot be empty": "La password non può essere vuota", "Password cannot be empty": "La password non può essere vuota",
"Password cannot be longer than 55 characters": "La password non può contenere più di 55 caratteri", "Password cannot be longer than 55 characters": "La password non può contenere più di 55 caratteri",
"Please log in": "Per favore, accedi", "Please log in": "Per favore, accedi",
@ -190,7 +188,6 @@
"Could not pull trending pages.": "Impossibile recuperare le tendenze.", "Could not pull trending pages.": "Impossibile recuperare le tendenze.",
"Hidden field \"challenge\" is a required field": "Il campo nascosto \"challenge\" è obbligatorio", "Hidden field \"challenge\" is a required field": "Il campo nascosto \"challenge\" è obbligatorio",
"Hidden field \"token\" is a required field": "Il campo nascosto «token» è obbligatorio", "Hidden field \"token\" is a required field": "Il campo nascosto «token» è obbligatorio",
"Erroneous challenge": "Campo «challenge» non valido",
"Erroneous token": "Campo \"token\" non valido", "Erroneous token": "Campo \"token\" non valido",
"No such user": "Utente non valido", "No such user": "Utente non valido",
"Token is expired, please try again": "Gettone scaduto, riprova", "Token is expired, please try again": "Gettone scaduto, riprova",

View file

@ -169,11 +169,9 @@
"Show replies": "返信を表示", "Show replies": "返信を表示",
"Incorrect password": "パスワードが間違っています", "Incorrect password": "パスワードが間違っています",
"Wrong answer": "回答が間違っています", "Wrong answer": "回答が間違っています",
"Erroneous CAPTCHA": "CAPTCHA が間違っています",
"CAPTCHA is a required field": "CAPTCHA は必須項目です",
"User ID is a required field": "ユーザー ID は必須項目です", "User ID is a required field": "ユーザー ID は必須項目です",
"Password is a required field": "パスワードは必須項目です", "Password is a required field": "パスワードは必須項目です",
"Wrong username or password": "ユーザー名またはパスワードが間違っています", "error_invalid_username_or_password": "ユーザー名またはパスワードが間違っています",
"Password cannot be empty": "パスワードを空にすることはできません", "Password cannot be empty": "パスワードを空にすることはできません",
"Password cannot be longer than 55 characters": "パスワードは55文字より長くできません", "Password cannot be longer than 55 characters": "パスワードは55文字より長くできません",
"Please log in": "ログインをしてください", "Please log in": "ログインをしてください",
@ -194,7 +192,6 @@
"Could not pull trending pages.": "急上昇ページを取得できませんでした。", "Could not pull trending pages.": "急上昇ページを取得できませんでした。",
"Hidden field \"challenge\" is a required field": "非表示項目 \"challenge\" は必須項目です", "Hidden field \"challenge\" is a required field": "非表示項目 \"challenge\" は必須項目です",
"Hidden field \"token\" is a required field": "非表示項目 \"token\" は必須項目です", "Hidden field \"token\" is a required field": "非表示項目 \"token\" は必須項目です",
"Erroneous challenge": "チャレンジが間違っています",
"Erroneous token": "トークンが間違っています", "Erroneous token": "トークンが間違っています",
"No such user": "ユーザーが存在しません", "No such user": "ユーザーが存在しません",
"Token is expired, please try again": "トークンが期限切れです。再度試してください", "Token is expired, please try again": "トークンが期限切れです。再度試してください",

View file

@ -234,7 +234,6 @@
"Hausa": "하우사어", "Hausa": "하우사어",
"No such user": "해당 사용자 없음", "No such user": "해당 사용자 없음",
"Erroneous token": "잘못된 token", "Erroneous token": "잘못된 token",
"Erroneous challenge": "잘못된 challenge",
"Hidden field \"token\" is a required field": "숨겨진 필드 \"token\"은 필수 필드입니다", "Hidden field \"token\" is a required field": "숨겨진 필드 \"token\"은 필수 필드입니다",
"Hidden field \"challenge\" is a required field": "숨겨진 필드 \"challenge\"는 필수 필드입니다", "Hidden field \"challenge\" is a required field": "숨겨진 필드 \"challenge\"는 필수 필드입니다",
"Could not pull trending pages.": "인기 급상승 페이지를 가져올 수 없습니다.", "Could not pull trending pages.": "인기 급상승 페이지를 가져올 수 없습니다.",
@ -276,11 +275,9 @@
"Please log in": "로그인하세요", "Please log in": "로그인하세요",
"Password cannot be longer than 55 characters": "비밀번호는 55자 이하여야 합니다", "Password cannot be longer than 55 characters": "비밀번호는 55자 이하여야 합니다",
"Password cannot be empty": "비밀번호는 비워둘 수 없습니다", "Password cannot be empty": "비밀번호는 비워둘 수 없습니다",
"Wrong username or password": "잘못된 사용자 이름 또는 비밀번호", "error_invalid_username_or_password": "잘못된 사용자 이름 또는 비밀번호",
"Password is a required field": "비밀번호는 필수 필드입니다", "Password is a required field": "비밀번호는 필수 필드입니다",
"User ID is a required field": "사용자 ID는 필수 필드입니다", "User ID is a required field": "사용자 ID는 필수 필드입니다",
"CAPTCHA is a required field": "CAPTCHA는 필수 필드입니다",
"Erroneous CAPTCHA": "잘못된 CAPTCHA",
"Blacklisted regions: ": "차단된 지역: ", "Blacklisted regions: ": "차단된 지역: ",
"Playlists": "재생목록", "Playlists": "재생목록",
"View as playlist": "재생목록으로 보기", "View as playlist": "재생목록으로 보기",

View file

@ -162,11 +162,9 @@
"Show replies": "Rodyti atsakymus", "Show replies": "Rodyti atsakymus",
"Incorrect password": "Slaptažodis neteisingas", "Incorrect password": "Slaptažodis neteisingas",
"Wrong answer": "Atsakymas neteisingas", "Wrong answer": "Atsakymas neteisingas",
"Erroneous CAPTCHA": "Klaidinga CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA yra reikalinga šiam laukeliui",
"User ID is a required field": "Vartotojo ID yra reikalingas šiam laukeliui", "User ID is a required field": "Vartotojo ID yra reikalingas šiam laukeliui",
"Password is a required field": "Slaptažodis yra reikalingas šiam laukeliui", "Password is a required field": "Slaptažodis yra reikalingas šiam laukeliui",
"Wrong username or password": "Neteisingas vartotojo vardas arba slaptažodis", "error_invalid_username_or_password": "Neteisingas vartotojo vardas arba slaptažodis",
"Password cannot be empty": "Slaptažodžio laukelis negali būti tuščias", "Password cannot be empty": "Slaptažodžio laukelis negali būti tuščias",
"Password cannot be longer than 55 characters": "Slaptažodis negali būti ilgesnis nei 55 simboliai", "Password cannot be longer than 55 characters": "Slaptažodis negali būti ilgesnis nei 55 simboliai",
"Please log in": "Prašome prisijungti", "Please log in": "Prašome prisijungti",
@ -185,7 +183,6 @@
"Could not pull trending pages.": "Nepavyko ištraukti tendencijų puslapių.", "Could not pull trending pages.": "Nepavyko ištraukti tendencijų puslapių.",
"Hidden field \"challenge\" is a required field": "Paslėptas laukas „iššūkis“ yra privalomas laukas", "Hidden field \"challenge\" is a required field": "Paslėptas laukas „iššūkis“ yra privalomas laukas",
"Hidden field \"token\" is a required field": "Paslėptas laukas „žetonas“ yra privalomas laukas", "Hidden field \"token\" is a required field": "Paslėptas laukas „žetonas“ yra privalomas laukas",
"Erroneous challenge": "Klaidingas iššūkis",
"Erroneous token": "Klaidingas žetonas", "Erroneous token": "Klaidingas žetonas",
"No such user": "Nėra tokio vartotojo", "No such user": "Nėra tokio vartotojo",
"Token is expired, please try again": "Žetonas pasibaigęs, prašome bandyti dar kartą", "Token is expired, please try again": "Žetonas pasibaigęs, prašome bandyti dar kartą",

View file

@ -162,11 +162,9 @@
"Show replies": "Vis svar", "Show replies": "Vis svar",
"Incorrect password": "Feil passord", "Incorrect password": "Feil passord",
"Wrong answer": "Ugyldig svar", "Wrong answer": "Ugyldig svar",
"Erroneous CAPTCHA": "Ugyldig CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA er et påkrevd felt",
"User ID is a required field": "Bruker-ID er et påkrevd felt", "User ID is a required field": "Bruker-ID er et påkrevd felt",
"Password is a required field": "Passord er et påkrevd felt", "Password is a required field": "Passord er et påkrevd felt",
"Wrong username or password": "Ugyldig brukernavn eller passord", "error_invalid_username_or_password": "Ugyldig brukernavn eller passord",
"Password cannot be empty": "Passordet kan ikke være tomt", "Password cannot be empty": "Passordet kan ikke være tomt",
"Password cannot be longer than 55 characters": "Passordet kan ikke være lengre enn 55 tegn", "Password cannot be longer than 55 characters": "Passordet kan ikke være lengre enn 55 tegn",
"Please log in": "Logg inn", "Please log in": "Logg inn",
@ -185,7 +183,6 @@
"Could not pull trending pages.": "Kunne ikke hente trendsettende sider.", "Could not pull trending pages.": "Kunne ikke hente trendsettende sider.",
"Hidden field \"challenge\" is a required field": "Skjult felt \"utfordring\" er et påkrevd felt", "Hidden field \"challenge\" is a required field": "Skjult felt \"utfordring\" er et påkrevd felt",
"Hidden field \"token\" is a required field": "Skjult felt \"symbol\" er et påkrevd felt", "Hidden field \"token\" is a required field": "Skjult felt \"symbol\" er et påkrevd felt",
"Erroneous challenge": "Ugyldig utfordring",
"Erroneous token": "Ugyldig symbol", "Erroneous token": "Ugyldig symbol",
"No such user": "Ugyldig bruker", "No such user": "Ugyldig bruker",
"Token is expired, please try again": "Symbol utløpt, prøv igjen", "Token is expired, please try again": "Symbol utløpt, prøv igjen",

View file

@ -157,11 +157,9 @@
"Show replies": "Antwoorden tonen", "Show replies": "Antwoorden tonen",
"Incorrect password": "Wachtwoord is onjuist", "Incorrect password": "Wachtwoord is onjuist",
"Wrong answer": "Onjuist antwoord", "Wrong answer": "Onjuist antwoord",
"Erroneous CAPTCHA": "Onjuiste CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA is vereist",
"User ID is a required field": "Gebruikers-id is vereist", "User ID is a required field": "Gebruikers-id is vereist",
"Password is a required field": "Wachtwoord is vereist", "Password is a required field": "Wachtwoord is vereist",
"Wrong username or password": "Onjuiste gebruikersnaam of wachtwoord", "error_invalid_username_or_password": "Onjuiste gebruikersnaam of wachtwoord",
"Please sign in using 'Log in with Google'": "Log in via 'Inloggen met Google'", "Please sign in using 'Log in with Google'": "Log in via 'Inloggen met Google'",
"Password cannot be empty": "Het wachtwoordveld mag niet leeg zijn", "Password cannot be empty": "Het wachtwoordveld mag niet leeg zijn",
"Password cannot be longer than 55 characters": "Het wachtwoord mag niet langer dan 55 tekens zijn", "Password cannot be longer than 55 characters": "Het wachtwoord mag niet langer dan 55 tekens zijn",
@ -181,7 +179,6 @@
"Could not pull trending pages.": "Kan uitgelichte pagina's niet ophalen.", "Could not pull trending pages.": "Kan uitgelichte pagina's niet ophalen.",
"Hidden field \"challenge\" is a required field": "Verborgen veld \"uitdaging\" is vereist", "Hidden field \"challenge\" is a required field": "Verborgen veld \"uitdaging\" is vereist",
"Hidden field \"token\" is a required field": "Verborgen veld \"toegangssleutel\" is vereist", "Hidden field \"token\" is a required field": "Verborgen veld \"toegangssleutel\" is vereist",
"Erroneous challenge": "Ongeldige uitdaging",
"Erroneous token": "Ongeldige toegangssleutel", "Erroneous token": "Ongeldige toegangssleutel",
"No such user": "Gebruiker bestaat niet", "No such user": "Gebruiker bestaat niet",
"Token is expired, please try again": "Toegangssleutel verlopen; probeer het opnieuw", "Token is expired, please try again": "Toegangssleutel verlopen; probeer het opnieuw",

View file

@ -161,11 +161,9 @@
"Show replies": "Pokaż odpowiedzi", "Show replies": "Pokaż odpowiedzi",
"Incorrect password": "Niepoprawne hasło", "Incorrect password": "Niepoprawne hasło",
"Wrong answer": "Niepoprawna odpowiedź", "Wrong answer": "Niepoprawna odpowiedź",
"Erroneous CAPTCHA": "CAPTCHA wykonane błędnie",
"CAPTCHA is a required field": "CAPTCHA jest polem wymaganym",
"User ID is a required field": "ID użytkownika jest polem wymaganym", "User ID is a required field": "ID użytkownika jest polem wymaganym",
"Password is a required field": "Hasło jest polem wymaganym", "Password is a required field": "Hasło jest polem wymaganym",
"Wrong username or password": "Niepoprawny login lub hasło", "error_invalid_username_or_password": "Niepoprawny login lub hasło",
"Please sign in using 'Log in with Google'": "Zaloguj się używając \"Zaloguj się przez Google\"", "Please sign in using 'Log in with Google'": "Zaloguj się używając \"Zaloguj się przez Google\"",
"Password cannot be empty": "Hasło nie może być puste", "Password cannot be empty": "Hasło nie może być puste",
"Password cannot be longer than 55 characters": "Hasło nie może być dłuższe niż 55 znaków", "Password cannot be longer than 55 characters": "Hasło nie może być dłuższe niż 55 znaków",
@ -185,7 +183,6 @@
"Could not pull trending pages.": "Nie udało się pobrać strony na czasie.", "Could not pull trending pages.": "Nie udało się pobrać strony na czasie.",
"Hidden field \"challenge\" is a required field": "Ukryte pole \"wyzwanie\" jest polem wymaganym", "Hidden field \"challenge\" is a required field": "Ukryte pole \"wyzwanie\" jest polem wymaganym",
"Hidden field \"token\" is a required field": "Ukryte pole \"token\" jest polem wymaganym", "Hidden field \"token\" is a required field": "Ukryte pole \"token\" jest polem wymaganym",
"Erroneous challenge": "Niepoprawne wyzwanie",
"Erroneous token": "Niepoprawny token", "Erroneous token": "Niepoprawny token",
"No such user": "Niepoprawny użytkownik", "No such user": "Niepoprawny użytkownik",
"Token is expired, please try again": "Token wygasł, spróbuj ponownie", "Token is expired, please try again": "Token wygasł, spróbuj ponownie",

View file

@ -164,11 +164,9 @@
"Show replies": "Mostrar respostas", "Show replies": "Mostrar respostas",
"Incorrect password": "Senha incorreta", "Incorrect password": "Senha incorreta",
"Wrong answer": "Resposta incorreta", "Wrong answer": "Resposta incorreta",
"Erroneous CAPTCHA": "CAPTCHA inválido",
"CAPTCHA is a required field": "O CAPTCHA é um campo obrigatório",
"User ID is a required field": "O nome de usuário é um campo obrigatório", "User ID is a required field": "O nome de usuário é um campo obrigatório",
"Password is a required field": "A senha é um campo obrigatório", "Password is a required field": "A senha é um campo obrigatório",
"Wrong username or password": "Nome de usuário ou senha inválidos", "error_invalid_username_or_password": "Nome de usuário ou senha inválidos",
"Please sign in using 'Log in with Google'": "Por favor, entre usando 'Entrar com conta Google'", "Please sign in using 'Log in with Google'": "Por favor, entre usando 'Entrar com conta Google'",
"Password cannot be empty": "A senha não pode ficar em branco", "Password cannot be empty": "A senha não pode ficar em branco",
"Password cannot be longer than 55 characters": "A senha não pode ter mais que 55 caracteres", "Password cannot be longer than 55 characters": "A senha não pode ter mais que 55 caracteres",
@ -188,7 +186,6 @@
"Could not pull trending pages.": "Não foi possível obter as páginas dos vídeos em alta.", "Could not pull trending pages.": "Não foi possível obter as páginas dos vídeos em alta.",
"Hidden field \"challenge\" is a required field": "O campo oculto \"desafio\" é obrigatório", "Hidden field \"challenge\" is a required field": "O campo oculto \"desafio\" é obrigatório",
"Hidden field \"token\" is a required field": "O campo oculto \"token\" é obrigatório", "Hidden field \"token\" is a required field": "O campo oculto \"token\" é obrigatório",
"Erroneous challenge": "Desafio inválido",
"Erroneous token": "Token inválido", "Erroneous token": "Token inválido",
"No such user": "Usuário inválido", "No such user": "Usuário inválido",
"Token is expired, please try again": "Token expirou, tente novamente", "Token is expired, please try again": "Token expirou, tente novamente",

View file

@ -164,11 +164,9 @@
"Show replies": "Mostrar respostas", "Show replies": "Mostrar respostas",
"Incorrect password": "Palavra-chave incorreta", "Incorrect password": "Palavra-chave incorreta",
"Wrong answer": "Resposta errada", "Wrong answer": "Resposta errada",
"Erroneous CAPTCHA": "CAPTCHA inválido",
"CAPTCHA is a required field": "CAPTCHA é um campo obrigatório",
"User ID is a required field": "O nome de utilizador é um campo obrigatório", "User ID is a required field": "O nome de utilizador é um campo obrigatório",
"Password is a required field": "Palavra-chave é um campo obrigatório", "Password is a required field": "Palavra-chave é um campo obrigatório",
"Wrong username or password": "Nome de utilizador ou palavra-chave incorreto", "error_invalid_username_or_password": "Nome de utilizador ou palavra-chave incorreto",
"Please sign in using 'Log in with Google'": "Por favor, inicie sessão usando 'Iniciar sessão com o Google'", "Please sign in using 'Log in with Google'": "Por favor, inicie sessão usando 'Iniciar sessão com o Google'",
"Password cannot be empty": "A palavra-chave não pode estar vazia", "Password cannot be empty": "A palavra-chave não pode estar vazia",
"Password cannot be longer than 55 characters": "A palavra-chave não pode ser superior a 55 caracteres", "Password cannot be longer than 55 characters": "A palavra-chave não pode ser superior a 55 caracteres",
@ -188,7 +186,6 @@
"Could not pull trending pages.": "Não foi possível obter as páginas de tendências.", "Could not pull trending pages.": "Não foi possível obter as páginas de tendências.",
"Hidden field \"challenge\" is a required field": "O campo oculto \"desafio\" é obrigatório", "Hidden field \"challenge\" is a required field": "O campo oculto \"desafio\" é obrigatório",
"Hidden field \"token\" is a required field": "O campo oculto \"token\" é um campo obrigatório", "Hidden field \"token\" is a required field": "O campo oculto \"token\" é um campo obrigatório",
"Erroneous challenge": "Desafio inválido",
"Erroneous token": "Token inválido", "Erroneous token": "Token inválido",
"No such user": "Utilizador inválido", "No such user": "Utilizador inválido",
"Token is expired, please try again": "Token expirou, tente novamente", "Token is expired, please try again": "Token expirou, tente novamente",

View file

@ -106,7 +106,6 @@
"Token is expired, please try again": "Token expirou, tente novamente", "Token is expired, please try again": "Token expirou, tente novamente",
"No such user": "Utilizador inválido", "No such user": "Utilizador inválido",
"Erroneous token": "Token inválido", "Erroneous token": "Token inválido",
"Erroneous challenge": "Desafio inválido",
"Hidden field \"token\" is a required field": "O campo oculto \"token\" é um campo obrigatório", "Hidden field \"token\" is a required field": "O campo oculto \"token\" é um campo obrigatório",
"Hidden field \"challenge\" is a required field": "O campo oculto \"desafio\" é obrigatório", "Hidden field \"challenge\" is a required field": "O campo oculto \"desafio\" é obrigatório",
"Playlist does not exist.": "A lista de reprodução não existe.", "Playlist does not exist.": "A lista de reprodução não existe.",
@ -123,11 +122,9 @@
"Password cannot be longer than 55 characters": "A palavra-chave não pode ser superior a 55 caracteres", "Password cannot be longer than 55 characters": "A palavra-chave não pode ser superior a 55 caracteres",
"Password cannot be empty": "A palavra-chave não pode estar vazia", "Password cannot be empty": "A palavra-chave não pode estar vazia",
"Please sign in using 'Log in with Google'": "Por favor, inicie sessão usando 'Iniciar sessão com o Google'", "Please sign in using 'Log in with Google'": "Por favor, inicie sessão usando 'Iniciar sessão com o Google'",
"Wrong username or password": "Nome de utilizador ou palavra-chave incorreto", "error_invalid_username_or_password": "Nome de utilizador ou palavra-chave incorreto",
"Password is a required field": "Palavra-chave é um campo obrigatório", "Password is a required field": "Palavra-chave é um campo obrigatório",
"User ID is a required field": "O nome de utilizador é um campo obrigatório", "User ID is a required field": "O nome de utilizador é um campo obrigatório",
"CAPTCHA is a required field": "CAPTCHA é um campo obrigatório",
"Erroneous CAPTCHA": "CAPTCHA inválido",
"Wrong answer": "Resposta errada", "Wrong answer": "Resposta errada",
"Incorrect password": "Palavra-chave incorreta", "Incorrect password": "Palavra-chave incorreta",
"Show replies": "Mostrar respostas", "Show replies": "Mostrar respostas",

View file

@ -153,11 +153,9 @@
"Show replies": "Afișați replicile", "Show replies": "Afișați replicile",
"Incorrect password": "Parolă incorectă", "Incorrect password": "Parolă incorectă",
"Wrong answer": "Răspuns invalid", "Wrong answer": "Răspuns invalid",
"Erroneous CAPTCHA": "CAPTCHA invalid",
"CAPTCHA is a required field": "Câmpul CAPTCHA este obligatoriu",
"User ID is a required field": "Câmpul ID Utilizator este obligatoriu", "User ID is a required field": "Câmpul ID Utilizator este obligatoriu",
"Password is a required field": "Câmpul Parolă este obligatoriu", "Password is a required field": "Câmpul Parolă este obligatoriu",
"Wrong username or password": "Nume de utilizator sau parolă invalidă", "error_invalid_username_or_password": "Nume de utilizator sau parolă invalidă",
"Please sign in using 'Log in with Google'": "Vă rog conectați-vă folosind \"Conectați-vă cu Google\"", "Please sign in using 'Log in with Google'": "Vă rog conectați-vă folosind \"Conectați-vă cu Google\"",
"Password cannot be empty": "Parola nu poate fi goală", "Password cannot be empty": "Parola nu poate fi goală",
"Password cannot be longer than 55 characters": "Parola nu poate să conțină mai mult de 55 de caractere", "Password cannot be longer than 55 characters": "Parola nu poate să conțină mai mult de 55 de caractere",
@ -177,7 +175,6 @@
"Could not pull trending pages.": "Încărcarea paginilor de tendințe a eșuat.", "Could not pull trending pages.": "Încărcarea paginilor de tendințe a eșuat.",
"Hidden field \"challenge\" is a required field": "Câmpul ascuns \"challenge\" este un câmp obligatoriu", "Hidden field \"challenge\" is a required field": "Câmpul ascuns \"challenge\" este un câmp obligatoriu",
"Hidden field \"token\" is a required field": "Câmpul ascuns \"token\" este un câmp obligatoriu", "Hidden field \"token\" is a required field": "Câmpul ascuns \"token\" este un câmp obligatoriu",
"Erroneous challenge": "Challenge invalid",
"Erroneous token": "Token invalid", "Erroneous token": "Token invalid",
"No such user": "Acest utilizator nu există", "No such user": "Acest utilizator nu există",
"Token is expired, please try again": "Jetonul a expirat, vă rugăm să încercați din nou", "Token is expired, please try again": "Jetonul a expirat, vă rugăm să încercați din nou",

View file

@ -162,11 +162,9 @@
"Show replies": "Показать ответы", "Show replies": "Показать ответы",
"Incorrect password": "Неправильный пароль", "Incorrect password": "Неправильный пароль",
"Wrong answer": "Неправильный ответ", "Wrong answer": "Неправильный ответ",
"Erroneous CAPTCHA": "Неправильная капча",
"CAPTCHA is a required field": "Необходимо решить капчу",
"User ID is a required field": "Необходимо ввести ID пользователя", "User ID is a required field": "Необходимо ввести ID пользователя",
"Password is a required field": "Необходимо ввести пароль", "Password is a required field": "Необходимо ввести пароль",
"Wrong username or password": "Неправильный логин или пароль", "error_invalid_username_or_password": "Неправильный логин или пароль",
"Please sign in using 'Log in with Google'": "Пожалуйста, нажмите «Войти через Google»", "Please sign in using 'Log in with Google'": "Пожалуйста, нажмите «Войти через Google»",
"Password cannot be empty": "Пароль не может быть пустым", "Password cannot be empty": "Пароль не может быть пустым",
"Password cannot be longer than 55 characters": "Пароль не может быть длиннее 55 символов", "Password cannot be longer than 55 characters": "Пароль не может быть длиннее 55 символов",
@ -186,7 +184,6 @@
"Could not pull trending pages.": "Не удаётся загрузить страницы «в тренде».", "Could not pull trending pages.": "Не удаётся загрузить страницы «в тренде».",
"Hidden field \"challenge\" is a required field": "Необходимо заполнить скрытое поле «challenge»", "Hidden field \"challenge\" is a required field": "Необходимо заполнить скрытое поле «challenge»",
"Hidden field \"token\" is a required field": "Необходимо заполнить скрытое поле «токен»", "Hidden field \"token\" is a required field": "Необходимо заполнить скрытое поле «токен»",
"Erroneous challenge": "Неправильный ответ в «challenge»",
"Erroneous token": "Неправильный токен", "Erroneous token": "Неправильный токен",
"No such user": "Пользователь не найден", "No such user": "Пользователь не найден",
"Token is expired, please try again": "Срок действия токена истёк, попробуйте позже", "Token is expired, please try again": "Срок действия токена истёк, попробуйте позже",

View file

@ -126,7 +126,6 @@
"comments_points_count_2": "{{count}} točke", "comments_points_count_2": "{{count}} točke",
"comments_points_count_3": "{{count}} točk", "comments_points_count_3": "{{count}} točk",
"Hidden field \"token\" is a required field": "Skrito polje »žeton« je zahtevano polje", "Hidden field \"token\" is a required field": "Skrito polje »žeton« je zahtevano polje",
"Erroneous challenge": "Napačen izziv",
"English": "angleščina", "English": "angleščina",
"English (United States)": "angleščina (Združene države)", "English (United States)": "angleščina (Združene države)",
"Albanian": "albanščina", "Albanian": "albanščina",
@ -329,10 +328,9 @@
"Premieres in `x`": "Premiere v `x`", "Premieres in `x`": "Premiere v `x`",
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Živjo! Izgleda, da imaš izklopljene JavaScripte . Klikni tukaj, če si želiš ogledati komentarje, vendar vedi, da bo lahko nalaganje trajajo nekoliko dlje.", "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Živjo! Izgleda, da imaš izklopljene JavaScripte . Klikni tukaj, če si želiš ogledati komentarje, vendar vedi, da bo lahko nalaganje trajajo nekoliko dlje.",
"Show replies": "Pokaži odgovore", "Show replies": "Pokaži odgovore",
"Erroneous CAPTCHA": "Napačna CAPTCHA",
"User ID is a required field": "ID uporabnika je obvezno polje", "User ID is a required field": "ID uporabnika je obvezno polje",
"Password is a required field": "Geslo je obvezno polje", "Password is a required field": "Geslo je obvezno polje",
"Wrong username or password": "Napačno uporabniško ime ali geslo", "error_invalid_username_or_password": "Napačno uporabniško ime ali geslo",
"Password cannot be longer than 55 characters": "Geslo ne sme biti daljše od 55 znakov", "Password cannot be longer than 55 characters": "Geslo ne sme biti daljše od 55 znakov",
"channel:`x`": "kanal: `x`", "channel:`x`": "kanal: `x`",
"Could not fetch comments": "Ni bilo mogoče pridobiti komentarjev", "Could not fetch comments": "Ni bilo mogoče pridobiti komentarjev",
@ -350,7 +348,6 @@
"Token is expired, please try again": "Žeton je potekel, poskusi znova", "Token is expired, please try again": "Žeton je potekel, poskusi znova",
"English (United Kingdom)": "angleščina (Združeno kraljestvo)", "English (United Kingdom)": "angleščina (Združeno kraljestvo)",
"Wrong answer": "Napačen odgovor", "Wrong answer": "Napačen odgovor",
"CAPTCHA is a required field": "CAPTCHA je obvezno polje",
"Could not get channel info.": "Ni bilo mogoče dobiti informacij o kanalu.", "Could not get channel info.": "Ni bilo mogoče dobiti informacij o kanalu.",
"comments_view_x_replies_0": "Poglej {{count}} odgovor", "comments_view_x_replies_0": "Poglej {{count}} odgovor",
"comments_view_x_replies_1": "Poglej {{count}} odgovora", "comments_view_x_replies_1": "Poglej {{count}} odgovora",

View file

@ -157,11 +157,9 @@
"Blacklisted regions: ": "Rajone të palejuara: ", "Blacklisted regions: ": "Rajone të palejuara: ",
"Premieres in `x`": "Premiera në `x`", "Premieres in `x`": "Premiera në `x`",
"Wrong answer": "Përgjigje e gabuar", "Wrong answer": "Përgjigje e gabuar",
"Erroneous CAPTCHA": "CAPTCHA e gabuar",
"CAPTCHA is a required field": "CAPTCHA është fushë e domosdoshme",
"User ID is a required field": "ID-ja e përdoruesit është fushë e domosdoshme", "User ID is a required field": "ID-ja e përdoruesit është fushë e domosdoshme",
"Password is a required field": "Fusha e fjalëkalimit është e domosdoshme", "Password is a required field": "Fusha e fjalëkalimit është e domosdoshme",
"Wrong username or password": "Emër përdoruesi ose fjalëkalim i gabuar", "error_invalid_username_or_password": "Emër përdoruesi ose fjalëkalim i gabuar",
"Please sign in using 'Log in with Google'": "Ju lutemi, bëni hyrjen duke përdorur “Bëni hyrjen me Google”", "Please sign in using 'Log in with Google'": "Ju lutemi, bëni hyrjen duke përdorur “Bëni hyrjen me Google”",
"Password cannot be empty": "Fjalëkalimi smund të jetë i zbrazët", "Password cannot be empty": "Fjalëkalimi smund të jetë i zbrazët",
"Password cannot be longer than 55 characters": "Fjalëkalimi smund të jetë më i gjatë se 55 shenja", "Password cannot be longer than 55 characters": "Fjalëkalimi smund të jetë më i gjatë se 55 shenja",

View file

@ -56,7 +56,6 @@
"Editing playlist `x`": "Izmena plej liste `x`", "Editing playlist `x`": "Izmena plej liste `x`",
"Please sign in using 'Log in with Google'": "Molimo Vas da se prijavite pomoću 'Log in with Google'", "Please sign in using 'Log in with Google'": "Molimo Vas da se prijavite pomoću 'Log in with Google'",
"Playlist does not exist.": "Nepostojeća plej lista.", "Playlist does not exist.": "Nepostojeća plej lista.",
"Erroneous challenge": "Pogrešan izazov",
"Maltese": "Malteški", "Maltese": "Malteški",
"Download": "Preuzmi", "Download": "Preuzmi",
"Download as: ": "Preuzmi kao: ", "Download as: ": "Preuzmi kao: ",
@ -77,7 +76,7 @@
"Switch Invidious Instance": "Promeni Invidious instancu", "Switch Invidious Instance": "Promeni Invidious instancu",
"Hide annotations": "Sakrij napomene", "Hide annotations": "Sakrij napomene",
"User ID is a required field": "Korisnički ID je obavezno polje", "User ID is a required field": "Korisnički ID je obavezno polje",
"Wrong username or password": "Pogrešno korisničko ime ili lozinka", "error_invalid_username_or_password": "Pogrešno korisničko ime ili lozinka",
"Please log in": "Molimo vas da se prijavite", "Please log in": "Molimo vas da se prijavite",
"channel:`x`": "kanal:`x`", "channel:`x`": "kanal:`x`",
"Could not fetch comments": "Uzimanje komentara nije uspelo", "Could not fetch comments": "Uzimanje komentara nije uspelo",
@ -178,7 +177,6 @@
"": "Prikaži `x` komentara" "": "Prikaži `x` komentara"
}, },
"View Reddit comments": "Prikaži Reddit komentare", "View Reddit comments": "Prikaži Reddit komentare",
"CAPTCHA is a required field": "CAPTCHA je obavezno polje",
"Croatian": "Hrvatski", "Croatian": "Hrvatski",
"Estonian": "Estonski", "Estonian": "Estonski",
"Filipino": "Filipino", "Filipino": "Filipino",
@ -278,7 +276,6 @@
"Wrong answer": "Pogrešan odgovor", "Wrong answer": "Pogrešan odgovor",
"preferences_quality_label": "Preferirani video kvalitet: ", "preferences_quality_label": "Preferirani video kvalitet: ",
"Hide replies": "Sakrij odgovore", "Hide replies": "Sakrij odgovore",
"Erroneous CAPTCHA": "Pogrešna CAPTCHA",
"Erroneous token": "Pogrešan žeton", "Erroneous token": "Pogrešan žeton",
"Czech": "Češki", "Czech": "Češki",
"Latin": "Latinski", "Latin": "Latinski",

View file

@ -147,7 +147,6 @@
"Burmese": "Бурмански", "Burmese": "Бурмански",
"preferences_quality_dash_label": "Преферирани квалитет DASH видео формата: ", "preferences_quality_dash_label": "Преферирани квалитет DASH видео формата: ",
"Erroneous token": "Погрешан жетон", "Erroneous token": "Погрешан жетон",
"CAPTCHA is a required field": "CAPTCHA је обавезно поље",
"No such user": "Непостојећи корисник", "No such user": "Непостојећи корисник",
"Chinese (Traditional)": "Кинески (Традиционални)", "Chinese (Traditional)": "Кинески (Традиционални)",
"adminprefs_modified_source_code_url_label": "УРЛ веза до складишта са Измењеном Изворном Кодом", "adminprefs_modified_source_code_url_label": "УРЛ веза до складишта са Измењеном Изворном Кодом",
@ -191,7 +190,7 @@
"preferences_category_misc": "Остала подешавања", "preferences_category_misc": "Остала подешавања",
"User ID is a required field": "Кориснички ИД је обавезно поље", "User ID is a required field": "Кориснички ИД је обавезно поље",
"Password is a required field": "Лозинка је обавезно поље", "Password is a required field": "Лозинка је обавезно поље",
"Wrong username or password": "Погрешно корисничко име или лозинка", "error_invalid_username_or_password": "Погрешно корисничко име или лозинка",
"Please sign in using 'Log in with Google'": "Молимо Вас да се пријавите помоћу 'Log in with Google'", "Please sign in using 'Log in with Google'": "Молимо Вас да се пријавите помоћу 'Log in with Google'",
"Password cannot be empty": "Лозинка не може бити празна", "Password cannot be empty": "Лозинка не може бити празна",
"Password cannot be longer than 55 characters": "Лозинка не може бити дужа од 55 карактера", "Password cannot be longer than 55 characters": "Лозинка не може бити дужа од 55 карактера",
@ -267,7 +266,6 @@
"Shared `x`": "Подељено `x`", "Shared `x`": "Подељено `x`",
"Playlists": "Плеј листе", "Playlists": "Плеј листе",
"Yoruba": "Јоруба", "Yoruba": "Јоруба",
"Erroneous challenge": "Погрешан изазов",
"Danish": "Дански", "Danish": "Дански",
"Could not get channel info.": "Узимање података о каналу није успело.", "Could not get channel info.": "Узимање података о каналу није успело.",
"search_filters_features_option_hd": "HD", "search_filters_features_option_hd": "HD",
@ -352,7 +350,6 @@
"footer_source_code": "Изворна Кода", "footer_source_code": "Изворна Кода",
"search_filters_features_option_three_d": "3D", "search_filters_features_option_three_d": "3D",
"search_filters_features_option_four_k": "4K", "search_filters_features_option_four_k": "4K",
"Erroneous CAPTCHA": "Погрешна CAPTCHA",
"`x` ago": "пре `x`", "`x` ago": "пре `x`",
"Arabic": "Арапски", "Arabic": "Арапски",
"Bulgarian": "Бугарски", "Bulgarian": "Бугарски",

View file

@ -160,11 +160,9 @@
"Show replies": "Visa svar", "Show replies": "Visa svar",
"Incorrect password": "Fel lösenord", "Incorrect password": "Fel lösenord",
"Wrong answer": "Fel svar", "Wrong answer": "Fel svar",
"Erroneous CAPTCHA": "Ogiltig CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA är ett obligatoriskt fält",
"User ID is a required field": "Användar-ID är ett obligatoriskt fält", "User ID is a required field": "Användar-ID är ett obligatoriskt fält",
"Password is a required field": "Lösenord är ett obligatoriskt fält", "Password is a required field": "Lösenord är ett obligatoriskt fält",
"Wrong username or password": "Ogiltigt användarnamn eller lösenord", "error_invalid_username_or_password": "Ogiltigt användarnamn eller lösenord",
"Please sign in using 'Log in with Google'": "Logga in genom \"Google-inloggning\"", "Please sign in using 'Log in with Google'": "Logga in genom \"Google-inloggning\"",
"Password cannot be empty": "Lösenordet kan inte vara tomt", "Password cannot be empty": "Lösenordet kan inte vara tomt",
"Password cannot be longer than 55 characters": "Lösenordet kan inte vara längre än 55 tecken", "Password cannot be longer than 55 characters": "Lösenordet kan inte vara längre än 55 tecken",
@ -184,7 +182,6 @@
"Could not pull trending pages.": "Kunde inte hämta trendande sidor.", "Could not pull trending pages.": "Kunde inte hämta trendande sidor.",
"Hidden field \"challenge\" is a required field": "Dolt fält \"challenge\" är ett obligatoriskt fält", "Hidden field \"challenge\" is a required field": "Dolt fält \"challenge\" är ett obligatoriskt fält",
"Hidden field \"token\" is a required field": "Dolt fält \"token\" är ett obligatoriskt fält", "Hidden field \"token\" is a required field": "Dolt fält \"token\" är ett obligatoriskt fält",
"Erroneous challenge": "Felaktig challenge",
"Erroneous token": "Felaktig token", "Erroneous token": "Felaktig token",
"No such user": "Ogiltig användare", "No such user": "Ogiltig användare",
"Token is expired, please try again": "Token föråldrad, försök igen", "Token is expired, please try again": "Token föråldrad, försök igen",

View file

@ -162,11 +162,9 @@
"Show replies": "Cevapları göster", "Show replies": "Cevapları göster",
"Incorrect password": "Yanlış parola", "Incorrect password": "Yanlış parola",
"Wrong answer": "Yanlış cevap", "Wrong answer": "Yanlış cevap",
"Erroneous CAPTCHA": "Hatalı CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA zorunlu bir alandır",
"User ID is a required field": "Kullanıcı kimliği zorunlu bir alandır", "User ID is a required field": "Kullanıcı kimliği zorunlu bir alandır",
"Password is a required field": "Parola zorunlu bir alandır", "Password is a required field": "Parola zorunlu bir alandır",
"Wrong username or password": "Yanlış kullanıcı adı ya da parola", "error_invalid_username_or_password": "Yanlış kullanıcı adı ya da parola",
"Please sign in using 'Log in with Google'": "Lütfen 'Google ile giriş yap' seçeneğini kullanarak oturum açın", "Please sign in using 'Log in with Google'": "Lütfen 'Google ile giriş yap' seçeneğini kullanarak oturum açın",
"Password cannot be empty": "Parola boş olamaz", "Password cannot be empty": "Parola boş olamaz",
"Password cannot be longer than 55 characters": "Parola 55 karakterden uzun olamaz", "Password cannot be longer than 55 characters": "Parola 55 karakterden uzun olamaz",
@ -186,7 +184,6 @@
"Could not pull trending pages.": "Trend sayfaları alınamıyor.", "Could not pull trending pages.": "Trend sayfaları alınamıyor.",
"Hidden field \"challenge\" is a required field": "Gizli alan \"challenge\" zorunlu bir alandır", "Hidden field \"challenge\" is a required field": "Gizli alan \"challenge\" zorunlu bir alandır",
"Hidden field \"token\" is a required field": "\"belirteç\" gizli alanı zorunlu bir alandır", "Hidden field \"token\" is a required field": "\"belirteç\" gizli alanı zorunlu bir alandır",
"Erroneous challenge": "Hatalı challenge",
"Erroneous token": "Hatalı belirteç", "Erroneous token": "Hatalı belirteç",
"No such user": "Böyle bir kullanıcı yok", "No such user": "Böyle bir kullanıcı yok",
"Token is expired, please try again": "Belirtecin süresi doldu, lütfen tekrar deneyin", "Token is expired, please try again": "Belirtecin süresi doldu, lütfen tekrar deneyin",

View file

@ -153,11 +153,9 @@
"Show replies": "Показати відповіді", "Show replies": "Показати відповіді",
"Incorrect password": "Неправильний пароль", "Incorrect password": "Неправильний пароль",
"Wrong answer": "Неправильна відповідь", "Wrong answer": "Неправильна відповідь",
"Erroneous CAPTCHA": "Неправильна капча",
"CAPTCHA is a required field": "Необхідно пройти CAPTCHA",
"User ID is a required field": "Необхідно ввести ID користувача", "User ID is a required field": "Необхідно ввести ID користувача",
"Password is a required field": "Необхідно ввести пароль", "Password is a required field": "Необхідно ввести пароль",
"Wrong username or password": "Неправильний логін чи пароль", "error_invalid_username_or_password": "Неправильний логін чи пароль",
"Please sign in using 'Log in with Google'": "Будь ласка, натисніть «Увійти через Google»", "Please sign in using 'Log in with Google'": "Будь ласка, натисніть «Увійти через Google»",
"Password cannot be empty": "Пароль не може бути порожнім", "Password cannot be empty": "Пароль не може бути порожнім",
"Password cannot be longer than 55 characters": "Пароль не може бути довшим за 55 знаків", "Password cannot be longer than 55 characters": "Пароль не може бути довшим за 55 знаків",
@ -177,7 +175,6 @@
"Could not pull trending pages.": "Не вдається завантажити сторінки «у тренді».", "Could not pull trending pages.": "Не вдається завантажити сторінки «у тренді».",
"Hidden field \"challenge\" is a required field": "Необхідно заповнити приховане поле «challenge»", "Hidden field \"challenge\" is a required field": "Необхідно заповнити приховане поле «challenge»",
"Hidden field \"token\" is a required field": "Необхідно заповнити приховане поле «token»", "Hidden field \"token\" is a required field": "Необхідно заповнити приховане поле «token»",
"Erroneous challenge": "Неправильна відповідь у «challenge»",
"Erroneous token": "Недійсний токен", "Erroneous token": "Недійсний токен",
"No such user": "Недопустиме ім’я користувача", "No such user": "Недопустиме ім’я користувача",
"Token is expired, please try again": "Термін дії токена закінчився, спробуйте пізніше", "Token is expired, please try again": "Термін дії токена закінчився, спробуйте пізніше",

View file

@ -150,11 +150,9 @@
"Show replies": "Hiển thị câu trả lời", "Show replies": "Hiển thị câu trả lời",
"Incorrect password": "Mật khẩu không đúng", "Incorrect password": "Mật khẩu không đúng",
"Wrong answer": "Câu trả lời sai", "Wrong answer": "Câu trả lời sai",
"Erroneous CAPTCHA": "CAPTCHA bị lỗi",
"CAPTCHA is a required field": "CAPTCHA là trường bắt buộc",
"User ID is a required field": "User ID là trường bắt buộc", "User ID is a required field": "User ID là trường bắt buộc",
"Password is a required field": "Mật khẩu là trường bắt buộc", "Password is a required field": "Mật khẩu là trường bắt buộc",
"Wrong username or password": "Tên người dùng hoặc mật khẩu sai", "error_invalid_username_or_password": "Tên người dùng hoặc mật khẩu sai",
"Password cannot be empty": "Mật khẩu không được để trống", "Password cannot be empty": "Mật khẩu không được để trống",
"Password cannot be longer than 55 characters": "Mật khẩu không được dài hơn 55 ký tự", "Password cannot be longer than 55 characters": "Mật khẩu không được dài hơn 55 ký tự",
"Please log in": "Xin vui lòng đăng nhập", "Please log in": "Xin vui lòng đăng nhập",
@ -171,7 +169,6 @@
"Could not pull trending pages.": "Không thể kéo các trang thịnh hành.", "Could not pull trending pages.": "Không thể kéo các trang thịnh hành.",
"Hidden field \"challenge\" is a required field": "Trường ẩn \"challenge\" là trường bắt buộc", "Hidden field \"challenge\" is a required field": "Trường ẩn \"challenge\" là trường bắt buộc",
"Hidden field \"token\" is a required field": "Trường ẩn \"token\" là trường bắt buộc", "Hidden field \"token\" is a required field": "Trường ẩn \"token\" là trường bắt buộc",
"Erroneous challenge": "Thử thách sai",
"Erroneous token": "Mã thông báo bị lỗi", "Erroneous token": "Mã thông báo bị lỗi",
"No such user": "Không có người dùng như vậy", "No such user": "Không có người dùng như vậy",
"Token is expired, please try again": "Token đã hết hạn, vui lòng thử lại", "Token is expired, please try again": "Token đã hết hạn, vui lòng thử lại",

View file

@ -169,11 +169,9 @@
"Show replies": "显示回复", "Show replies": "显示回复",
"Incorrect password": "密码错误", "Incorrect password": "密码错误",
"Wrong answer": "错误的回复", "Wrong answer": "错误的回复",
"Erroneous CAPTCHA": "验证码错误",
"CAPTCHA is a required field": "验证码必填",
"User ID is a required field": "用户名必填", "User ID is a required field": "用户名必填",
"Password is a required field": "密码必填", "Password is a required field": "密码必填",
"Wrong username or password": "用户名或密码错误", "error_invalid_username_or_password": "用户名或密码错误",
"Password cannot be empty": "密码不能为空", "Password cannot be empty": "密码不能为空",
"Password cannot be longer than 55 characters": "密码长度不能大于 55", "Password cannot be longer than 55 characters": "密码长度不能大于 55",
"Please log in": "请登录", "Please log in": "请登录",
@ -194,7 +192,6 @@
"Could not pull trending pages.": "无法获取“时下流行”页面。", "Could not pull trending pages.": "无法获取“时下流行”页面。",
"Hidden field \"challenge\" is a required field": "隐藏表单项 \"challenge\" 为必填", "Hidden field \"challenge\" is a required field": "隐藏表单项 \"challenge\" 为必填",
"Hidden field \"token\" is a required field": "隐藏表单项 \"token\" 为必填", "Hidden field \"token\" is a required field": "隐藏表单项 \"token\" 为必填",
"Erroneous challenge": "错误的验证回复(challenge)",
"Erroneous token": "错误的令牌", "Erroneous token": "错误的令牌",
"No such user": "用户不存在", "No such user": "用户不存在",
"Token is expired, please try again": "令牌过期,请重试", "Token is expired, please try again": "令牌过期,请重试",

View file

@ -169,11 +169,9 @@
"Show replies": "顯示回覆", "Show replies": "顯示回覆",
"Incorrect password": "不正確的密碼", "Incorrect password": "不正確的密碼",
"Wrong answer": "錯誤的答案", "Wrong answer": "錯誤的答案",
"Erroneous CAPTCHA": "錯誤的 CAPTCHA",
"CAPTCHA is a required field": "CAPTCHA 為必填欄位",
"User ID is a required field": "使用者 ID 為必填欄位", "User ID is a required field": "使用者 ID 為必填欄位",
"Password is a required field": "密碼為必填欄位", "Password is a required field": "密碼為必填欄位",
"Wrong username or password": "錯誤的使用者名稱或密碼", "error_invalid_username_or_password": "錯誤的使用者名稱或密碼",
"Password cannot be empty": "密碼不能為空", "Password cannot be empty": "密碼不能為空",
"Password cannot be longer than 55 characters": "密碼不能長於55個字元", "Password cannot be longer than 55 characters": "密碼不能長於55個字元",
"Please log in": "請登入", "Please log in": "請登入",
@ -194,7 +192,6 @@
"Could not pull trending pages.": "無法拉取趨勢頁面。", "Could not pull trending pages.": "無法拉取趨勢頁面。",
"Hidden field \"challenge\" is a required field": "隱藏的欄位 \"challenge\" 是必填欄位", "Hidden field \"challenge\" is a required field": "隱藏的欄位 \"challenge\" 是必填欄位",
"Hidden field \"token\" is a required field": "隱藏的欄位 \"token\" 是必填欄位", "Hidden field \"token\" is a required field": "隱藏的欄位 \"token\" 是必填欄位",
"Erroneous challenge": "錯誤的 challenge",
"Erroneous token": "錯誤的 token", "Erroneous token": "錯誤的 token",
"No such user": "無此使用者", "No such user": "無此使用者",
"Token is expired, please try again": "Token 已過期,請再試一次", "Token is expired, please try again": "Token 已過期,請再試一次",

View file

@ -0,0 +1,135 @@
module Invidious::Frontend::LoginRegister
extend self
# HTML form input template
#
# `id` defines the CSS `id` attribute, as well as the localized label text.
# `type` defines the type of input (text, password, etc...)
private macro text_input(id, type)
str << %(\t\t\t<div class="pure-control-group">\n)
str << "\t\t\t\t<label for='{{id}}'>"
str << translate(locale, "login_page_{{id}}_label")
str << "</label><input type='{{type}}' id='{{id}}'>\n"
str << "\t\t\t</div>\n"
end
# Submit button template
#
# `variant` provided defines the CSS class name, as well
# as the associated localized text string.
private macro submit_button(variant)
str << %(\t<div class="pure-controls {{variant}}-submit-button">\n)
str << %(\t\t<button type='submit' class="pure-button pure-button-primary">)
str << translate(locale, "login_page_{{variant}}_button")
str << "</button>\n"
str << "\t</div>\n"
end
# Generate the log-in form's HTML
def gen_login_form(
env : HTTP::Server::Context,
account_type : String = "invidious",
captcha : User::Captcha? = nil
) : String
locale = env.get("preferences").as(Preferences).locale
# Create the parameters for the form URL
params = HTTP::Params.new
params["type"] = account_type
if referer = env.get?("referer").try &.as(String)
params["referer"] = referer
end
url = URI.new(path: "/login", query: params)
return String.build(1200) do |str|
# Begin log-in form
str << %(\t<form class="pure-form" method='post' action=") << url << %(">)
# Form content
case account_type
when "invidious"
# Text inputs
str << %(\t\t<div class="username-pass-fields">)
str << %(<fieldset class="pure-form-aligned">\n)
text_input(username, text)
text_input(password, password)
str << "\t\t</fieldset></div>\n"
# Captcha, if required
if !captcha.nil? && !captcha.type.none?
str << rendered "components/captcha"
end
end
# End of log-in form
str << "\t</form>\n"
submit_button(login)
# Prompt for the register page (we reuse the form's
# uri object for simplicity sake)
url.path = "/register"
str << "\t<p>"
str << translate(locale, "login_page_goto_register_prompt", url.to_s)
str << "</p>\n"
end
end
# Generate the registration form's HTML
def gen_register_form(
env : HTTP::Server::Context,
captcha : User::Captcha?
) : String
locale = env.get("preferences").as(Preferences).locale
# Create the parameters for the form URL
params = HTTP::Params.new
if referer = env.get?("referer").try &.as(String)
params["referer"] = referer
end
url = URI.new(path: "/register", query: params)
return String.build(1200) do |str|
# Begin registration form
str << %(\t<form class="pure-form" method='post' action=") << url << %(">)
# Text inputs
str << %(\t\t<div class="username-pass-fields">)
str << %(<fieldset class="pure-form-aligned">\n)
text_input(username, text)
str << "<br/>"
text_input(password, password)
text_input(confirm, password)
str << "\t\t</fieldset></div>\n"
# Captcha, if required
if !captcha.nil? && !captcha.type.none?
str << rendered "components/captcha"
end
# End of registration form
str << "\t</form>\n"
submit_button(register)
# Prompt for the login page (we reuse the form's
# uri object for simplicity sake)
url.path = "/login"
str << "\t<p>"
str << translate(locale, "login_page_goto_login_prompt", url.to_s)
str << "</p>\n"
str << "</div>"
end
end
end

View file

@ -48,9 +48,9 @@ module Invidious::Routes::Account
return error_template(400, ex) return error_template(400, ex)
end end
password = env.params.body["password"]? old_password = env.params.body["password"]?
if !password if old_password.nil? || old_password.empty?
return error_template(401, "Password is a required field") return error_template(401, "error_required_field_password")
end end
new_passwords = env.params.body.select { |k, v| k.match(/^new_password\[\d+\]$/) }.map { |k, v| v } new_passwords = env.params.body.select { |k, v| k.match(/^new_password\[\d+\]$/) }.map { |k, v| v }
@ -68,7 +68,7 @@ module Invidious::Routes::Account
return error_template(400, "Password cannot be longer than 55 characters") return error_template(400, "Password cannot be longer than 55 characters")
end end
if !Crypto::Bcrypt::Password.new(user.password.not_nil!).verify(password.byte_slice(0, 55)) if !user.validate_password(old_password)
return error_template(401, "Incorrect password") return error_template(401, "Incorrect password")
end end

View file

@ -3,187 +3,160 @@
module Invidious::Routes::Login module Invidious::Routes::Login
def self.login_page(env) def self.login_page(env)
locale = env.get("preferences").as(Preferences).locale locale = env.get("preferences").as(Preferences).locale
user = env.get? "user"
return env.redirect "/feed/subscriptions" if user
if !CONFIG.login_enabled
return error_template(400, "Login has been disabled by administrator.")
end
referer = get_referer(env, "/feed/subscriptions") referer = get_referer(env, "/feed/subscriptions")
email = nil return env.redirect referer if env.get? "user"
password = nil
captcha = nil
account_type = env.params.query["type"]? if !CONFIG.login_enabled
account_type ||= "invidious" return error_template(403, "error_login_disabled")
end
captcha_type = env.params.query["captcha"]? account_type = env.params.query["type"]? || "invidious"
captcha_type ||= "image"
tfa = env.params.query["tfa"]? captcha_type = User::Captcha.parse_type(env.params.query)
prompt = nil captcha = User::Captcha.generate(captcha_type)
templated "user/login" return templated "user/login"
end end
def self.login(env) def self.login(env)
locale = env.get("preferences").as(Preferences).locale locale = env.get("preferences").as(Preferences).locale
referer = get_referer(env, "/feed/subscriptions") referer = get_referer(env, "/feed/subscriptions")
if !CONFIG.login_enabled if !CONFIG.login_enabled
return error_template(403, "Login has been disabled by administrator.") return error_template(403, "error_login_disabled")
end end
# https://stackoverflow.com/a/574698 # Verify captcha
email = env.params.body["email"]?.try &.downcase.byte_slice(0, 254) if CONFIG.captcha_enabled
password = env.params.body["password"]? begin
captcha_verified = User::Captcha.verify(env)
raise InfoException.new("error_invalid_captcha") if !captcha_verified
rescue ex
return error_template(400, ex)
end
end
account_type = env.params.query["type"]? account_type = env.params.query["type"]? || "invidious"
account_type ||= "invidious"
case account_type case account_type
when "invidious" when "invidious"
if !email # https://stackoverflow.com/a/574698
return error_template(401, "User ID is a required field") username = env.params.body["username"]?.try &.downcase.byte_slice(0, 254)
password = env.params.body["password"]?
if username.nil? || username.empty? || password.nil? || password.empty?
return error_template(403, "error_invalid_username_or_password")
end end
if !password user = Database::Users.select(email: username)
return error_template(401, "Password is a required field")
end
user = Invidious::Database::Users.select(email: email)
if user
if Crypto::Bcrypt::Password.new(user.password.not_nil!).verify(password.byte_slice(0, 55))
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
Invidious::Database::SessionIDs.insert(sid, email)
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.domain, sid)
else
return error_template(401, "Wrong username or password")
end
# Since this user has already registered, we don't want to overwrite their preferences
if env.request.cookies["PREFS"]?
cookie = env.request.cookies["PREFS"]
cookie.expires = Time.utc(1990, 1, 1)
env.response.cookies << cookie
end
else
if !CONFIG.registration_enabled
return error_template(400, "Registration has been disabled by administrator.")
end
if password.empty?
return error_template(401, "Password cannot be empty")
end
# See https://security.stackexchange.com/a/39851
if password.bytesize > 55
return error_template(400, "Password cannot be longer than 55 characters")
end
password = password.byte_slice(0, 55)
if CONFIG.captcha_enabled
captcha_type = env.params.body["captcha_type"]?
answer = env.params.body["answer"]?
change_type = env.params.body["change_type"]?
if !captcha_type || change_type
if change_type
captcha_type = change_type
end
captcha_type ||= "image"
account_type = "invidious"
tfa = false
prompt = ""
if captcha_type == "image"
captcha = Invidious::User::Captcha.generate_image(HMAC_KEY)
else
captcha = Invidious::User::Captcha.generate_text(HMAC_KEY)
end
return templated "user/login"
end
tokens = env.params.body.select { |k, _| k.match(/^token\[\d+\]$/) }.map { |_, v| v }
answer ||= ""
captcha_type ||= "image"
case captcha_type
when "image"
answer = answer.lstrip('0')
answer = OpenSSL::HMAC.hexdigest(:sha256, HMAC_KEY, answer)
begin
validate_request(tokens[0], answer, env.request, HMAC_KEY, locale)
rescue ex
return error_template(400, ex)
end
else # "text"
answer = Digest::MD5.hexdigest(answer.downcase.strip)
if tokens.empty?
return error_template(500, "Erroneous CAPTCHA")
end
found_valid_captcha = false
error_exception = Exception.new
tokens.each do |tok|
begin
validate_request(tok, answer, env.request, HMAC_KEY, locale)
found_valid_captcha = true
rescue ex
error_exception = ex
end
end
if !found_valid_captcha
return error_template(500, error_exception)
end
end
end
if !user.nil? && user.validate_password(password)
# Generate session ID and store it.
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32)) sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
user, sid = create_user(sid, email, password) begin
Database::SessionIDs.insert(sid, username)
if language_header = env.request.headers["Accept-Language"]? rescue ex
if language = ANG.language_negotiator.best(language_header, LOCALES.keys) return error_template(500, "error_database_unavailable")
user.preferences.locale = language.header
end
end end
Invidious::Database::Users.insert(user) # Generate cookies
Invidious::Database::SessionIDs.insert(sid, email) env.response.cookies["SID"] = User::Cookies.sid(CONFIG.domain, sid)
env.response.cookies["PREFS"] = User::Cookies.prefs(CONFIG.domain, user.preferences)
view_name = "subscriptions_#{sha256(user.email)}" else
PG_DB.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(user.email)}") return error_template(403, "error_invalid_username_or_password")
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.domain, sid)
if env.request.cookies["PREFS"]?
user.preferences = env.get("preferences").as(Preferences)
Invidious::Database::Users.update_preferences(user)
cookie = env.request.cookies["PREFS"]
cookie.expires = Time.utc(1990, 1, 1)
env.response.cookies << cookie
end
end end
env.redirect referer
else
env.redirect referer
end end
return env.redirect referer
end
def self.register_page(env)
locale = env.get("preferences").as(Preferences).locale
referer = get_referer(env, "/feed/subscriptions")
return env.redirect referer if env.get? "user"
if !CONFIG.registration_enabled
return error_template(403, "error_registration_disabled")
end
captcha_type = User::Captcha.parse_type(env.params.query)
captcha = User::Captcha.generate(captcha_type)
return templated "user/register"
end
def self.register(env)
locale = env.get("preferences").as(Preferences).locale
referer = get_referer(env, "/feed/subscriptions")
if !CONFIG.registration_enabled
return error_template(403, "error_registration_disabled")
end
# https://stackoverflow.com/a/574698
username = env.params.body["username"]?.try &.downcase.byte_slice(0, 254)
password = env.params.body["password"]?
confirm = env.params.body["confirm"]?
if username.nil? || username.empty?
return error_template(400, "error_required_field_username")
end
if password.nil? || password.empty? || confirm.nil? || confirm.empty?
return error_template(400, "error_required_field_password")
end
if password != confirm
return error_template(400, "error_passwords_dont_match")
end
# TODO: find a way to allow longer passwords
# See https://security.stackexchange.com/a/39851
if password.bytesize > 55
return error_template(400, "Password cannot be longer than 55 characters")
end
# Verify captcha
if CONFIG.captcha_enabled
begin
captcha_verified = User::Captcha.verify(env)
raise InfoException.new("error_invalid_captcha") if !captcha_verified
rescue ex
return error_template(400, ex)
end
end
# Make sure that user doesn't exist!!
user_check = Database::Users.select(email: username)
if !user_check.nil?
return error_template(400, "error_username_already_registered")
end
# Generate session ID
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
user = User.create(sid, username, password)
# Use the preferences from user cookie (pre-registration)
# and save them into the account. Otherwise, make a new one.
if env.request.cookies["PREFS"]?
user.preferences = env.get("preferences").as(Preferences)
end
# Create the proper DN
# TODO: use DB transaction here to avoid corrupted states
Database::Users.insert(user)
Database::SessionIDs.insert(sid, username)
view_name = "subscriptions_#{sha256(user.email)}"
PG_DB.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(user.email)}")
# Generate cookies
env.response.cookies["SID"] = User::Cookies.sid(CONFIG.domain, sid)
env.response.cookies["PREFS"] = User::Cookies.prefs(CONFIG.domain, user.preferences)
return env.redirect referer
end end
def self.signout(env) def self.signout(env)
@ -214,6 +187,6 @@ module Invidious::Routes::Login
env.response.cookies << cookie env.response.cookies << cookie
end end
env.redirect referer return env.redirect referer
end end
end end

View file

@ -51,9 +51,11 @@ module Invidious::Routing
# ------------------- # -------------------
def register_user_routes def register_user_routes
# User login/out # User login/out and registration
get "/login", Routes::Login, :login_page get "/login", Routes::Login, :login_page
post "/login", Routes::Login, :login post "/login", Routes::Login, :login
get "/register", Routes::Login, :register_page
post "/register", Routes::Login, :register
post "/signout", Routes::Login, :signout post "/signout", Routes::Login, :signout
# User preferences # User preferences

View file

@ -1,12 +1,57 @@
require "openssl/hmac" require "openssl/hmac"
struct Invidious::User struct Invidious::User
module Captcha struct Captcha
extend self
private TEXTCAPTCHA_URL = URI.parse("https://textcaptcha.com") private TEXTCAPTCHA_URL = URI.parse("https://textcaptcha.com")
def generate_image(key) # Structure that holds the type, the question string and the
# cryptographically signed response(s).
getter type : Type
getter question : String
getter tokens : Array(String)
def initialize(@type, @question, @tokens)
end
# -------------------
# Type parsing
# -------------------
enum Type
None
Text
Image
end
def self.parse_type(params : HTTP::Params) : Type
if CONFIG.captcha_enabled
type_text = params["captcha"]? || "image"
type = Type.parse?(type_text) || Type::Image
# You opened the dev tools, didn't you? :P
type = Type::Image if type.none?
else
type = Type::None
end
return type
end
# -------------------
# Generators
# -------------------
# High-level method that calls the captcha generator for the given type.
def self.generate(type : Type) : Captcha?
case type
when .image? then return gen_image_captcha(HMAC_KEY)
when .text? then return gen_text_captcha(HMAC_KEY)
else
return nil
end
end
private def self.gen_image_captcha(key) : Captcha
second = Random::Secure.rand(12) second = Random::Secure.rand(12)
second_angle = second * 30 second_angle = second * 30
second = second * 5 second = second * 5
@ -17,9 +62,6 @@ struct Invidious::User
hour = Random::Secure.rand(12) hour = Random::Secure.rand(12)
hour_angle = hour * 30 + minute_angle.to_f / 12 hour_angle = hour * 30 + minute_angle.to_f / 12
if hour == 0
hour = 12
end
clock_svg = <<-END_SVG clock_svg = <<-END_SVG
<svg viewBox="0 0 100 100" width="200px" height="200px"> <svg viewBox="0 0 100 100" width="200px" height="200px">
@ -52,16 +94,43 @@ struct Invidious::User
Base64.strict_encode(proc.output.gets_to_end) Base64.strict_encode(proc.output.gets_to_end)
end end
answer = "#{hour}:#{minute.to_s.rjust(2, '0')}:#{second.to_s.rjust(2, '0')}" answer_raw = self.format_time(hour, minute, second, validate: false)
answer = OpenSSL::HMAC.hexdigest(:sha256, key, answer) answer = OpenSSL::HMAC.hexdigest(:sha256, key, answer_raw)
return { LOGGER.trace("Captcha: image question is #{answer_raw} (anwser digest: #{answer})")
return Captcha.new(
type: Type::Image,
question: image, question: image,
tokens: {generate_response(answer, {":login"}, key, use_nonce: true)}, tokens: [generate_response(answer, {":login"}, key, use_nonce: true)],
} )
end end
def generate_text(key) private def self.format_time(hours : Int, minutes : Int, seconds : Int, *, validate : Bool)
# Check for incorrect answers
if validate
raise Exception.new if !(0..23).includes?(hours)
raise Exception.new if !(0..59).includes?(minutes)
raise Exception.new if !(0..59).includes?(seconds)
end
# Normalize hours
case hours
when .zero? then hours = 12
when .> 12 then hours -= 12
end
# Craft answer string
return String.build(8) do |answer|
answer << hours.to_s(precision: 2)
answer << ':'
answer << minutes.to_s(precision: 2)
answer << ':'
answer << seconds.to_s(precision: 2)
end
end
private def self.gen_text_captcha(key) : Captcha
response = make_client(TEXTCAPTCHA_URL, &.get("/github.com/iv.org/invidious.json").body) response = make_client(TEXTCAPTCHA_URL, &.get("/github.com/iv.org/invidious.json").body)
response = JSON.parse(response) response = JSON.parse(response)
@ -69,10 +138,70 @@ struct Invidious::User
generate_response(answer.as_s, {":login"}, key, use_nonce: true) generate_response(answer.as_s, {":login"}, key, use_nonce: true)
end end
return { question = response["q"].as_s
question: response["q"].as_s,
tokens: tokens, LOGGER.trace("Captcha: text question is #{question}: (answers digests: #{tokens})")
}
return Captcha.new(
type: Type::Text,
question: question,
tokens: tokens,
)
end
# -------------------
# Validation
# -------------------
# Return true if the captcha was succesfully validated
# Otherwise, raise the appropriate Exception
def self.verify(env) : Bool
captcha_type = self.parse_type(env.params.body)
answer = env.params.body["answer"]? || ""
tokens = env.params.body.fetch_all("token")
if answer.empty? || tokens.empty?
LOGGER.debug("Captcha: validate: got error_invalid_captcha, answer or token is empty")
raise InfoException.new("error_invalid_captcha")
end
case captcha_type
when .image?
begin
hours, minutes, seconds = answer.split(':').map &.to_i
answer = self.format_time(hours, minutes, seconds, validate: true)
rescue ex
LOGGER.debug("Captcha: validate: got error_invalid_captcha, answer to image captcha failed to parse")
raise InfoException.new("error_invalid_captcha")
end
answer = OpenSSL::HMAC.hexdigest(:sha256, HMAC_KEY, answer)
# Raises on error
validate_request(tokens[0], answer, env.request, HMAC_KEY)
return true
when .text?
answer = Digest::MD5.hexdigest(answer.downcase.strip)
error_exception = InfoException.new
tokens.each do |tok|
begin
# Raises on error
validate_request(tok, answer, env.request, HMAC_KEY)
return true
rescue ex
error_exception = ex
end
end
LOGGER.debug("Captcha: validate: bad answer to text captcha")
raise error_exception
end
# Just to be safe
return false
end end
end end
end end

View file

@ -4,16 +4,36 @@ struct Invidious::User
include DB::Serializable include DB::Serializable
property updated : Time property updated : Time
property notifications : Array(String) property notifications : Array(String) = [] of String
property subscriptions : Array(String) property subscriptions : Array(String) = [] of String
property email : String property email : String
@[DB::Field(converter: Invidious::User::PreferencesConverter)] @[DB::Field(converter: Invidious::User::PreferencesConverter)]
property preferences : Preferences property preferences : Preferences
property password : String? property password : String?
property token : String property token : String
property watched : Array(String) property watched : Array(String) = [] of String
property feed_needs_update : Bool? property feed_needs_update : Bool? = true
def initialize(*, @email, @token, @password)
@updated = Time.utc
@preferences = Preferences.new(CONFIG.default_user_preferences.to_tuple)
end
def self.create(sid, email, password) : User
hashed_pwd = Crypto::Bcrypt::Password.create(password, cost: 10)
token = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
return User.new(email: email, token: token, password: hashed_pwd.to_s)
end
def validate_password(password : String) : Bool
# Damned Google accounts were stored with a nil password
stored_password = @password
return false if stored_password.nil?
return Crypto::Bcrypt::Password.new(stored_password).verify(password)
end
module PreferencesConverter module PreferencesConverter
def self.from_rs(rs) def self.from_rs(rs)

View file

@ -3,25 +3,6 @@ require "crypto/bcrypt/password"
# Materialized views may not be defined using bound parameters (`$1` as used elsewhere) # Materialized views may not be defined using bound parameters (`$1` as used elsewhere)
MATERIALIZED_VIEW_SQL = ->(email : String) { "SELECT cv.* FROM channel_videos cv WHERE EXISTS (SELECT subscriptions FROM users u WHERE cv.ucid = ANY (u.subscriptions) AND u.email = E'#{email.gsub({'\'' => "\\'", '\\' => "\\\\"})}') ORDER BY published DESC" } MATERIALIZED_VIEW_SQL = ->(email : String) { "SELECT cv.* FROM channel_videos cv WHERE EXISTS (SELECT subscriptions FROM users u WHERE cv.ucid = ANY (u.subscriptions) AND u.email = E'#{email.gsub({'\'' => "\\'", '\\' => "\\\\"})}') ORDER BY published DESC" }
def create_user(sid, email, password)
password = Crypto::Bcrypt::Password.create(password, cost: 10)
token = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
user = Invidious::User.new({
updated: Time.utc,
notifications: [] of String,
subscriptions: [] of String,
email: email,
preferences: Preferences.new(CONFIG.default_user_preferences.to_tuple),
password: password.to_s,
token: token,
watched: [] of String,
feed_needs_update: true,
})
return user, sid
end
def get_subscription_feed(user, max_results = 40, page = 1) def get_subscription_feed(user, max_results = 40, page = 1)
limit = max_results.clamp(0, MAX_ITEMS_PER_PAGE) limit = max_results.clamp(0, MAX_ITEMS_PER_PAGE)
offset = (page - 1) * limit offset = (page - 1) * limit

View file

@ -0,0 +1,39 @@
<div class="captcha flexible">
<input type='hidden' name='captcha_type' value="<%= captcha.type %>">
<%- captcha.tokens.each do |tok| -%>
<input type='hidden' name='tokens' value="<%= HTML.escape(tok) %>">
<%- end -%>
<%- if captcha.type.image? %>
<div class="left">
<img src="<%= captcha.question %>"/>
</div>
<div class="right">
<fieldset class="pure-form-stacked">
<div class="pure-control-group">
<label for='answer'><%= translate(locale, "Time (h:mm:ss):") %></label><input
type='text' name='answer' type='text' placeholder="hh:mm:ss">
</div>
</fieldset>
<a src="<%= url %>&captcha_type=text"><%= translate(locale, "login_page_request_text_captcha") %></a>
</div>
<%- else # type.text? %>
<fieldset class="pure-form-stacked">
<div class="pure-control-group">
<label for='answer' lang="en"><%= captcha.question %></label><input
type='text' name='answer' type='text' placeholder="<%= translate(locale, "Answer") %>">
</div>
</fieldset>
<a src=") << url << %(&captcha_type=image"><%= translate(locale, "login_page_request_image_captcha") %></a>
<%- end %>
</div>

View file

@ -1,77 +1,10 @@
<% content_for "header" do %> <% content_for "header" do %>
<title><%= translate(locale, "Log in") %> - Invidious</title> <title><%= translate(locale, "login_page_title_login") %> - Invidious</title>
<link rel="stylesheet" href="/css/user.css?v=<%= ASSET_COMMIT %>">
<% end %> <% end %>
<div class="pure-g"> <div class="h-box">
<div class="pure-u-1 pure-u-lg-1-5"></div> <div class="login-container">
<div class="pure-u-1 pure-u-lg-3-5"> <%= Invidious::Frontend::LoginRegister.gen_login_form(env, account_type, captcha) %>
<div class="h-box"> </div>
<%- case account_type when -%>
<%- when "invidious" -%>
<form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.encode_www_form(referer) %>&type=invidious" method="post">
<fieldset>
<% if email %>
<input name="email" type="hidden" value="<%= HTML.escape(email) %>">
<% else %>
<label for="email"><%= translate(locale, "User ID") %> :</label>
<input required class="pure-input-1" name="email" type="text" placeholder="<%= translate(locale, "User ID") %>">
<% end %>
<% if password %>
<input name="password" type="hidden" value="<%= HTML.escape(password) %>">
<% else %>
<label for="password"><%= translate(locale, "Password") %> :</label>
<input required class="pure-input-1" name="password" type="password" placeholder="<%= translate(locale, "Password") %>">
<% end %>
<% if captcha %>
<% case captcha_type when %>
<% when "image" %>
<% captcha = captcha.not_nil! %>
<img style="width:50%" src='<%= captcha[:question] %>'/>
<% captcha[:tokens].each_with_index do |token, i| %>
<input type="hidden" name="token[<%= i %>]" value="<%= HTML.escape(token) %>">
<% end %>
<input type="hidden" name="captcha_type" value="image">
<label for="answer"><%= translate(locale, "Time (h:mm:ss):") %></label>
<input type="text" name="answer" type="text" placeholder="h:mm:ss">
<% else # "text" %>
<% captcha = captcha.not_nil! %>
<% captcha[:tokens].each_with_index do |token, i| %>
<input type="hidden" name="token[<%= i %>]" value="<%= HTML.escape(token) %>">
<% end %>
<input type="hidden" name="captcha_type" value="text">
<label for="answer"><%= captcha[:question] %></label>
<input type="text" name="answer" type="text" placeholder="<%= translate(locale, "Answer") %>">
<% end %>
<button type="submit" name="action" value="signin" class="pure-button pure-button-primary">
<%= translate(locale, "Register") %>
</button>
<% case captcha_type when %>
<% when "image" %>
<label>
<button type="submit" name="change_type" class="pure-button pure-button-primary" value="text">
<%= translate(locale, "Text CAPTCHA") %>
</button>
</label>
<% else # "text" %>
<label>
<button type="submit" name="change_type" class="pure-button pure-button-primary" value="image">
<%= translate(locale, "Image CAPTCHA") %>
</button>
</label>
<% end %>
<% else %>
<button type="submit" name="action" value="signin" class="pure-button pure-button-primary">
<%= translate(locale, "Sign In") %>/<%= translate(locale, "Register") %>
</button>
<% end %>
</fieldset>
</form>
<%- end -%>
</div>
</div>
<div class="pure-u-1 pure-u-lg-1-5"></div>
</div> </div>

View file

@ -0,0 +1,10 @@
<% content_for "header" do %>
<title><%= translate(locale, "login_page_title_register") %> - Invidious</title>
<link rel="stylesheet" href="/css/user.css?v=<%= ASSET_COMMIT %>">
<% end %>
<div class="h-box">
<div class="register-container">
<%= Invidious::Frontend::LoginRegister.gen_register_form(env, captcha) %>
</div>
</div>