Merge remote-tracking branch 'origin/master' into develop

v1.18.x
Julian Lam 7 years ago
commit ec07247854

@ -19,23 +19,23 @@
"dependencies": {
"ace-builds": "^1.2.9",
"async": "2.6.0",
"autoprefixer": "7.1.6",
"autoprefixer": "7.2.4",
"bcryptjs": "2.4.3",
"benchpressjs": "^1.2.0",
"body-parser": "^1.18.2",
"bootstrap": "^3.3.7",
"chart.js": "^2.7.0",
"chart.js": "^2.7.1",
"colors": "^1.1.2",
"compression": "^1.7.1",
"commander": "^2.11.0",
"commander": "^2.12.2",
"connect-ensure-login": "^0.1.1",
"connect-flash": "^0.1.1",
"connect-mongo": "2.0.0",
"connect-mongo": "2.0.1",
"connect-multiparty": "^2.1.0",
"connect-redis": "3.3.2",
"connect-redis": "3.3.3",
"cookie-parser": "^1.4.3",
"cron": "^1.3.0",
"cropperjs": "^1.1.3",
"cropperjs": "^1.2.2",
"csurf": "^1.9.0",
"daemon": "^1.1.0",
"express": "^4.16.2",
@ -48,12 +48,12 @@
"jquery": "^3.2.1",
"jsesc": "2.5.1",
"json-2-csv": "^2.1.2",
"less": "^2.7.2",
"less": "^2.7.3",
"lodash": "^4.17.4",
"logrotate-stream": "^0.2.5",
"lru-cache": "4.1.1",
"material-design-lite": "^1.3.0",
"mime": "^2.0.3",
"mime": "^2.2.0",
"mkdirp": "^0.5.1",
"mongodb": "2.2.33",
"morgan": "^1.9.0",
@ -69,22 +69,22 @@
"nodebb-plugin-spam-be-gone": "0.5.1",
"nodebb-rewards-essentials": "0.0.9",
"nodebb-theme-lavender": "5.0.0",
"nodebb-theme-persona": "7.2.9",
"nodebb-theme-persona": "7.2.10",
"nodebb-theme-slick": "1.1.2",
"nodebb-theme-vanilla": "8.1.4",
"nodebb-widget-essentials": "4.0.1",
"nodemailer": "4.4.0",
"nodemailer": "4.4.1",
"passport": "^0.4.0",
"passport-local": "1.0.0",
"postcss": "6.0.14",
"postcss": "6.0.15",
"postcss-clean": "1.1.0",
"promise-polyfill": "^6.0.2",
"promise-polyfill": "^7.0.0",
"prompt": "^1.0.0",
"redis": "2.8.0",
"request": "2.83.0",
"rimraf": "2.6.2",
"rss": "^1.2.2",
"sanitize-html": "^1.14.1",
"sanitize-html": "^1.16.3",
"semver": "^5.4.1",
"serve-favicon": "^2.4.5",
"sitemap": "^1.13.0",
@ -94,8 +94,8 @@
"socketio-wildcard": "2.0.0",
"spdx-license-list": "^3.0.1",
"toobusy-js": "^0.5.1",
"uglify-js": "^3.1.5",
"validator": "9.1.2",
"uglify-js": "^3.3.4",
"validator": "9.2.0",
"winston": "^2.4.0",
"xml": "^1.0.1",
"xregexp": "3.2.0",
@ -103,16 +103,16 @@
},
"devDependencies": {
"coveralls": "^3.0.0",
"eslint": "^4.9.0",
"eslint": "^4.14.0",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-plugin-import": "^2.8.0",
"grunt": "^1.0.1",
"grunt-contrib-watch": "^1.0.0",
"jsdom": "^11.3.0",
"mocha": "^4.0.1",
"jsdom": "^11.5.1",
"mocha": "^4.1.0",
"mocha-lcov-reporter": "^1.3.0",
"nyc": "^11.2.1",
"smtp-server": "^3.3.0"
"nyc": "^11.4.1",
"smtp-server": "^3.4.1"
},
"bugs": {
"url": "https://github.com/NodeBB/NodeBB/issues"

@ -1,5 +1,5 @@
{
"notifications": "Notifications",
"notifications": "التنبيهات",
"chat-messages": "Chat Messages",
"play-sound": "Play",
"incoming-message": "Incoming Message",

@ -1,6 +1,6 @@
{
"settings": "Category Settings",
"privileges": "Privileges",
"settings": "اعدادات القسم",
"privileges": "الصلاحيات",
"name": "Category Name",
"description": "Category Description",

@ -1,5 +1,5 @@
{
"name": "Group Name",
"name": "اسم المجموعة",
"description": "Group Description",
"member-count": "Member Count",
"system": "System Group",

@ -1,6 +1,6 @@
{
"users": "Users",
"edit": "Edit",
"users": "المستخدمين",
"edit": "تحرير",
"make-admin": "Make Admin",
"remove-admin": "Remove Admin",
"validate-email": "Validate Email",

@ -1,6 +1,6 @@
{
"eu-consent": "EU Consent",
"consent.enabled": "Enabled",
"consent.enabled": "تفعيل",
"consent.message": "Notification message",
"consent.acceptance": "Acceptance message",
"consent.link-text": "Policy Link Text",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "أدوات الموضوع",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "علق الموضوع",
"thread_tools.unpin": "إلغاء تعليق الموضوع",
"thread_tools.lock": "أقفل الموضوع",

@ -112,7 +112,7 @@
"topic_search_help": "إذا قمت بتفعيل ميزة البحث في-الموضوع، سيتم تجاوز الخيار الافتراضي للمتصفح مما يؤدي للبحث بكامل الموضوع بدلا عن البحث في الجزء الظاهر في الشاشة.",
"delay_image_loading": "تأخير عرض الصور",
"image_load_delay_help": "إذا تم تمكينه، فلن يتم تحميل الصور في المواضيع حتى يتم تمريرها في الشاشة",
"scroll_to_my_post": "After posting a reply, show the new post",
"scroll_to_my_post": "بعد اضافة رد على المشاركة, قم بإظهار المشاركة",
"follow_topics_you_reply_to": "متابعة المواضيع التي تقوم بالرد عليها",
"follow_topics_you_create": "متابعة المواضيع التي تقوم بإنشائها",
"grouptitle": "عنوان المجموعة",

@ -52,7 +52,7 @@
"not-watching.description": "Не искам да получавам известия за новите отговори.<br/>Темата да се показва в списъка с непрочетени, само ако категорията не се пренебрегва.",
"ignoring.description": "Не искам да получавам известия за новите отговори.<br/>Не искам темата да се показва в списъка с непрочетени.",
"thread_tools.title": "Инструменти за темата",
"thread_tools.markAsUnreadForAll": "Отбелязване като непрочетена за всички",
"thread_tools.markAsUnreadForAll": "Отбелязване на всички като непрочетени",
"thread_tools.pin": "Закачане на темата",
"thread_tools.unpin": "Откачане на темата",
"thread_tools.lock": "Заключване на темата",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "টপিক সম্পর্কিত টুলস",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "টপিক পিন করুন",
"thread_tools.unpin": "টপিক আনপিন করুন",
"thread_tools.lock": "টপিক বন্ধ করুন",

@ -52,7 +52,7 @@
"not-watching.description": "Neupozorňovat na nové odpovědi. <br/>Zobrazit téma v nepřečtených, není-li tato kategorie ignorována",
"ignoring.description": "Neupozorňovat na nové odpovědi.<br/>Nezobrazovat téma v nepřečtených.",
"thread_tools.title": "Nástroje tématu",
"thread_tools.markAsUnreadForAll": "Označit jako nepřečtené pro všechny",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Připnout téma",
"thread_tools.unpin": "Odepnout téma",
"thread_tools.lock": "Zamknout téma",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Emne værktøjer",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Fastgør tråd",
"thread_tools.unpin": "Frigør tråd",
"thread_tools.lock": "Lås tråd",

@ -52,7 +52,7 @@
"not-watching.description": "Keine Benachrichtigung bei neuen Beiträgen.<br/>Ungelesen Beiträge anzeigen wenn die Kategorie nicht ignoriert wird.",
"ignoring.description": "Keine Benachrichtigung bei neuen Beiträgen.<br/>Ungelesene Beiträge nicht anzeigen.",
"thread_tools.title": "Themen-Werkzeuge",
"thread_tools.markAsUnreadForAll": "Für alle als ungelesen markiert.",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Thema anheften",
"thread_tools.unpin": "Thema nicht mehr anheften",
"thread_tools.lock": "Thema schließen",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Εργαλεία Θέματος",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Καρφίτσωμα Θέματος",
"thread_tools.unpin": "Ξεκαρφίτσωμα Θέματος",
"thread_tools.lock": "Κλείδωμα Θέματος",

@ -63,7 +63,7 @@
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Topic Tools",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Pin Topic",
"thread_tools.unpin": "Unpin Topic",
"thread_tools.lock": "Lock Topic",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Topic Tools",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Pin Topic",
"thread_tools.unpin": "Unpin Topic",
"thread_tools.lock": "Lock Topic",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Topic Tools",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Pin Topic",
"thread_tools.unpin": "Unpin Topic",
"thread_tools.lock": "Lock Topic",

@ -52,7 +52,7 @@
"not-watching.description": "No notificarme de nuevas respuestas.<br/>Mostrar tema en no leídos si sigo esa categoría. ",
"ignoring.description": "No notificarme de nuevas respuestas.<br/>No mostrar tema en no leídos. ",
"thread_tools.title": "Herramientas",
"thread_tools.markAsUnreadForAll": "Marcar todo como no leído.",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Adherir tema",
"thread_tools.unpin": "Despegar tema",
"thread_tools.lock": "Cerrar tema",

@ -52,7 +52,7 @@
"not-watching.description": "Ära teavita mind uutest vastustest.<br/>Näita teemat lugemata teemade hulgas, kui kategooria on ignoreeritud.",
"ignoring.description": "Ära teavita mind uutest vastustest.<br/>Ära näita teemat lugemata teemade hulgas.",
"thread_tools.title": "Teema tööriistad",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Tõsta esile teema",
"thread_tools.unpin": "Märgista teema",
"thread_tools.lock": "Lukusta teema",

@ -52,7 +52,7 @@
"not-watching.description": "به من پس از ارسال هر پاسخی جدیدی اطلاع نده.<br/>تاپیک به صورت خوانده نشده قرار بگیرد ولی نادیده گرفته نشود.",
"ignoring.description": "به من پس از ارسال هر پاسخی جدیدی اطلاع نده.<br/>دیگر تاپیک را به صورت خوانده نشده نشان نده.",
"thread_tools.title": "ابزارهای موضوع",
"thread_tools.markAsUnreadForAll": "علامت بزن به عنوان خوانده نشده برای همه",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "سنجاق زدن موضوع",
"thread_tools.unpin": "برداشتن سنجاق موضوع",
"thread_tools.lock": "قفل کردن موضوع",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Aiheen työkalut",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Kiinnitä aihe",
"thread_tools.unpin": "Poista aiheen kiinnitys",
"thread_tools.lock": "Lukitse aihe",

@ -8,7 +8,7 @@
"custom-js.enable": "Activer le Javascript personnalisé",
"custom-header": "En-tête personnalisé",
"custom-header.description": "Enter custom HTML here (ex. Meta Tags, etc.), which will be appended to the <code>&lt;head&gt;</code> section of your forum's markup. Script tags are allowed, but are discouraged, as the <a href=\"#custom-header\" data-toggle=\"tab\">Custom Javascript</a> tab is available.",
"custom-header.description": "Entrez un code html personnalisé ici ( par exemple : Méta-Tags,...), qui sera rajouté à la section <code>&lt;head&gt;</code> du balisage de votre forum. Les balises de textes sont autorisés, mais sont déconseillés, l'onglet <a href=\"#custom-header\" data-toggle=\"tab\">Javascript personnalisé</a> étant prévu à cet effet.",
"custom-header.enable": "Activer les en-têtes personnalisés",
"custom-css.livereload": "Activer le rechargement en direct",

@ -39,7 +39,7 @@
"section-appearance": "Apparence",
"appearance/themes": "Thèmes",
"appearance/skins": "Skins",
"appearance/customise": "Custom Content (HTML/JS/CSS)",
"appearance/customise": "Contenu personnalisé (HTML/JS/CSS)",
"section-extend": "Extensions",
"extend/plugins": "Plugins",

@ -2,5 +2,5 @@
"notifications": "Notifications",
"welcome-notification": "Notification de bienvenue",
"welcome-notification-link": "Lien de notification de bienvenue",
"welcome-notification-uid": "Welcome Notification User (UID)"
"welcome-notification-uid": "Notification de bienvenue de l'utilisateur (UID)"
}

@ -4,7 +4,7 @@
"sorting.oldest-to-newest": "Du plus ancien au plus récent",
"sorting.newest-to-oldest": "Du plus récent au plus ancien",
"sorting.most-votes": "Avec le plus de votes",
"sorting.most-posts": "Most Posts",
"sorting.most-posts": "Avec le plus de messages",
"sorting.topic-default": "Tri des sujets par défaut",
"restrictions": "Restrictions d'envoi",
"restrictions.post-queue": "Activer la file d'attente des messages",

@ -19,8 +19,8 @@
"themes": "Thèmes",
"disable-user-skins": "Empêcher les utilisateurs de choisir un skin personnalisé",
"account-protection": "Protection du compte",
"admin-relogin-duration": "Admin relogin duration (minutes)",
"admin-relogin-duration-help": "After a set amount of time accessing the admin section will require re-login, set to 0 to disable",
"admin-relogin-duration": "Temps de reconnexion pour le compte administrateur (en minutes)",
"admin-relogin-duration-help": "Après un certain temps, l'accessibilité à la section d'administration nécessitera une reconnexion ; fixer le nombre à 0 pour désactiver cet effet.",
"login-attempts": "Tentatives de connexions par heure",
"login-attempts-help": "Si le nombre de tentatives de connexion à un compte dépasse ce seuil, le compte sera bloqué pour une durée pré-configurée",
"lockout-duration": "Durée du blocage (minutes)",

@ -30,7 +30,7 @@
"notif.chat.unsub.info": "Cette notification de chat a été envoyé en raison de vos paramètres d'abonnement.",
"notif.post.cta": "Cliquer ici pour lire le sujet complet",
"notif.post.unsub.info": "La notification de ce message vous a été envoyé en raison de vos paramètres d'abonnement.",
"notif.cta": "Click here to go to forum",
"notif.cta": "Cliquez ici pour accéder au forum",
"test.text1": "Ceci est un e-mail de test pour vérifier que l'e-mailer est correctement configuré pour NodeBB.",
"unsub.cta": "Cliquez ici pour modifier ces paramètres",
"banned.subject": "Vous avez été banni de %1",

@ -125,7 +125,7 @@
"parse-error": "Une erreur est survenue en analysant la réponse du serveur",
"wrong-login-type-email": "Veuillez utiliser votre adresse email pour vous connecter",
"wrong-login-type-username": "Veuillez utiliser votre identifiant pour vous connecter",
"sso-registration-disabled": "Registration has been disabled for %1 accounts, please register with an email address first",
"sso-registration-disabled": "L'enregistrement a été désactivé pour les comptes %1, s'il vous plaît, enregistrez vous avec un adresse mail en premier",
"invite-maximum-met": "Vous avez invité la quantité maximale de personnes (%1 de %2).",
"no-session-found": "Pas de session de connexion trouvé!",
"not-in-room": "L'utilisateur n'est pas dans cette salle",
@ -135,5 +135,5 @@
"invalid-home-page-route": "Route de page d'accueil invalide",
"invalid-session": "Session Interrompue",
"invalid-session-text": "Il semble que votre session ne soit plus active, ou que le serveur ne la reconnaisse plus. Merci de rafraichir cette page.",
"no-topics-selected": "No topics selected!"
"no-topics-selected": "Aucun sujet sélectionné !"
}

@ -9,7 +9,7 @@
"continue_to": "Continuer vers %1",
"return_to": "Revenir à %1",
"new_notification": "Nouvelle notification",
"new_notification_from": "You have a new Notification from %1",
"new_notification_from": "Vous avez une nouvelle notification de %1",
"you_have_unread_notifications": "Vous avez des notifications non-lues",
"all": "Tout",
"topics": "Sujets",
@ -47,18 +47,18 @@
"email-confirmed-message": "Merci pour la validation de votre adresse email. Votre compte est désormais activé.",
"email-confirm-error-message": "Il y a un un problème dans la vérification de votre adresse email. Le code est peut être invalide ou a expiré.",
"email-confirm-sent": "Email de vérification envoyé.",
"none": "None",
"notification_only": "Notification Only",
"email_only": "Email Only",
"notification_and_email": "Notification & Email",
"notificationType_upvote": "When someone upvotes your post",
"notificationType_new-topic": "When someone you follow posts a topic",
"notificationType_new-reply": "When a new reply is posted in a topic you are watching",
"notificationType_follow": "When someone starts following you",
"notificationType_new-chat": "When you receive a chat message",
"notificationType_group-invite": "When you receive a group invite",
"notificationType_new-register": "When someone gets added to registration queue",
"notificationType_post-queue": "When a new post is queued",
"notificationType_new-post-flag": "When a post is flagged",
"notificationType_new-user-flag": "When a user is flagged"
"none": "aucun",
"notification_only": "Seulement une notification",
"email_only": "Seulement un email",
"notification_and_email": "Notification et email",
"notificationType_upvote": "Lorsque quelqu'un a voté pour un de vos messages",
"notificationType_new-topic": "Lorsque quelqu'un que vous suivez publie un sujet",
"notificationType_new-reply": "Lorsqu'une nouvelle réponse est ajoutée dans un sujet que vous suivez",
"notificationType_follow": "Lorsque quelqu'un commence à vous suivre",
"notificationType_new-chat": "Lorsque vous recevez un message du chat ",
"notificationType_group-invite": "Lorsque vous recevez une invitation d'un groupe",
"notificationType_new-register": "Lorsque quelqu'un est ajouté à la file d'attente d'inscription",
"notificationType_post-queue": "Lorsque un nouveau message est mis en file d'attente",
"notificationType_new-post-flag": "Lorsque un message est marqué",
"notificationType_new-user-flag": "Lorsque un utilisateur est marqué"
}

@ -52,7 +52,7 @@
"not-watching.description": "Ne pas me notifier les nouvelles réponses.<br/>Afficher le sujet dans l'onglet \"Non lu\" si la catégorie n'est pas ignorée.",
"ignoring.description": "Ne pas me notifier les nouvelle réponses.<br/>Ne pas afficher ce sujet dans l'onglet \"Non lu\".",
"thread_tools.title": "Outils pour sujets",
"thread_tools.markAsUnreadForAll": "Marquer tous comme non-lus",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Épingler le sujet",
"thread_tools.unpin": "Désépingler le sujet",
"thread_tools.lock": "Verrouiller le sujet",
@ -68,8 +68,8 @@
"thread_tools.restore_confirm": "Êtes-vous sûr de bien vouloir restaurer ce sujet ?",
"thread_tools.purge": "Supprimer définitivement le(s) sujet(s)",
"thread_tools.purge_confirm": "Êtes-vous sûr de bien vouloir supprimer définitivement ce sujet ?",
"thread_tools.merge_topics": "Merge Topics",
"thread_tools.merge": "Merge",
"thread_tools.merge_topics": "Fusionner les Sujets",
"thread_tools.merge": "Fusionner",
"topic_move_success": "Ce sujet a bien été déplacé vers %1.",
"post_delete_confirm": "Êtes-vous sûr de bien vouloir supprimer ce message ?",
"post_restore_confirm": "Êtes-vous sûr de bien vouloir restaurer ce message ?",
@ -91,7 +91,7 @@
"fork_pid_count": "%1 message(s) sélectionné(s)",
"fork_success": "Sujet copié avec succès ! Cliquez ici pour aller au sujet copié.",
"delete_posts_instruction": "Sélectionnez les messages que vous souhaitez supprimer/vider",
"merge_topics_instruction": "Click the topics you want to merge",
"merge_topics_instruction": "Cliquez sur les sujets que vous voulez fusionner",
"composer.title_placeholder": "Entrer le titre du sujet ici…",
"composer.handle_placeholder": "Nom",
"composer.discard": "Abandonner",

@ -52,7 +52,7 @@
"not-watching.description": "Non me notifiquedes as novas respostas. <br/>Amosa-lo fío en non lidos se a categoría non está ignorada.",
"ignoring.description": "Non me notifiquedes as novas respostas. <br/>Non amosa-lo fío en non lidos.",
"thread_tools.title": "Ferramentas do tema",
"thread_tools.markAsUnreadForAll": "Marcar todo como non lido",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Fixar Tema",
"thread_tools.unpin": "Despegar Tema",
"thread_tools.lock": "Pechar Tema",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "כלי נושא",
"thread_tools.markAsUnreadForAll": "סמן הכל כלא נקרא",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "נעץ נושא",
"thread_tools.unpin": "הסר נעץ",
"thread_tools.lock": "נעל נושא",

@ -52,7 +52,7 @@
"not-watching.description": "Ne obaviještavaj me o novim odgovorima.<br/>Prikaži temu u nepročitanim ako kategorija nije ignorirana.",
"ignoring.description": "Nemoj slati obavijesti o novim odgovorima.<br/>Ne prikazuj temu u nepročitanom.",
"thread_tools.title": "Alati teme",
"thread_tools.markAsUnreadForAll": "Označi kao nepročitano za sve",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Zakači temu",
"thread_tools.unpin": "Otkači temu",
"thread_tools.lock": "Zaključaj temu",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Topic Tools",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Kiemel",
"thread_tools.unpin": "Kiemelés megszűntetése",
"thread_tools.lock": "Topik lezárása",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Perangkat Topik",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Tempel Topik",
"thread_tools.unpin": "Copot Topik",
"thread_tools.lock": "Kunci Topik",

@ -52,7 +52,7 @@
"not-watching.description": "Non notificarmi sulle nuove risposte.<br/>Mostra la discussione fra le non lette se la categoria non è ignorata.",
"ignoring.description": "Non notificarmi sulle nuove risposte.<br/>Non mostrare la discussione fra le non lette.",
"thread_tools.title": "Strumenti per la Discussione",
"thread_tools.markAsUnreadForAll": "Segna tutti come non letti",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Fissa Discussione",
"thread_tools.unpin": "Sblocca Discussione",
"thread_tools.lock": "Blocca Discussione",

@ -52,7 +52,7 @@
"not-watching.description": "新しく返信通知を受け取らない。<br/>カテゴリが無視されていない場合、未読のスレッドを表示します。",
"ignoring.description": "新しく返信通知を受け取らない。<br/>未読のスレッドは表示されません。",
"thread_tools.title": "スレッドツール",
"thread_tools.markAsUnreadForAll": "すべて未読にマーク",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "スレッドを最上部に固定",
"thread_tools.unpin": "スレッドの固定を解除",
"thread_tools.lock": "スレッドをロック",

@ -52,7 +52,7 @@
"not-watching.description": "새로운 답글에 대해 알림 받지 않기. 해당 게시판을 팔로우 중이라면 \"읽지않은 게시물\" 에서 보여주기.",
"ignoring.description": "새로운 답글에 대한 알림 받지 않기. \"읽지않은 게시물\"에서 보여주지 않기.",
"thread_tools.title": "게시물 관리",
"thread_tools.markAsUnreadForAll": "모든 사용자에게 읽지 않음으로 표시",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "상단 고정",
"thread_tools.unpin": "상단 고정 해제",
"thread_tools.lock": "잠금",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Temos priemonės",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Prisegti temą",
"thread_tools.unpin": "Atsegti temą",
"thread_tools.lock": "Užrakinti temą",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Perkakas Topik",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Pinkan topik",
"thread_tools.unpin": "Batalkan pin topik",
"thread_tools.lock": "Kunci topik",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Emneverktøy",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Fest tråd",
"thread_tools.unpin": "Ufest tråd",
"thread_tools.lock": "Lås tråd",

@ -1,64 +1,64 @@
{
"state": "State",
"reporter": "Reporter",
"reported-at": "Reported At",
"description": "Description",
"state": "Status",
"reporter": "Rapporteur",
"reported-at": "Gerapporteerd op",
"description": "Beschrijving",
"no-flags": "Hooray! No flags found.",
"assignee": "Assignee",
"update": "Update",
"updated": "Updated",
"assignee": "Toegekend aan",
"update": "Bijwerken",
"updated": "Bijgewerkt",
"target-purged": "The content this flag referred to has been purged and is no longer available.",
"quick-filters": "Quick Filters",
"filter-active": "There are one or more filters active in this list of flags",
"filter-reset": "Remove Filters",
"filters": "Filter Options",
"filter-reporterId": "Reporter UID",
"filter-active": "Er zijn een of meer filters actief in deze lijst van markeringen",
"filter-reset": "Filters verwijderen",
"filters": "Filter opties",
"filter-reporterId": "Rapporteur UID",
"filter-targetUid": "Flagged UID",
"filter-type": "Flag Type",
"filter-type-all": "All Content",
"filter-type-post": "Post",
"filter-state": "State",
"filter-type-all": "Alle inhoud",
"filter-type-post": "Bericht",
"filter-state": "Status",
"filter-assignee": "Assignee UID",
"filter-cid": "Category",
"filter-quick-mine": "Assigned to me",
"filter-cid-all": "All categories",
"apply-filters": "Apply Filters",
"filter-cid": "Categorie",
"filter-quick-mine": "Toegewezen aan mij",
"filter-cid-all": "Alle categorieën",
"apply-filters": "Filters toepassen",
"quick-links": "Quick Links",
"flagged-user": "Flagged User",
"view-profile": "View Profile",
"start-new-chat": "Start New Chat",
"view-profile": "Profiel bekijken",
"start-new-chat": "Begin een nieuwe chat",
"go-to-target": "View Flag Target",
"user-view": "View Profile",
"user-edit": "Edit Profile",
"user-view": "Profiel bekijken",
"user-edit": "Profiel wijzigen",
"notes": "Flag Notes",
"add-note": "Add Note",
"no-notes": "No shared notes.",
"add-note": "Notitie toevoegen",
"no-notes": "Geen gedeelde notities",
"history": "Flag History",
"back": "Back to Flags List",
"no-history": "No flag history.",
"state-all": "All states",
"state-open": "New/Open",
"state-wip": "Work in Progress",
"state-resolved": "Resolved",
"state-rejected": "Rejected",
"no-assignee": "Not Assigned",
"note-added": "Note Added",
"state-all": "Alle statussen",
"state-open": "Nieuw/Open",
"state-wip": "Wordt aan gewerkt",
"state-resolved": "Opgelost",
"state-rejected": "Afgewezen",
"no-assignee": "Niet toegewezen",
"note-added": "Notitie toegevoegd",
"modal-title": "Report Inappropriate Content",
"modal-title": "Rapporteer ongepaste content",
"modal-body": "Please specify your reason for flagging %1 %2 for review. Alternatively, use one of the quick report buttons if applicable.",
"modal-reason-spam": "Spam",
"modal-reason-offensive": "Offensive",
"modal-reason-other": "Other (specify below)",
"modal-reason-custom": "Reason for reporting this content...",
"modal-submit": "Submit Report",
"modal-reason-offensive": "Aanstootgevend",
"modal-reason-other": "Anders (specificeer onder)",
"modal-reason-custom": "Reden voor het rapporteren van deze content...",
"modal-submit": "Rapport verzenden",
"modal-submit-success": "Content has been flagged for moderation.",
"modal-submit-confirm": "Confirm Submission",
"modal-submit-confirm-text": "You have a custom reason specified already. Are you sure you wish to submit via quick-report?",
"modal-submit-confirm-text-help": "Submitting a quick report will overwrite any custom reasons defined."
"modal-submit-confirm": "Bevestig verzending",
"modal-submit-confirm-text": "U hebt al een aangepaste reden gegegeven. Weet u zeker dat u een wilt verzenden via quick-report?",
"modal-submit-confirm-text-help": "Verzenden van een quick-report overschrijft reeds gedefinieerde aangepaste redenen."
}

@ -52,7 +52,7 @@
"not-watching.description": "Stuur me geen melding van nieuwe reacties.<br/>Toon onderwerp in ongelezen mits de categorie niet genegeerd wordt.",
"ignoring.description": "Stuur me geen melding van nieuwe reacties.<br/>Toon dit onderwerp niet onder de ongelezen onderwerpen.",
"thread_tools.title": "Acties",
"thread_tools.markAsUnreadForAll": "Markeer alles als ongelezen",
"thread_tools.markAsUnreadForAll": "Alles als ongelezen markeren",
"thread_tools.pin": "Onderwerp vastpinnen",
"thread_tools.unpin": "Onderwerp losmaken",
"thread_tools.lock": "Onderwerp sluiten",

@ -126,9 +126,9 @@
"sso.title": "Single Sign-on Services",
"sso.associated": "Geassocieerd met",
"sso.not-associated": "Klik hier om geassocieerd te worden met",
"sso.dissociate": "Dissociate",
"sso.dissociate-confirm-title": "Confirm Dissociation",
"sso.dissociate-confirm": "Are you sure you wish to dissociate your account from %1?",
"sso.dissociate": "Ontkoppelen",
"sso.dissociate-confirm-title": "Bevestig ontkoppeling",
"sso.dissociate-confirm": "Weet u zeker dat u uw account wilt ontkoppelen van %1?",
"info.latest-flags": "Laatste markeringen",
"info.no-flags": "Geen gemarkeerde berichten gevonden",
"info.ban-history": "Recente verban-geschiedenis",

@ -52,7 +52,7 @@
"not-watching.description": "Nie informuj mnie o nowych odpowiedziach<br/> Pokazuj temat w nieprzeczytanych, jeśli kategoria nie jest ignorowana.",
"ignoring.description": "Nie informuj mnie o nowych odpowiedziach.<br/>Nie pokazuj tematu w nieprzeczytanych.",
"thread_tools.title": "Narzędzia tematu",
"thread_tools.markAsUnreadForAll": "Zaznacz wszystkie jako nieprzeczytane",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Przypnij temat",
"thread_tools.unpin": "Odepnij temat",
"thread_tools.lock": "Zablokuj temat",

@ -52,7 +52,7 @@
"not-watching.description": "Não me notificar de novas respostas.<br/>Mostrar tópico em não-lido se a categoria não estiver sendo ignorada.",
"ignoring.description": "Não me notificar de novas respostas.<br/>Não mostrar tópico em não-lido.",
"thread_tools.title": "Ferramentas de Tópico",
"thread_tools.markAsUnreadForAll": "Marcar como não-lido para todos",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Fixar Tópico",
"thread_tools.unpin": "Desfixar Tópico",
"thread_tools.lock": "Trancar Tópico",

@ -52,7 +52,7 @@
"not-watching.description": "Não me notificar de novas respostas.<br/>Mostrar tópico em \"não lidos\" se a categoria não está ignorada.",
"ignoring.description": "Não me notificar de novas respostas.<br/>Não mostrar este tópico em \"não lidos\".",
"thread_tools.title": "Ferramentas de tópicos",
"thread_tools.markAsUnreadForAll": "Marcar todas como não lidas",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Fixar tópico",
"thread_tools.unpin": "Desafixar tópico",
"thread_tools.lock": "Bloquear tópico",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Unelte pentru subiecte",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Pin Subiect",
"thread_tools.unpin": "Unpin Subiect",
"thread_tools.lock": "Închide Subiect",

@ -52,7 +52,7 @@
"not-watching.description": "Не уведомлять меня о новых ответах.<br/>Показать тему в непрочитанных, если категория мной не игнорируется.",
"ignoring.description": "Не уведомлять меня о новых ответах.<br/>Не отображать тему в непрочитанных.",
"thread_tools.title": "Настройки темы",
"thread_tools.markAsUnreadForAll": "Отметить все записи непрочитанными",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Прикрепить тему",
"thread_tools.unpin": "Открепить тему",
"thread_tools.lock": "Закрыть тему",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Ibikoresho by'Ikiganiro",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Zamura Ikiganiro",
"thread_tools.unpin": "Manura Ikiganiro",
"thread_tools.lock": "Fungirana Ikiganiro",

@ -52,7 +52,7 @@
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Topic Tools",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Pone in evidèntzia s'Arresonda",
"thread_tools.unpin": "Boga dae s'Evidèntzia s'Arresonasa",
"thread_tools.lock": "Bloca Arresonada",

@ -52,7 +52,7 @@
"not-watching.description": "Vypnúť upozornenia na nové odpovede.<br/> Zobraziť tému v neprečítaných ak kategória nie je ignorovaná.",
"ignoring.description": "Neupozorňovať na nové upozornenia.<br/>Nezobrazovať témy v neprečítaných.",
"thread_tools.title": "Nástroje témy",
"thread_tools.markAsUnreadForAll": "Označiť všetko ako neprečítané",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Zviditeľniť tému",
"thread_tools.unpin": "Odstrániť zviditeľnenie témy",
"thread_tools.lock": "Uzamknúť tému",

@ -52,7 +52,7 @@
"not-watching.description": "Ne obvesti me o novih odgovorih.<br/>Teme prikaži v Neprebrano le če kategorija ni prezrta.",
"ignoring.description": "Ne obvesti me o novih odgovorih.<br/>Teme ne prikaži v Neprebrano.",
"thread_tools.title": "Orodja teme",
"thread_tools.markAsUnreadForAll": "Označi vse kot neprebrano",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Pripni temo",
"thread_tools.unpin": "Odpni temo",
"thread_tools.lock": "Zakleni temo",

@ -52,7 +52,7 @@
"not-watching.description": "Немој ме обавештавати о новим одговорима.<br/>Прикажи тему у непрочитаним ако категорија није игнорисана.",
"ignoring.description": "Немој ме обавештавати о новим одговорима.<br/>Не приказуј тему у непрочитаним",
"thread_tools.title": "Алатке теме",
"thread_tools.markAsUnreadForAll": "Означи свима као непрочитано",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Закачи тему",
"thread_tools.unpin": "Откачи тему",
"thread_tools.lock": "Закључај тему",

@ -52,7 +52,7 @@
"not-watching.description": "Meddela mig inte om nya svar. <br/> Visa ämne i oläst ifall kategorin är ignorerad.",
"ignoring.description": "Meddela mig inte om nya svar. <br/>Visa inte ämne i oläst.",
"thread_tools.title": "Ämnesverktyg",
"thread_tools.markAsUnreadForAll": "Markera oläst för alla",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Nåla fast ämne",
"thread_tools.unpin": "Lösgör ämne",
"thread_tools.lock": "Lås ämne",

@ -52,7 +52,7 @@
"not-watching.description": "อย่าเตือนฉันเมือมีคำตอบใหม่ <br/> แสดงกระทู้ในรายการที่ยังไม่ได้อ่านหากหมวดหมู่นี้ไม่ได้รับการเมินเฉย",
"ignoring.description": "อย่าเตือนฉันเมื่อมีคำตอบใหม่ <br/>อย่าแสดงกระทู้ในรายการที่ยังไม่ได้อ่าน",
"thread_tools.title": "เครื่องมือช่วยจัดการ Topic",
"thread_tools.markAsUnreadForAll": "มาร์คว่ายังไม่ยังอ่านทั้งหมด",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "ปักหมุดกระทู้",
"thread_tools.unpin": "เลิกปักหมุดกระทู้",
"thread_tools.lock": "ล็อคกระทู้",

@ -52,7 +52,7 @@
"not-watching.description": "Yeni bir ileti geldiğinde bildirme.<br/>Kategori susturulmamışsa okunmamış olarak göster.",
"ignoring.description": "Yeni bir ileti geldiğinde bildirme.<br/>Okunmamış olarak gösterme.",
"thread_tools.title": "Konu Ayarları",
"thread_tools.markAsUnreadForAll": "Hepsini okunmadı olarak işaretle",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Başlığı Sabitle",
"thread_tools.unpin": "Başlığı Sabitleme",
"thread_tools.lock": "Başlığı Kitle",

@ -52,7 +52,7 @@
"not-watching.description": "Не сповіщати мене про нові відповіді.<br/>Показувати тему в непрочитаних якщо категорія не ігнорується.",
"ignoring.description": "Не сповіщати мене про нові відповіді.<br/>Не показувати тему в непрочитаних.",
"thread_tools.title": "Інструменти теми",
"thread_tools.markAsUnreadForAll": "Відмітити всі непрочитаними",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Прикріпити тему",
"thread_tools.unpin": "Відкріпити тему",
"thread_tools.lock": "Заблокувати тему",

@ -52,7 +52,7 @@
"not-watching.description": "Không thông báo tôi các trả lời mới. <br/>Hiển thị mục chưa đọc nếu danh mục bị bỏ qua.",
"ignoring.description": "Không thông báo tôi các trả lời mới. <br/>Không hiển thị các mục chưa đọc.",
"thread_tools.title": "Công cụ",
"thread_tools.markAsUnreadForAll": "Đánh dấu tất cả thành chưa đọc",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "Pin chủ đề",
"thread_tools.unpin": "Bỏ pin chủ đề",
"thread_tools.lock": "Khóa chủ đề",

@ -52,7 +52,7 @@
"not-watching.description": "不要在有新回复时通知我。<br/>如果这个版块未被忽略则在未读主题中显示。",
"ignoring.description": "不要在有新回复时通知我。<br/>不要在未读主题中显示该主题。",
"thread_tools.title": "主题工具",
"thread_tools.markAsUnreadForAll": "标记全部未读",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "置顶主题",
"thread_tools.unpin": "取消置顶主题",
"thread_tools.lock": "锁定主题",

@ -52,7 +52,7 @@
"not-watching.description": "有新的回覆不用通知我。<br/>如果類別不是被忽略的,在未讀頁中顯示主題。",
"ignoring.description": "有新的回覆不用通知我。<br/>在未讀頁中不顯示主題。",
"thread_tools.title": "主題工具箱",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Mark Unread For All",
"thread_tools.pin": "釘選主題",
"thread_tools.unpin": "取消釘選主題",
"thread_tools.lock": "鎖定主題",

@ -217,6 +217,10 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator', 'benchpress'
};
trafficCanvas.width = $(trafficCanvas).parent().width();
data.datasets[0].yAxisID = 'left-y-axis';
data.datasets[1].yAxisID = 'right-y-axis';
graphs.traffic = new Chart(trafficCtx, {
type: 'line',
data: data,
@ -227,9 +231,20 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator', 'benchpress'
},
scales: {
yAxes: [{
id: 'left-y-axis',
ticks: {
beginAtZero: true,
},
type: 'linear',
position: 'left',
}, {
id: 'right-y-axis',
ticks: {
beginAtZero: true,
suggestedMax: 10,
},
type: 'linear',
position: 'right',
}],
},
tooltips: {

@ -107,7 +107,9 @@ app.cacheBuster = null;
};
app.logout = function (e) {
e.preventDefault();
if (e) {
e.preventDefault();
}
$(window).trigger('action:app.logout');
/*

@ -127,11 +127,11 @@
category.children.forEach(function (child) {
if (child && !child.isSection) {
var link = child.link ? child.link : (relative_path + '/category/' + child.slug);
html += '<a href="' + link + '">' +
'<span class="fa-stack fa-lg">' +
'<i style="color:' + child.bgColor + ';" class="fa fa-circle fa-stack-2x"></i>' +
'<i style="color:' + child.color + ';" class="fa fa-stack-1x ' + child.icon + '"></i>' +
'</span><small>' + child.name + '</small></a> ';
html += '<span class="category-children-item pull-left">' +
'<div class="icon pull-left" style="' + generateCategoryBackground(child) + '">' +
'<i class="fa fa-fw ' + child.icon + '"></i>' +
'</div>' +
'<a href="' + link + '"><small>' + child.name + '</small></a></span>';
}
});
html = html ? ('<span class="category-children">' + html + '</span>') : html;

@ -61,6 +61,8 @@ module.exports = function (Categories) {
'topics:tag',
'posts:edit',
'posts:delete',
'posts:upvote',
'posts:downvote',
'topics:delete',
];

@ -6,9 +6,11 @@ var path = require('path');
var packageInstall = require('./package-install');
var dirname = require('./paths').baseDir;
var defaultPackage;
// check to make sure dependencies are installed
try {
fs.readFileSync(path.join(dirname, 'package.json'));
defaultPackage = JSON.parse(fs.readFileSync(path.join(dirname, 'install/package.json'), 'utf8'));
} catch (e) {
if (e.code === 'ENOENT') {
console.warn('package.json not found.');
@ -29,13 +31,24 @@ try {
}
try {
fs.readFileSync(path.join(dirname, 'node_modules/async/package.json'), 'utf8');
fs.readFileSync(path.join(dirname, 'node_modules/commander/package.json'), 'utf8');
fs.readFileSync(path.join(dirname, 'node_modules/colors/package.json'), 'utf8');
fs.readFileSync(path.join(dirname, 'node_modules/nconf/package.json'), 'utf8');
var semver = require('semver');
var checkVersion = function (packageName) {
var version = JSON.parse(fs.readFileSync(path.join(dirname, 'node_modules', packageName, 'package.json'), 'utf8')).version;
if (!semver.satisfies(version, defaultPackage.dependencies[packageName])) {
var e = new TypeError('Incorrect dependency version: ' + packageName);
e.code = 'DEP_WRONG_VERSION';
throw e;
}
};
checkVersion('nconf');
checkVersion('async');
checkVersion('commander');
checkVersion('colors');
} catch (e) {
if (e.code === 'ENOENT') {
console.warn('Dependencies not yet installed.');
if (['ENOENT', 'DEP_WRONG_VERSION', 'MODULE_NOT_FOUND'].indexOf(e.code) !== -1) {
console.warn('Dependencies outdated or not yet installed.');
console.log('Installing them now...\n');
packageInstall.installAll();
@ -241,7 +254,7 @@ program
'When running particular upgrade scripts, options are ignored.',
'By default all options are enabled. Passing any options disables that default.',
'Only package and dependency updates: ' + './nodebb upgrade -mi'.yellow,
'Only database update: ' + './nodebb upgrade -d'.yellow,
'Only database update: ' + './nodebb upgrade -s'.yellow,
].join('\n'));
})
.action(function (scripts, options) {

@ -30,8 +30,6 @@ function updatePackageFile() {
exports.updatePackageFile = updatePackageFile;
function installAll() {
process.stdout.write(' started\n'.green);
var prod = global.env !== 'development';
var command = 'npm install';
try {

@ -23,6 +23,7 @@ var steps = {
install: {
message: 'Bringing base dependencies up to date...',
handler: function (next) {
process.stdout.write(' started\n'.green);
packageInstall.installAll();
next();
},

@ -8,7 +8,7 @@ var topics = require('../topics');
var pagination = require('../pagination');
var helpers = require('./helpers');
var tagsController = {};
var tagsController = module.exports;
tagsController.getTag = function (req, res, next) {
var tag = validator.escape(String(req.params.tag));
@ -33,7 +33,7 @@ tagsController.getTag = function (req, res, next) {
templateData.nextStart = stop + 1;
async.parallel({
topicCount: function (next) {
topics.getTagTopicCount(tag, next);
topics.getTagTopicCount(req.params.tag, next);
},
tids: function (next) {
topics.getTagTids(req.params.tag, start, stop, next);
@ -47,44 +47,41 @@ tagsController.getTag = function (req, res, next) {
topicCount = results.topicCount;
topics.getTopics(results.tids, req.uid, next);
},
], function (err, topics) {
if (err) {
return next(err);
}
res.locals.metaTags = [
{
name: 'title',
content: tag,
},
{
property: 'og:title',
content: tag,
},
];
templateData.topics = topics;
function (topics) {
res.locals.metaTags = [
{
name: 'title',
content: tag,
},
{
property: 'og:title',
content: tag,
},
];
templateData.topics = topics;
var pageCount = Math.max(1, Math.ceil(topicCount / settings.topicsPerPage));
templateData.pagination = pagination.create(page, pageCount);
var pageCount = Math.max(1, Math.ceil(topicCount / settings.topicsPerPage));
templateData.pagination = pagination.create(page, pageCount);
res.render('tag', templateData);
});
res.render('tag', templateData);
},
], next);
};
tagsController.getTags = function (req, res, next) {
topics.getTags(0, 99, function (err, tags) {
if (err) {
return next(err);
}
tags = tags.filter(Boolean);
var data = {
tags: tags,
nextStart: 100,
breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[tags:tags]]' }]),
title: '[[pages:tags]]',
};
res.render('tags', data);
});
async.waterfall([
function (next) {
topics.getTags(0, 99, next);
},
function (tags) {
tags = tags.filter(Boolean);
var data = {
tags: tags,
nextStart: 100,
breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[tags:tags]]' }]),
title: '[[pages:tags]]',
};
res.render('tags', data);
},
], next);
};
module.exports = tagsController;

@ -90,11 +90,11 @@ module.exports = function (Groups) {
return callback(new Error('[[error:group-name-too-long]]'));
}
if (!Groups.isPrivilegeGroup(name) && name.indexOf(':') !== -1) {
if (!Groups.isPrivilegeGroup(name) && name.includes(':')) {
return callback(new Error('[[error:invalid-group-name]]'));
}
if (name.indexOf('/') !== -1 || !utils.slugify(name)) {
if (name.includes('/') || !utils.slugify(name)) {
return callback(new Error('[[error:invalid-group-name]]'));
}

@ -14,6 +14,7 @@ var JS = module.exports;
JS.scripts = {
base: [
'node_modules/promise-polyfill/dist/polyfill.js',
'node_modules/jquery/dist/jquery.js',
'node_modules/socket.io-client/dist/socket.io.js',
'public/vendor/jquery/timeago/jquery.timeago.js',
@ -36,7 +37,6 @@ JS.scripts = {
'public/src/ajaxify.js',
'public/src/overrides.js',
'public/src/widgets.js',
'node_modules/promise-polyfill/promise.js',
],
// files listed below are only available client-side, or are bundled in to reduce # of network requests on cold load

@ -6,6 +6,7 @@ var meta = require('../meta');
var db = require('../database');
var user = require('../user');
var plugins = require('../plugins');
var privileges = require('../privileges');
module.exports = function (Posts) {
var votesInProgress = {};
@ -15,16 +16,27 @@ module.exports = function (Posts) {
return callback(new Error('[[error:reputation-system-disabled]]'));
}
if (voteInProgress(pid, uid)) {
return callback(new Error('[[error:already-voting-for-this-post]]'));
}
async.waterfall([
function (next) {
privileges.posts.can('posts:upvote', pid, uid, next);
},
function (canUpvote, next) {
if (!canUpvote) {
return next(new Error('[[error:no-privileges]]'));
}
putVoteInProgress(pid, uid);
if (voteInProgress(pid, uid)) {
return next(new Error('[[error:already-voting-for-this-post]]'));
}
toggleVote('upvote', pid, uid, function (err, data) {
clearVoteProgress(pid, uid);
callback(err, data);
});
putVoteInProgress(pid, uid);
toggleVote('upvote', pid, uid, function (err, data) {
clearVoteProgress(pid, uid);
next(err, data);
});
},
], callback);
};
Posts.downvote = function (pid, uid, callback) {
@ -36,16 +48,27 @@ module.exports = function (Posts) {
return callback(new Error('[[error:downvoting-disabled]]'));
}
if (voteInProgress(pid, uid)) {
return callback(new Error('[[error:already-voting-for-this-post]]'));
}
async.waterfall([
function (next) {
privileges.posts.can('posts:downvote', pid, uid, next);
},
function (canUpvote, next) {
if (!canUpvote) {
return next(new Error('[[error:no-privileges]]'));
}
putVoteInProgress(pid, uid);
if (voteInProgress(pid, uid)) {
return next(new Error('[[error:already-voting-for-this-post]]'));
}
toggleVote('downvote', pid, uid, function (err, data) {
clearVoteProgress(pid, uid);
callback(err, data);
});
putVoteInProgress(pid, uid);
toggleVote('downvote', pid, uid, function (err, data) {
clearVoteProgress(pid, uid);
next(err, data);
});
},
], callback);
};
Posts.unvote = function (pid, uid, callback) {
@ -106,7 +129,7 @@ module.exports = function (Posts) {
};
function voteInProgress(pid, uid) {
return Array.isArray(votesInProgress[uid]) && votesInProgress[uid].indexOf(parseInt(pid, 10)) !== -1;
return Array.isArray(votesInProgress[uid]) && votesInProgress[uid].includes(parseInt(pid, 10));
}
function putVoteInProgress(pid, uid) {

@ -11,6 +11,8 @@ privileges.privilegeLabels = [
{ name: 'Tag Topics' },
{ name: 'Edit Posts' },
{ name: 'Delete Posts' },
{ name: 'Upvote Posts' },
{ name: 'Downvote Posts' },
{ name: 'Delete Topics' },
{ name: 'Purge' },
{ name: 'Moderate' },
@ -25,6 +27,8 @@ privileges.userPrivilegeList = [
'topics:tag',
'posts:edit',
'posts:delete',
'posts:upvote',
'posts:downvote',
'topics:delete',
'purge',
'moderate',

@ -64,6 +64,9 @@ module.exports = function (Topics) {
'cid:' + topicData.cid + ':uid:' + topicData.uid + ':tids',
], timestamp, topicData.tid, next);
},
function (next) {
db.sortedSetAdd('cid:' + topicData.cid + ':tids:votes', 0, topicData.tid, next);
},
function (next) {
categories.updateRecentTid(topicData.cid, topicData.tid, next);
},

@ -250,6 +250,7 @@ module.exports = function (Topics) {
var topic;
var oldCid;
var cid = data.cid;
async.waterfall([
function (next) {
Topics.exists(tid, next);
@ -258,14 +259,18 @@ module.exports = function (Topics) {
if (!exists) {
return next(new Error('[[error:no-topic]]'));
}
Topics.getTopicFields(tid, ['cid', 'lastposttime', 'pinned', 'deleted', 'postcount'], next);
Topics.getTopicFields(tid, ['cid', 'lastposttime', 'pinned', 'deleted', 'postcount', 'upvotes', 'downvotes'], next);
},
function (topicData, next) {
topic = topicData;
if (parseInt(cid, 10) === parseInt(topic.cid, 10)) {
return next(new Error('[[error:cant-move-topic-to-same-category]]'));
}
db.sortedSetsRemove([
'cid:' + topicData.cid + ':tids',
'cid:' + topicData.cid + ':tids:pinned',
'cid:' + topicData.cid + ':tids:posts',
'cid:' + topicData.cid + ':tids:votes',
'cid:' + topicData.cid + ':tids:lastposttime',
'cid:' + topicData.cid + ':recent_tids',
], tid, next);
@ -285,6 +290,10 @@ module.exports = function (Topics) {
topic.postcount = topic.postcount || 0;
db.sortedSetAdd('cid:' + cid + ':tids:posts', topic.postcount, tid, next);
},
function (next) {
var votes = (parseInt(topic.upvotes, 10) || 0) - (parseInt(topic.downvotes, 10) || 0);
db.sortedSetAdd('cid:' + cid + ':tids:votes', votes, tid, next);
},
], function (err) {
next(err);
});

@ -16,7 +16,7 @@ module.exports = {
var topicData;
async.waterfall([
function (next) {
db.getObjectFields('topic:' + tid, ['mainPid', 'cid'], next);
db.getObjectFields('topic:' + tid, ['mainPid', 'cid', 'pinned'], next);
},
function (_topicData, next) {
topicData = _topicData;
@ -44,7 +44,11 @@ module.exports = {
db.sortedSetAdd('topics:votes', votes, tid, next);
},
function (next) {
db.sortedSetAdd('cid:' + topicData.cid + ':tids:votes', votes, tid, next);
if (parseInt(topicData.pinned, 10) !== 1) {
db.sortedSetAdd('cid:' + topicData.cid + ':tids:votes', votes, tid, next);
} else {
next();
}
},
], function (err) {
next(err);

@ -0,0 +1,53 @@
'use strict';
var async = require('async');
var batch = require('../../batch');
var db = require('../../database');
module.exports = {
name: 'Fix sort by votes for moved topics',
timestamp: Date.UTC(2018, 0, 8),
method: function (callback) {
var progress = this.progress;
batch.processSortedSet('topics:tid', function (tids, next) {
async.eachLimit(tids, 500, function (tid, _next) {
progress.incr();
var topicData;
async.waterfall([
function (next) {
db.getObjectFields('topic:' + tid, ['cid', 'oldCid', 'upvotes', 'downvotes', 'pinned'], next);
},
function (_topicData, next) {
topicData = _topicData;
if (!topicData.cid || !topicData.oldCid) {
return _next();
}
var upvotes = parseInt(topicData.upvotes, 10) || 0;
var downvotes = parseInt(topicData.downvotes, 10) || 0;
var votes = upvotes - downvotes;
async.series([
function (next) {
db.sortedSetRemove('cid:' + topicData.oldCid + ':tids:votes', tid, next);
},
function (next) {
if (parseInt(topicData.pinned, 10) !== 1) {
db.sortedSetAdd('cid:' + topicData.cid + ':tids:votes', votes, tid, next);
} else {
next();
}
},
], function (err) {
next(err);
});
},
], _next);
}, next);
}, {
progress: progress,
batch: 500,
}, callback);
},
};

@ -0,0 +1,22 @@
'use strict';
var async = require('async');
var privileges = require('../../privileges');
var db = require('../../database');
module.exports = {
name: 'Give vote privilege to registered-users on all categories',
timestamp: Date.UTC(2018, 0, 9),
method: function (callback) {
db.getSortedSetRange('categories:cid', 0, -1, function (err, cids) {
if (err) {
return callback(err);
}
async.eachSeries(cids, function (cid, next) {
privileges.categories.give(['posts:upvote', 'posts:downvote'], cid, 'registered-users', next);
}, callback);
});
},
};

@ -5,7 +5,7 @@
<th class="arrowed" colspan="3">
[[admin/manage/categories:privileges.section-viewing]]
</th>
<th class="arrowed" colspan="6">
<th class="arrowed" colspan="8">
[[admin/manage/categories:privileges.section-posting]]
</th>
<th class="arrowed" colspan="2">
@ -61,7 +61,7 @@
<th class="arrowed" colspan="3">
[[admin/manage/categories:privileges.section-viewing]]
</th>
<th class="arrowed" colspan="6">
<th class="arrowed" colspan="8">
[[admin/manage/categories:privileges.section-posting]]
</th>
<th class="arrowed" colspan="2">

@ -651,6 +651,8 @@ describe('Categories', function () {
'topics:tag': false,
'topics:delete': false,
'posts:edit': false,
'posts:upvote': false,
'posts:downvote': false,
purge: false,
moderate: false,
});
@ -678,6 +680,8 @@ describe('Categories', function () {
assert.deepEqual(data, {
'groups:find': true,
'groups:posts:edit': true,
'groups:posts:upvote': true,
'groups:posts:downvote': true,
'groups:topics:delete': false,
'groups:topics:create': true,
'groups:topics:reply': true,

@ -112,6 +112,7 @@ describe('emailer', function () {
Meta.configs.setMultiple({
'email:smtpTransport:enabled': '1',
'email:smtpTransport:user': username,
'email:smtpTransport:pass': 'anything',
'email:smtpTransport:service': 'nodebb-custom-smtp',
'email:smtpTransport:port': 4000,
'email:smtpTransport:host': 'localhost',

@ -72,6 +72,22 @@ describe('Post\'s', function () {
});
describe('voting', function () {
it('should fail to upvote post if group does not have upvote permission', function (done) {
privileges.categories.rescind(['posts:upvote', 'posts:downvote'], cid, 'registered-users', function (err) {
assert.ifError(err);
socketPosts.upvote({ uid: voterUid }, { pid: postData.pid, room_id: 'topic_1' }, function (err) {
assert.equal(err.message, '[[error:no-privileges]]');
socketPosts.downvote({ uid: voterUid }, { pid: postData.pid, room_id: 'topic_1' }, function (err) {
assert.equal(err.message, '[[error:no-privileges]]');
privileges.categories.give(['posts:upvote', 'posts:downvote'], cid, 'registered-users', function (err) {
assert.ifError(err);
done();
});
});
});
});
});
it('should upvote a post', function (done) {
socketPosts.upvote({ uid: voterUid }, { pid: postData.pid, room_id: 'topic_1' }, function (err, result) {
assert.ifError(err);

@ -87,7 +87,7 @@ describe('helpers', function () {
],
};
var html = helpers.generateChildrenCategories(category);
assert.equal(html, '<span class="category-children"><a href="' + nconf.get('relative_path') + '/category/undefined"><span class="fa-stack fa-lg"><i style="color:#ff0000;" class="fa fa-circle fa-stack-2x"></i><i style="color:#00ff00;" class="fa fa-stack-1x undefined"></i></span><small>children</small></a> </span>');
assert.equal(html, '<span class="category-children"><span class="category-children-item pull-left"><div class="icon pull-left" style="background-color: #ff0000; color: #00ff00;"><i class="fa fa-fw undefined"></i></div><a href="' + nconf.get('relative_path') + '/category/undefined"><small>children</small></a></span></span>');
done();
});

Loading…
Cancel
Save