diff --git a/Gemfile b/Gemfile index 5a10c2a103..3f8f8f153b 100644 --- a/Gemfile +++ b/Gemfile @@ -120,6 +120,8 @@ group :test do gem 'fakeweb', '~> 1.3.0', require: false gem 'minitest', require: false gem 'timecop' + # TODO: Remove once we upgrade to Rails 5. + gem 'test_after_commit' end group :test, :development do diff --git a/Gemfile.lock b/Gemfile.lock index deec6ecc55..c89972ca1f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -138,7 +138,7 @@ GEM json (1.8.6) jwt (1.5.2) kgio (2.10.0) - libv8 (5.3.332.38.3) + libv8 (5.3.332.38.5) listen (0.7.3) logster (1.2.7) loofah (2.0.3) @@ -153,7 +153,7 @@ GEM method_source (0.8.2) mime-types (2.99.2) mini_portile2 (2.1.0) - mini_racer (0.1.7) + mini_racer (0.1.9) libv8 (~> 5.3) minitest (5.9.1) mocha (1.1.0) @@ -206,7 +206,7 @@ GEM omniauth-twitter (1.3.0) omniauth-oauth (~> 1.1) rack - onebox (1.8.2) + onebox (1.8.3) fast_blank (>= 1.0.0) htmlentities (~> 4.3.4) moneta (~> 0.8) @@ -276,7 +276,7 @@ GEM ffi (>= 1.0.6) msgpack (>= 0.4.3) trollop (>= 1.16.2) - redis (3.3.1) + redis (3.3.3) redis-namespace (1.5.2) redis (~> 3.0, >= 3.0.4) rest-client (1.8.0) @@ -359,6 +359,8 @@ GEM activesupport (>= 4.0) sprockets (>= 3.0.0) stackprof (0.2.10) + test_after_commit (1.1.0) + activerecord (>= 3.2) thor (0.19.1) thread_safe (0.3.5) tilt (2.0.5) @@ -470,6 +472,7 @@ DEPENDENCIES sinatra spork-rails stackprof + test_after_commit thor timecop uglifier @@ -477,4 +480,4 @@ DEPENDENCIES unicorn BUNDLED WITH - 1.14.3 + 1.14.6 diff --git a/app/assets/javascripts/admin/components/admin-directory-toggle.js.es6 b/app/assets/javascripts/admin/components/admin-directory-toggle.js.es6 new file mode 100644 index 0000000000..e4d19613b5 --- /dev/null +++ b/app/assets/javascripts/admin/components/admin-directory-toggle.js.es6 @@ -0,0 +1,33 @@ +import { iconHTML } from 'discourse-common/helpers/fa-icon'; +import { bufferedRender } from 'discourse-common/lib/buffered-render'; + +export default Ember.Component.extend(bufferedRender({ + tagName: 'th', + classNames: ['sortable'], + rerenderTriggers: ['order', 'ascending'], + + buildBuffer(buffer) { + const icon = this.get('icon'); + + if (icon) { + buffer.push(iconHTML(icon)); + } + + buffer.push(I18n.t(this.get('i18nKey'))); + + if (this.get('field') === this.get('order')) { + buffer.push(iconHTML(this.get('ascending') ? 'chevron-up' : 'chevron-down')); + } + }, + + click() { + const currentOrder = this.get('order'); + const field = this.get('field'); + + if (currentOrder === field) { + this.set('ascending', this.get('ascending') ? null : true); + } else { + this.setProperties({ order: field, ascending: null }); + } + } +})); diff --git a/app/assets/javascripts/admin/controllers/admin-groups-type-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-groups-type-index.js.es6 new file mode 100644 index 0000000000..ca80f093d1 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-groups-type-index.js.es6 @@ -0,0 +1,11 @@ +import computed from 'ember-addons/ember-computed-decorators'; + +export default Ember.Controller.extend({ + adminGroupsType: Ember.inject.controller(), + sortedGroups: Ember.computed.alias("adminGroupsType.sortedGroups"), + + @computed("sortedGroups") + messageKey(sortedGroups) { + return `admin.groups.${sortedGroups.length > 0 ? 'none_selected' : 'no_custom_groups'}`; + } +}); diff --git a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 index 1d877dadaf..0d8aec0771 100644 --- a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 @@ -1,9 +1,14 @@ import debounce from 'discourse/lib/debounce'; import { i18n } from 'discourse/lib/computed'; import AdminUser from 'admin/models/admin-user'; +import { observes } from 'ember-addons/ember-computed-decorators'; + export default Ember.Controller.extend({ query: null, + queryParams: ['order', 'ascending'], + order: 'seen', + ascending: null, showEmails: false, refreshing: false, listFilter: null, @@ -39,14 +44,15 @@ export default Ember.Controller.extend({ this._refreshUsers(); }, 250).observes('listFilter'), + + @observes('order', 'ascending') _refreshUsers: function() { - var self = this; this.set('refreshing', true); - AdminUser.findAll(this.get('query'), { filter: this.get('listFilter'), show_emails: this.get('showEmails') }).then(function (result) { - self.set('model', result); - }).finally(function() { - self.set('refreshing', false); + AdminUser.findAll(this.get('query'), { filter: this.get('listFilter'), show_emails: this.get('showEmails'), order: this.get('order'), ascending: this.get('ascending') }).then( (result) => { + this.set('model', result); + }).finally( () => { + this.set('refreshing', false); }); }, diff --git a/app/assets/javascripts/admin/routes/admin-backups.js.es6 b/app/assets/javascripts/admin/routes/admin-backups.js.es6 index 95407e9ff3..6d1a425190 100644 --- a/app/assets/javascripts/admin/routes/admin-backups.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-backups.js.es6 @@ -85,7 +85,7 @@ export default Discourse.Route.extend({ if (confirmed) { Discourse.User.currentProp("hideReadOnlyAlert", true); backup.restore().then(function() { - self.controllerFor("adminBackupsLogs").clear(); + self.controllerFor("adminBackupsLogs").get("logs").clear(); self.controllerFor("adminBackups").set("model.isOperationRunning", true); self.transitionTo("admin.backups.logs"); }); diff --git a/app/assets/javascripts/admin/templates/customize-css-html-show.hbs b/app/assets/javascripts/admin/templates/customize-css-html-show.hbs index 024c670845..6a10c7ae0b 100644 --- a/app/assets/javascripts/admin/templates/customize-css-html-show.hbs +++ b/app/assets/javascripts/admin/templates/customize-css-html-show.hbs @@ -1,7 +1,7 @@
{{text-field class="style-name" value=model.name}} - {{fa-icon "download"}} {{i18n 'admin.export_json.button_text'}} + {{fa-icon "download"}} {{i18n 'admin.export_json.button_text'}}
+ {{plugin-outlet name="web-hook-fields" args=(hash model=model)}} +
{{input type="checkbox" name="verify_certificate" checked=model.verify_certificate}} {{i18n 'admin.web_hooks.verify_certificate'}}
diff --git a/app/assets/javascripts/discourse/components/categories-boxes-with-topics.js.es6 b/app/assets/javascripts/discourse/components/categories-boxes-with-topics.js.es6 new file mode 100644 index 0000000000..b3fb6f8786 --- /dev/null +++ b/app/assets/javascripts/discourse/components/categories-boxes-with-topics.js.es6 @@ -0,0 +1,12 @@ +import computed from 'ember-addons/ember-computed-decorators'; + +export default Ember.Component.extend({ + tagName: "section", + classNameBindings: [':category-boxes-with-topics', 'anyLogos:with-logos:no-logos'], + + @computed('categories.[].uploaded_logo.url') + anyLogos() { + return this.get("categories").any((c) => { return !Ember.isEmpty(c.get('uploaded_logo.url')); }); + return this.get("categories").any(c => !Ember.isEmpty(c.get('uploaded_logo.url'))); + } +}); diff --git a/app/assets/javascripts/discourse/components/categories-boxes.js.es6 b/app/assets/javascripts/discourse/components/categories-boxes.js.es6 new file mode 100644 index 0000000000..fc63667da2 --- /dev/null +++ b/app/assets/javascripts/discourse/components/categories-boxes.js.es6 @@ -0,0 +1,12 @@ +import computed from 'ember-addons/ember-computed-decorators'; + +export default Ember.Component.extend({ + tagName: "section", + classNameBindings: [':category-boxes', 'anyLogos:with-logos:no-logos'], + + @computed('categories.[].uploaded_logo.url') + anyLogos() { + return this.get("categories").any((c) => { return !Ember.isEmpty(c.get('uploaded_logo.url')); }); + return this.get("categories").any(c => !Ember.isEmpty(c.get('uploaded_logo.url'))); + } +}); diff --git a/app/assets/javascripts/discourse/components/cdn-img.js.es6 b/app/assets/javascripts/discourse/components/cdn-img.js.es6 index 007d9cb903..7be0c0b561 100644 --- a/app/assets/javascripts/discourse/components/cdn-img.js.es6 +++ b/app/assets/javascripts/discourse/components/cdn-img.js.es6 @@ -1,8 +1,10 @@ -export default Ember.Component.extend({ - tagName: 'img', - attributeBindings: ['cdnSrc:src'], +import computed from 'ember-addons/ember-computed-decorators'; - cdnSrc: function() { - return Discourse.getURLWithCDN(this.get('src')); - }.property('src') +export default Ember.Component.extend({ + tagName: '', + + @computed('src') + cdnSrc(src) { + return Discourse.getURLWithCDN(src); + } }); diff --git a/app/assets/javascripts/discourse/components/discourse-topic.js.es6 b/app/assets/javascripts/discourse/components/discourse-topic.js.es6 index 17f40f3928..4a578d1f1b 100644 --- a/app/assets/javascripts/discourse/components/discourse-topic.js.es6 +++ b/app/assets/javascripts/discourse/components/discourse-topic.js.es6 @@ -64,6 +64,24 @@ export default Ember.Component.extend(AddArchetypeClass, Scrolling, { this.appEvents.on('post:highlight', postNumber => { Ember.run.scheduleOnce('afterRender', null, highlight, postNumber); }); + + this.appEvents.on('header:update-topic', topic => { + + if (topic === null) { + this._lastShowTopic = false; + this.appEvents.trigger('header:hide-topic'); + return; + } + + const offset = window.pageYOffset || $('html').scrollTop(); + this._lastShowTopic = this.showTopicInHeader(topic, offset); + + if (this._lastShowTopic) { + this.appEvents.trigger('header:show-topic', topic); + } else { + this.appEvents.trigger('header:hide-topic'); + } + }); }, willDestroyElement() { diff --git a/app/assets/javascripts/discourse/components/edit-category-panel.js.es6 b/app/assets/javascripts/discourse/components/edit-category-panel.js.es6 index 5cf7a0e1f8..470dc5237f 100644 --- a/app/assets/javascripts/discourse/components/edit-category-panel.js.es6 +++ b/app/assets/javascripts/discourse/components/edit-category-panel.js.es6 @@ -1,11 +1,10 @@ -const EditCategoryPanel = Ember.Component.extend({ - classNameBindings: [':modal-tab', 'activeTab::invisible'], -}); +const EditCategoryPanel = Ember.Component.extend({}); export default EditCategoryPanel; export function buildCategoryPanel(tab, extras) { return EditCategoryPanel.extend({ - activeTab: Ember.computed.equal('selectedTab', tab) + activeTab: Ember.computed.equal('selectedTab', tab), + classNameBindings: [':modal-tab', 'activeTab::invisible', `:edit-category-tab-${tab}`] }, extras || {}); } diff --git a/app/assets/javascripts/discourse/components/edit-category-settings.js.es6 b/app/assets/javascripts/discourse/components/edit-category-settings.js.es6 index f1b089ac1a..0d5336835a 100644 --- a/app/assets/javascripts/discourse/components/edit-category-settings.js.es6 +++ b/app/assets/javascripts/discourse/components/edit-category-settings.js.es6 @@ -5,9 +5,28 @@ import computed from "ember-addons/ember-computed-decorators"; export default buildCategoryPanel('settings', { emailInEnabled: setting('email_in'), showPositionInput: setting('fixed_category_positions'), - + isParentCategory: Em.computed.empty('category.parent_category_id'), + showSubcategoryListStyle: Em.computed.and('category.show_subcategory_list', 'isParentCategory'), isDefaultSortOrder: Em.computed.empty('category.sort_order'), + @computed + availableSubcategoryListStyles() { + return [ + {name: I18n.t('category.subcategory_list_styles.rows'), value: 'rows'}, + {name: I18n.t('category.subcategory_list_styles.rows_with_featured_topics'), value: 'rows_with_featured_topics'}, + {name: I18n.t('category.subcategory_list_styles.boxes'), value: 'boxes'}, + {name: I18n.t('category.subcategory_list_styles.boxes_with_featured_topics'), value: 'boxes_with_featured_topics'} + ]; + }, + + @computed + availableViews() { + return [ + {name: I18n.t('filters.latest.title'), value: 'latest'}, + {name: I18n.t('filters.top.title'), value: 'top'} + ]; + }, + @computed availableSorts() { return ['likes', 'op_likes', 'views', 'posts', 'activity', 'posters', 'category', 'created'] @@ -21,13 +40,5 @@ export default buildCategoryPanel('settings', { {name: I18n.t('category.sort_ascending'), value: 'true'}, {name: I18n.t('category.sort_descending'), value: 'false'} ]; - }, - - @computed - availableViews() { - return [ - {name: I18n.t('filters.latest.title'), value: 'latest'}, - {name: I18n.t('filters.top.title'), value: 'top'} - ]; } }); diff --git a/app/assets/javascripts/discourse/components/group-membership-button.js.es6 b/app/assets/javascripts/discourse/components/group-membership-button.js.es6 index dba83c69dc..83ad277df2 100644 --- a/app/assets/javascripts/discourse/components/group-membership-button.js.es6 +++ b/app/assets/javascripts/discourse/components/group-membership-button.js.es6 @@ -15,37 +15,32 @@ export default Ember.Component.extend({ @computed("model.is_group_user", "model.id", "groupUserIds") userIsGroupUser(isGroupUser, groupId, groupUserIds) { - if (isGroupUser) { + if (isGroupUser !== undefined) { return isGroupUser; } else { return !!groupUserIds && groupUserIds.includes(groupId); } }, - @computed - joinGroupAction() { - return this.currentUser ? 'joinGroup' : 'showLogin'; - }, - - @computed - requestMembershipAction() { - return this.currentUser ? 'requestMembership' : 'showLogin'; + _showLoginModal() { + this.sendAction('showLogin'); + $.cookie('destination_url', window.location.href); }, actions: { - showLogin() { - this.sendAction('showLogin'); - }, - joinGroup() { - this.set('updatingMembership', true); - const model = this.get('model'); + if (this.currentUser) { + this.set('updatingMembership', true); + const model = this.get('model'); - model.addMembers(this.currentUser.get('username')).then(() => { - model.set('is_group_user', true); - }).catch(popupAjaxError).finally(() => { - this.set('updatingMembership', false); - }); + model.addMembers(this.currentUser.get('username')).then(() => { + model.set('is_group_user', true); + }).catch(popupAjaxError).finally(() => { + this.set('updatingMembership', false); + }); + } else { + this._showLoginModal(); + } }, leaveGroup() { @@ -60,14 +55,18 @@ export default Ember.Component.extend({ }, requestMembership() { - const groupName = this.get('model.name'); + if (this.currentUser) { + const groupName = this.get('model.name'); - Group.loadOwners(groupName).then(result => { - const names = result.map(owner => owner.username).join(","); - const title = I18n.t('groups.request_membership_pm.title'); - const body = I18n.t('groups.request_membership_pm.body', { groupName }); - this.sendAction("createNewMessageViaParams", names, title, body); - }); + Group.loadOwners(groupName).then(result => { + const names = result.map(owner => owner.username).join(","); + const title = I18n.t('groups.request_membership_pm.title'); + const body = I18n.t('groups.request_membership_pm.body', { groupName }); + this.sendAction("createNewMessageViaParams", names, title, body); + }); + } else { + this._showLoginModal(); + } } } }); diff --git a/app/assets/javascripts/discourse/components/search-advanced-options.js.es6 b/app/assets/javascripts/discourse/components/search-advanced-options.js.es6 index 4c658c6358..dd6910d18a 100644 --- a/app/assets/javascripts/discourse/components/search-advanced-options.js.es6 +++ b/app/assets/javascripts/discourse/components/search-advanced-options.js.es6 @@ -14,11 +14,10 @@ const REGEXP_MIN_POST_COUNT_PREFIX = /^min_post_count:/ig; const REGEXP_POST_TIME_PREFIX = /^(before|after):/ig; const REGEXP_TAGS_REPLACE = /(^(tags?:|#(?=[a-z0-9\-]+::tag))|::tag\s?$)/ig; - -const REGEXP_IN_MATCH = /^in:(posted|watching|tracking|bookmarks|first|pinned|unpinned)/ig; +const REGEXP_IN_MATCH = /^in:(posted|watching|tracking|bookmarks|first|pinned|unpinned|wiki|unseen)/ig; const REGEXP_SPECIAL_IN_LIKES_MATCH = /^in:likes/ig; const REGEXP_SPECIAL_IN_PRIVATE_MATCH = /^in:private/ig; -const REGEXP_SPECIAL_IN_WIKI_MATCH = /^in:wiki/ig; +const REGEXP_SPECIAL_IN_SEEN_MATCH = /^in:seen/ig; const REGEXP_CATEGORY_SLUG = /^(\#[a-zA-Z0-9\-:]+)/ig; const REGEXP_CATEGORY_ID = /^(category:[0-9]+)/ig; @@ -28,6 +27,7 @@ export default Em.Component.extend({ classNames: ['search-advanced-options'], inOptions: [ + {name: I18n.t('search.advanced.filters.unseen'), value: "unseen"}, {name: I18n.t('search.advanced.filters.posted'), value: "posted"}, {name: I18n.t('search.advanced.filters.watching'), value: "watching"}, {name: I18n.t('search.advanced.filters.tracking'), value: "tracking"}, @@ -35,6 +35,7 @@ export default Em.Component.extend({ {name: I18n.t('search.advanced.filters.first'), value: "first"}, {name: I18n.t('search.advanced.filters.pinned'), value: "pinned"}, {name: I18n.t('search.advanced.filters.unpinned'), value: "unpinned"}, + {name: I18n.t('search.advanced.filters.wiki'), value: "wiki"}, ], statusOptions: [ {name: I18n.t('search.advanced.statuses.open'), value: "open"}, @@ -75,7 +76,7 @@ export default Em.Component.extend({ in: { likes: false, private: false, - wiki: false + seen: false } }, status: '', @@ -102,7 +103,7 @@ export default Em.Component.extend({ this.setSearchedTermValue('searchedTerms.in', REGEXP_IN_PREFIX, REGEXP_IN_MATCH); this.setSearchedTermSpecialInValue('searchedTerms.special.in.likes', REGEXP_SPECIAL_IN_LIKES_MATCH); this.setSearchedTermSpecialInValue('searchedTerms.special.in.private', REGEXP_SPECIAL_IN_PRIVATE_MATCH); - this.setSearchedTermSpecialInValue('searchedTerms.special.in.wiki', REGEXP_SPECIAL_IN_WIKI_MATCH); + this.setSearchedTermSpecialInValue('searchedTerms.special.in.seen', REGEXP_SPECIAL_IN_SEEN_MATCH); this.setSearchedTermValue('searchedTerms.status', REGEXP_STATUS_PREFIX); this.setSearchedTermValueForPostTime(); this.setSearchedTermValue('searchedTerms.min_post_count', REGEXP_MIN_POST_COUNT_PREFIX); @@ -438,15 +439,15 @@ export default Em.Component.extend({ } }, - @observes('searchedTerms.special.in.wiki') - updateSearchTermForSpecialInWiki() { - const match = this.filterBlocks(REGEXP_SPECIAL_IN_WIKI_MATCH); - const inFilter = this.get('searchedTerms.special.in.wiki'); + @observes('searchedTerms.special.in.seen') + updateSearchTermForSpecialInSeen() { + const match = this.filterBlocks(REGEXP_SPECIAL_IN_SEEN_MATCH); + const inFilter = this.get('searchedTerms.special.in.seen'); let searchTerm = this.get('searchTerm') || ''; if (inFilter) { if (match.length === 0) { - searchTerm += ` in:wiki`; + searchTerm += ` in:seen`; this.set('searchTerm', searchTerm.trim()); } } else if (match.length !== 0) { diff --git a/app/assets/javascripts/discourse/components/user-card-contents.js.es6 b/app/assets/javascripts/discourse/components/user-card-contents.js.es6 index 7585cbd693..6aefcaa2f2 100644 --- a/app/assets/javascripts/discourse/components/user-card-contents.js.es6 +++ b/app/assets/javascripts/discourse/components/user-card-contents.js.es6 @@ -116,7 +116,6 @@ export default Ember.Component.extend(CleansUp, { const args = { stats: false }; args.include_post_count_for = this.get('topic.id'); - args.skip_track_visit = true; User.findByUsername(username, args).then(user => { if (user.topic_post_count) { diff --git a/app/assets/javascripts/discourse/controllers/discovery/categories.js.es6 b/app/assets/javascripts/discourse/controllers/discovery/categories.js.es6 index 19d6ae6b80..3cc8acc692 100644 --- a/app/assets/javascripts/discourse/controllers/discovery/categories.js.es6 +++ b/app/assets/javascripts/discourse/controllers/discovery/categories.js.es6 @@ -1,6 +1,13 @@ import computed from 'ember-addons/ember-computed-decorators'; import DiscoveryController from 'discourse/controllers/discovery'; +const subcategoryStyleComponentNames = { + 'rows': 'categories_only', + 'rows_with_featured_topics': 'categories_with_featured_topics', + 'boxes': 'categories_boxes', + 'boxes_with_featured_topics': 'categories_boxes_with_topics' +}; + export default DiscoveryController.extend({ discovery: Ember.inject.controller(), @@ -19,7 +26,12 @@ export default DiscoveryController.extend({ @computed("model.parentCategory") categoryPageStyle(parentCategory) { - const style = this.siteSettings.desktop_category_page_style; + let style = this.siteSettings.desktop_category_page_style; + + if (parentCategory) { + style = subcategoryStyleComponentNames[parentCategory.get('subcategory_list_style')] || style; + } + const componentName = (parentCategory && style === "categories_and_latest_topics") ? "categories_only" : style; diff --git a/app/assets/javascripts/discourse/controllers/edit-category.js.es6 b/app/assets/javascripts/discourse/controllers/edit-category.js.es6 index cdc773d592..e05c37937b 100644 --- a/app/assets/javascripts/discourse/controllers/edit-category.js.es6 +++ b/app/assets/javascripts/discourse/controllers/edit-category.js.es6 @@ -8,6 +8,7 @@ export default Ember.Controller.extend(ModalFunctionality, { saving: false, deleting: false, panels: null, + hiddenTooltip: true, _initPanels: function() { this.set('panels', []); @@ -16,6 +17,7 @@ export default Ember.Controller.extend(ModalFunctionality, { onShow() { this.changeSize(); this.titleChanged(); + this.set('hiddenTooltip', true); }, changeSize: function() { @@ -101,6 +103,10 @@ export default Ember.Controller.extend(ModalFunctionality, { self.set('deleting', false); } }); + }, + + toggleDeleteTooltip() { + this.toggleProperty('hiddenTooltip'); } } diff --git a/app/assets/javascripts/discourse/controllers/group.js.es6 b/app/assets/javascripts/discourse/controllers/group.js.es6 index 126f8911dc..07fc0ab8c1 100644 --- a/app/assets/javascripts/discourse/controllers/group.js.es6 +++ b/app/assets/javascripts/discourse/controllers/group.js.es6 @@ -53,18 +53,18 @@ export default Ember.Controller.extend({ this.get('tabs')[0].set('count', this.get('model.user_count')); }, - @computed('model.is_group_user', 'model.is_group_owner', 'model.automatic') - getTabs(isGroupUser, isGroupOwner, automatic) { + @computed('model.is_group_owner', 'model.automatic') + getTabs() { return this.get('tabs').filter(t => { - let display = true; + let canSee = true; - if (this.currentUser && t.get('requiresGroupAdmin')) { - display = automatic ? false : (this.currentUser.admin || isGroupOwner); - } else if (t.get('requiresGroupAdmin')) { - display = false; + if (this.currentUser && t.requiresGroupAdmin) { + canSee = this.currentUser.canManageGroup(this.get('model')); + } else if (t.requiresGroupAdmin) { + canSee = false; } - return display; + return canSee; }); } }); diff --git a/app/assets/javascripts/discourse/controllers/raw-email.js.es6 b/app/assets/javascripts/discourse/controllers/raw-email.js.es6 index 29ea5adc28..d197c2c08e 100644 --- a/app/assets/javascripts/discourse/controllers/raw-email.js.es6 +++ b/app/assets/javascripts/discourse/controllers/raw-email.js.es6 @@ -5,15 +5,39 @@ import IncomingEmail from 'admin/models/incoming-email'; // This controller handles displaying of raw email export default Ember.Controller.extend(ModalFunctionality, { rawEmail: "", + textPart: "", + htmlPart: "", + + tab: "raw", + + showRawEmail: Ember.computed.equal("tab", "raw"), + showTextPart: Ember.computed.equal("tab", "text_part"), + showHtmlPart: Ember.computed.equal("tab", "html_part"), + + onShow() { this.send("displayRaw"); }, loadRawEmail(postId) { return Post.loadRawEmail(postId) - .then(result => this.set("rawEmail", result.raw_email)); + .then(result => this.setProperties({ + "rawEmail": result.raw_email, + "textPart": result.text_part, + "htmlPart": result.html_part, + })); }, loadIncomingRawEmail(incomingEmailId) { return IncomingEmail.loadRawEmail(incomingEmailId) - .then(result => this.set("rawEmail", result.raw_email)); + .then(result => this.setProperties({ + "rawEmail": result.raw_email, + "textPart": result.text_part, + "htmlPart": result.html_part, + })); + }, + + actions: { + displayRaw() { this.set("tab", "raw"); }, + displayTextPart() { this.set("tab", "text_part"); }, + displayHtmlPart() { this.set("tab", "html_part"); } } }); diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index 17996c23ef..26f8fb941f 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -913,7 +913,7 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { if (data.reload_topic) { topic.reload().then(() => { this.send('postChangedRoute', topic.get('post_number') || 1); - this.appEvents.trigger('header:show-topic', topic); + this.appEvents.trigger('header:update-topic', topic); }); } else { if (topic.get('isPrivateMessage') && diff --git a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 index e8723b6af1..8efabdb327 100644 --- a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 +++ b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 @@ -10,13 +10,9 @@ export default { after: 'message-bus', initialize(container) { - const user = container.lookup('current-user:main'), - site = container.lookup('site:main'), - siteSettings = container.lookup('site-settings:main'), - bus = container.lookup('message-bus:main'), - keyValueStore = container.lookup('key-value-store:main'), - store = container.lookup('store:main'), - appEvents = container.lookup('app-events:main'); + const user = container.lookup('current-user:main'); + const keyValueStore = container.lookup('key-value-store:main'); + const bus = container.lookup('message-bus:main'); // clear old cached notifications, we used to store in local storage // TODO 2017 delete this line @@ -36,12 +32,17 @@ export default { } bus.subscribe(`/notification/${user.get('id')}`, data => { + const store = container.lookup('store:main'); + const appEvents = container.lookup('app-events:main'); + const oldUnread = user.get('unread_notifications'); const oldPM = user.get('unread_private_messages'); - user.set('unread_notifications', data.unread_notifications); - user.set('unread_private_messages', data.unread_private_messages); - user.set('read_first_notification', data.read_first_notification); + user.setProperties({ + unread_notifications: data.unread_notifications, + unread_private_messages: data.unread_private_messages, + read_first_notification: data.read_first_notification + }); if (oldUnread !== data.unread_notifications || oldPM !== data.unread_private_messages) { appEvents.trigger('notifications:changed'); @@ -84,6 +85,9 @@ export default { } }, user.notification_channel_position); + const site = container.lookup('site:main'); + const siteSettings = container.lookup('site-settings:main'); + bus.subscribe("/categories", data => { _.each(data.categories, c => site.updateCategory(c)); _.each(data.deleted_categories, id => site.removeCategory(id)); diff --git a/app/assets/javascripts/discourse/lib/ajax.js.es6 b/app/assets/javascripts/discourse/lib/ajax.js.es6 index 612d161499..98e65ed9c0 100644 --- a/app/assets/javascripts/discourse/lib/ajax.js.es6 +++ b/app/assets/javascripts/discourse/lib/ajax.js.es6 @@ -69,7 +69,7 @@ export function ajax() { args.error = (xhr, textStatus, errorThrown) => { // note: for bad CSRF we don't loop an extra request right away. // this allows us to eliminate the possibility of having a loop. - if (xhr.status === 403 && xhr.responseText === "['BAD CSRF']") { + if (xhr.status === 403 && xhr.responseText === "[\"BAD CSRF\"]") { Discourse.Session.current().set('csrfToken', null); } diff --git a/app/assets/javascripts/discourse/lib/autocomplete.js.es6 b/app/assets/javascripts/discourse/lib/autocomplete.js.es6 index bfaa65d49a..4b49fdc014 100644 --- a/app/assets/javascripts/discourse/lib/autocomplete.js.es6 +++ b/app/assets/javascripts/discourse/lib/autocomplete.js.es6 @@ -261,7 +261,11 @@ export default function(options) { left: "-1000px" }); - me.parent().append(div); + if (options.appendSelector) { + me.parents(options.appendSelector).append(div); + } else { + me.parent().append(div); + } if (!isInput && !options.treatAsTextarea) { vOffset = div.height(); diff --git a/app/assets/javascripts/discourse/lib/click-track.js.es6 b/app/assets/javascripts/discourse/lib/click-track.js.es6 index f5f9119be5..ff9cb9a862 100644 --- a/app/assets/javascripts/discourse/lib/click-track.js.es6 +++ b/app/assets/javascripts/discourse/lib/click-track.js.es6 @@ -46,12 +46,16 @@ export default { // Update badge clicks unless it's our own if (!ownLink) { - var $badge = $('span.badge', $link); + const $badge = $('span.badge', $link); if ($badge.length === 1) { // don't update counts in category badge nor in oneboxes (except when we force it) if (isValidLink($link)) { - var html = $badge.html(); - if (/^\d+$/.test(html)) { $badge.html(parseInt(html, 10) + 1); } + const html = $badge.html(); + const key = `${new Date().toLocaleDateString()}-${postId}-${href}`; + if (/^\d+$/.test(html) && !sessionStorage.getItem(key)) { + sessionStorage.setItem(key, true); + $badge.html(parseInt(html, 10) + 1); + } } } } diff --git a/app/assets/javascripts/discourse/lib/search.js.es6 b/app/assets/javascripts/discourse/lib/search.js.es6 index 7831868230..0824f8edca 100644 --- a/app/assets/javascripts/discourse/lib/search.js.es6 +++ b/app/assets/javascripts/discourse/lib/search.js.es6 @@ -130,14 +130,14 @@ export function isValidSearchTerm(searchTerm) { } }; -export function applySearchAutocomplete($input, siteSettings, appEvents) { +export function applySearchAutocomplete($input, siteSettings, appEvents, options) { const afterComplete = function() { if (appEvents) { appEvents.trigger("search-autocomplete:after-complete"); } }; - $input.autocomplete({ + $input.autocomplete(_.merge({ template: findRawTemplate('category-tag-autocomplete'), key: '#', width: '100%', @@ -153,9 +153,9 @@ export function applySearchAutocomplete($input, siteSettings, appEvents) { return searchCategoryTag(term, siteSettings); }, afterComplete - }); + }, options)); - $input.autocomplete({ + $input.autocomplete(_.merge({ template: findRawTemplate('user-selector-autocomplete'), key: "@", width: '100%', @@ -163,5 +163,5 @@ export function applySearchAutocomplete($input, siteSettings, appEvents) { transformComplete: v => v.username || v.name, dataSource: term => userSearch({ term, includeGroups: true }), afterComplete - }); + }, options)); }; diff --git a/app/assets/javascripts/discourse/models/category.js.es6 b/app/assets/javascripts/discourse/models/category.js.es6 index 1ac1a9ca0c..8550159ddd 100644 --- a/app/assets/javascripts/discourse/models/category.js.es6 +++ b/app/assets/javascripts/discourse/models/category.js.es6 @@ -105,7 +105,8 @@ const Category = RestModel.extend({ topic_featured_link_allowed: this.get('topic_featured_link_allowed'), show_subcategory_list: this.get('show_subcategory_list'), num_featured_topics: this.get('num_featured_topics'), - default_view: this.get('default_view') + default_view: this.get('default_view'), + subcategory_list_style: this.get('subcategory_list_style') }, type: id ? 'PUT' : 'POST' }); diff --git a/app/assets/javascripts/discourse/models/group.js.es6 b/app/assets/javascripts/discourse/models/group.js.es6 index 99c95caf61..7d1ab55e70 100644 --- a/app/assets/javascripts/discourse/models/group.js.es6 +++ b/app/assets/javascripts/discourse/models/group.js.es6 @@ -17,9 +17,10 @@ const Group = RestModel.extend({ return Em.isEmpty(value) ? "" : value; }, - type: function() { - return this.get("automatic") ? "automatic" : "custom"; - }.property("automatic"), + @computed('automatic') + type(automatic) { + return automatic ? "automatic" : "custom"; + }, @computed('user_count') userCountDisplay(userCount) { @@ -93,6 +94,7 @@ const Group = RestModel.extend({ }); }, + @computed('flair_bg_color') flairBackgroundHexColor() { return this.get('flair_bg_color') ? this.get('flair_bg_color').replace(new RegExp("[^0-9a-fA-F]", "g"), "") : null; @@ -224,7 +226,7 @@ Group.reopenClass({ mentionable(name) { return ajax(`/groups/${name}/mentionable`, { data: { name } }); - }, + } }); export default Group; diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6 index d4e24f5af8..5086c54cbc 100644 --- a/app/assets/javascripts/discourse/models/user.js.es6 +++ b/app/assets/javascripts/discourse/models/user.js.es6 @@ -500,8 +500,11 @@ const User = RestModel.extend({ return summary; }); - } + }, + canManageGroup(group) { + return group.get('automatic') ? false : (this.get('admin') || group.get('is_group_owner')); + } }); User.reopenClass(Singleton, { diff --git a/app/assets/javascripts/discourse/routes/group-edit.js.es6 b/app/assets/javascripts/discourse/routes/group-edit.js.es6 index 8608e6ecf3..19b8ec1cae 100644 --- a/app/assets/javascripts/discourse/routes/group-edit.js.es6 +++ b/app/assets/javascripts/discourse/routes/group-edit.js.es6 @@ -7,6 +7,12 @@ export default Ember.Route.extend({ return this.modelFor('group'); }, + afterModel(group) { + if (!this.currentUser || !this.currentUser.canManageGroup(group)) { + this.transitionTo("group.members", group); + } + }, + setupController(controller, model) { this.controllerFor('group-edit').setProperties({ model }); this.controllerFor("group").set("showing", 'edit'); diff --git a/app/assets/javascripts/discourse/templates/components/categories-boxes-with-topics.hbs b/app/assets/javascripts/discourse/templates/components/categories-boxes-with-topics.hbs new file mode 100644 index 0000000000..8d11bffb17 --- /dev/null +++ b/app/assets/javascripts/discourse/templates/components/categories-boxes-with-topics.hbs @@ -0,0 +1,29 @@ +{{#each categories as |c|}} +
+ +
+{{/each}} diff --git a/app/assets/javascripts/discourse/templates/components/categories-boxes.hbs b/app/assets/javascripts/discourse/templates/components/categories-boxes.hbs new file mode 100644 index 0000000000..00ee5fe8ff --- /dev/null +++ b/app/assets/javascripts/discourse/templates/components/categories-boxes.hbs @@ -0,0 +1,16 @@ +{{#each categories as |c|}} +
+ + {{#if c.uploaded_logo.url}} + {{cdn-img src=c.uploaded_logo.url class="logo"}} + {{/if}} + +
+

{{c.name}}

+
+ {{{c.description_excerpt}}} +
+
+
+
+{{/each}} diff --git a/app/assets/javascripts/discourse/templates/components/cdn-img.hbs b/app/assets/javascripts/discourse/templates/components/cdn-img.hbs new file mode 100644 index 0000000000..e4e4459ddb --- /dev/null +++ b/app/assets/javascripts/discourse/templates/components/cdn-img.hbs @@ -0,0 +1,3 @@ +{{#if src}} + +{{/if}} \ No newline at end of file diff --git a/app/assets/javascripts/discourse/templates/components/edit-category-images.hbs b/app/assets/javascripts/discourse/templates/components/edit-category-images.hbs index 02f655c57e..56e2debffd 100644 --- a/app/assets/javascripts/discourse/templates/components/edit-category-images.hbs +++ b/app/assets/javascripts/discourse/templates/components/edit-category-images.hbs @@ -4,7 +4,7 @@ imageId=logoImageId imageUrl=logoImageUrl type="category_logo" - class="no-repeat"}} + class="no-repeat contain-image"}}
diff --git a/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs b/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs index d3e6a73d3a..e12846ea3c 100644 --- a/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs +++ b/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs @@ -19,14 +19,51 @@
-{{#unless category.parent_category_id}} -
+{{#if isParentCategory}} +
-{{/unless}} +{{/if}} + +{{#if showSubcategoryListStyle}} +
+ +
+{{/if}} + +
+ +
+ +
+ +
+ +
{{/if}} -
- -
- -
- -
- {{#if emailInEnabled}}
diff --git a/app/assets/javascripts/discourse/templates/group-index.hbs b/app/assets/javascripts/discourse/templates/group-index.hbs index 86a35b1112..a58ed87a3c 100644 --- a/app/assets/javascripts/discourse/templates/group-index.hbs +++ b/app/assets/javascripts/discourse/templates/group-index.hbs @@ -1,7 +1,3 @@ -{{group-membership-button model=model - createNewMessageViaParams='createNewMessageViaParams' - showLogin='showLogin'}} - {{#if hasMembers}} {{#load-more selector=".group-members tr" action="loadMore"}} diff --git a/app/assets/javascripts/discourse/templates/group.hbs b/app/assets/javascripts/discourse/templates/group.hbs index 571c1813d6..95fcabb36a 100644 --- a/app/assets/javascripts/discourse/templates/group.hbs +++ b/app/assets/javascripts/discourse/templates/group.hbs @@ -29,17 +29,25 @@ {{/if}} - {{#mobile-nav class='group-nav' desktopClass="nav nav-pills" currentPath=application.currentPath}} - {{#each getTabs as |tab|}} -
  • - {{#link-to tab.location model title=tab.message}} - {{#if tab.icon}}{{fa-icon tab.icon}}{{/if}} - {{tab.message}} - {{#if tab.count}}({{tab.count}}){{/if}} - {{/link-to}} -
  • - {{/each}} - {{/mobile-nav}} +
    +
    + {{#mobile-nav class='group-nav' desktopClass="nav nav-pills" currentPath=application.currentPath}} + {{#each getTabs as |tab|}} +
  • + {{#link-to tab.location model title=tab.message}} + {{#if tab.icon}}{{fa-icon tab.icon}}{{/if}} + {{tab.message}} + {{#if tab.count}}({{tab.count}}){{/if}} + {{/link-to}} +
  • + {{/each}} + {{/mobile-nav}} + + {{group-membership-button model=model + createNewMessageViaParams='createNewMessageViaParams' + showLogin='showLogin'}} +
    +
    {{outlet}} diff --git a/app/assets/javascripts/discourse/templates/modal/edit-category.hbs b/app/assets/javascripts/discourse/templates/modal/edit-category.hbs index fbbafa353f..7f6063283d 100644 --- a/app/assets/javascripts/discourse/templates/modal/edit-category.hbs +++ b/app/assets/javascripts/discourse/templates/modal/edit-category.hbs @@ -28,8 +28,16 @@ icon="trash-o" label="category.delete"}} {{else}} -
    - {{{model.cannot_delete_reason}}} +
    + {{d-button disabled=deleteDisabled + class="disable-no-hover" + action="toggleDeleteTooltip" + icon="question-circle" + label="category.delete"}} + +
    + {{{model.cannot_delete_reason}}} +
    {{/if}}
    diff --git a/app/assets/javascripts/discourse/templates/modal/raw-email.hbs b/app/assets/javascripts/discourse/templates/modal/raw-email.hbs index 12667d0143..4a59eef06f 100644 --- a/app/assets/javascripts/discourse/templates/modal/raw-email.hbs +++ b/app/assets/javascripts/discourse/templates/modal/raw-email.hbs @@ -1,7 +1,45 @@ -{{#d-modal-body title="raw_email.title" maxHeight="80%"}} - {{#if rawEmail}} - {{textarea value=rawEmail class="raw-email-textarea"}} - {{else}} - {{i18n 'raw_email.not_available'}} - {{/if}} +{{#d-modal-body title="raw_email.title" class="incoming-email-modal" maxHeight="80%"}} +
    + {{d-button action="displayRaw" + label="post.raw_email.displays.raw.button" + title="post.raw_email.displays.raw.title" + class=(if showRawEmail 'active') + }} + + {{#if textPart}} + {{d-button action="displayTextPart" + label="post.raw_email.displays.text_part.button" + title="post.raw_email.displays.text_part.title" + class=(if showTextPart 'active') + }} + {{/if}} + + {{#if htmlPart}} + {{d-button action="displayHtmlPart" + label="post.raw_email.displays.html_part.button" + title="post.raw_email.displays.html_part.title" + class=(if showHtmlPart 'active') + }} + {{/if}} +
    + +
    + {{#if showRawEmail}} + {{#if rawEmail}} + {{textarea value=rawEmail}} + {{else}} + {{i18n 'raw_email.not_available'}} + {{/if}} + {{/if}} + + {{#if showTextPart}} + {{textarea value=textPart}} + {{/if}} + + {{#if showHtmlPart}} +
    + {{{htmlPart}}} +
    + {{/if}} +
    {{/d-modal-body}} diff --git a/app/assets/javascripts/discourse/templates/preferences.hbs b/app/assets/javascripts/discourse/templates/preferences.hbs index 3f39e111fd..4be554bdf6 100644 --- a/app/assets/javascripts/discourse/templates/preferences.hbs +++ b/app/assets/javascripts/discourse/templates/preferences.hbs @@ -1,5 +1,7 @@ {{#d-section pageClass="user-preferences" class="user-content user-preferences"}} + {{plugin-outlet name="above-user-preferences"}} +
    diff --git a/app/assets/javascripts/discourse/widgets/hamburger-categories.js.es6 b/app/assets/javascripts/discourse/widgets/hamburger-categories.js.es6 index 37bdae69fb..15e3dc9b3f 100644 --- a/app/assets/javascripts/discourse/widgets/hamburger-categories.js.es6 +++ b/app/assets/javascripts/discourse/widgets/hamburger-categories.js.es6 @@ -6,6 +6,12 @@ createWidget('hamburger-category', { tagName: 'li.category-link', html(c) { + if (c.parent_category_id) { + this.tagName += '.subcategory'; + } + + this.tagName += '.category-' + Discourse.Category.slugFor(c, '-'); + const results = [ this.attach('category-link', { category: c, allowUncategorized: true }) ]; const unreadTotal = parseInt(c.get('unreadTopics'), 10) + parseInt(c.get('newTopics'), 10); diff --git a/app/assets/javascripts/discourse/widgets/header.js.es6 b/app/assets/javascripts/discourse/widgets/header.js.es6 index c74dac720f..1f66b5eec6 100644 --- a/app/assets/javascripts/discourse/widgets/header.js.es6 +++ b/app/assets/javascripts/discourse/widgets/header.js.es6 @@ -262,7 +262,10 @@ export default createWidget('header', { Ember.run.schedule('afterRender', () => { const $searchInput = $('#search-term'); $searchInput.focus().select(); - applySearchAutocomplete($searchInput, this.siteSettings, this.appEvents); + + applySearchAutocomplete($searchInput, this.siteSettings, this.appEvents, { + appendSelector: '.menu-panel' + }); }); } }, diff --git a/app/assets/javascripts/discourse/widgets/post-small-action.js.es6 b/app/assets/javascripts/discourse/widgets/post-small-action.js.es6 index 8c59b053d7..b128b246ce 100644 --- a/app/assets/javascripts/discourse/widgets/post-small-action.js.es6 +++ b/app/assets/javascripts/discourse/widgets/post-small-action.js.es6 @@ -16,6 +16,8 @@ const icons = { 'pinned.disabled': 'thumb-tack unpinned', 'pinned_globally.enabled': 'thumb-tack', 'pinned_globally.disabled': 'thumb-tack unpinned', + 'banner.enabled': 'thumb-tack', + 'banner.disabled': 'thumb-tack unpinned', 'visible.enabled': 'eye', 'visible.disabled': 'eye-slash', 'split_topic': 'sign-out', diff --git a/app/assets/javascripts/discourse/widgets/topic-admin-menu.js.es6 b/app/assets/javascripts/discourse/widgets/topic-admin-menu.js.es6 index 5269f44a34..699dd78142 100644 --- a/app/assets/javascripts/discourse/widgets/topic-admin-menu.js.es6 +++ b/app/assets/javascripts/discourse/widgets/topic-admin-menu.js.es6 @@ -137,10 +137,13 @@ export default createWidget('topic-admin-menu', { icon: 'thumb-tack', label: featured ? 'actions.unpin' : 'actions.pin' }); } - buttons.push({ className: 'topic-admin-change-timestamp', - action: 'showChangeTimestamp', - icon: 'calendar', - label: 'change_timestamp.title' }); + + if (this.currentUser.admin) { + buttons.push({ className: 'topic-admin-change-timestamp', + action: 'showChangeTimestamp', + icon: 'calendar', + label: 'change_timestamp.title' }); + } if (!isPrivateMessage) { buttons.push({ className: 'topic-admin-archive', diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss index 13893d7cc2..0e3c536b04 100644 --- a/app/assets/stylesheets/common/admin/admin_base.scss +++ b/app/assets/stylesheets/common/admin/admin_base.scss @@ -31,8 +31,10 @@ $mobile-breakpoint: 700px; width: 100%; tr {text-align: left;} td, th {padding: 8px;} - th {border-top: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);} + th {border-top: 1px solid dark-light-diff($primary, $secondary, 90%, -60%); text-align: left;} td {border-bottom: 1px solid dark-light-diff($primary, $secondary, 90%, -60%); border-top: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);} + th.sortable i.fa-chevron-down, + th.sortable i.fa-chevron-up {margin-left: 0.5em;} tr:hover { background-color: darken($secondary, 2.5%); } tr.selected { background-color: lighten($primary, 80%); } .filters input { margin-bottom: 0; } @@ -696,6 +698,10 @@ section.details { width: 100%; border-color: dark-light-choose(scale-color($primary, $lightness: 75%), scale-color($secondary, $lightness: 25%)); } + + .content-list { + margin-right: 20px; + } } // Customise area diff --git a/app/assets/stylesheets/common/base/modal.scss b/app/assets/stylesheets/common/base/modal.scss index 56198d9e16..3eb8868bfa 100644 --- a/app/assets/stylesheets/common/base/modal.scss +++ b/app/assets/stylesheets/common/base/modal.scss @@ -73,9 +73,6 @@ max-width: 710px; margin: 0 auto; background-color: $secondary; - border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%); - - box-shadow: 0 3px 7px rgba(0,0,0, .8); background-clip: padding-box; } @@ -154,9 +151,6 @@ .warning { color: $danger !important; } - .raw-email-textarea { - height: 300px; - } .json-uploader { .jsfu-shade-container { display: table-row; @@ -328,5 +322,79 @@ .auto-close-fields label { font-size: .929em; } + + .subcategory-list-style-field { + margin-left: 16px; + } + + .edit-category-tab-settings { + section.field { + margin-bottom: 10px; + } + } + + .disable_info_wrap { + position: relative; + display: inline-block; + float: right; + + .cannot_delete_reason { + position: absolute; + background: dark-light-choose(scale-color($primary, $lightness: 10%), scale-color($secondary, $lightness: 10%)); + color: dark-light-choose(scale-color($primary, $lightness: 100%), scale-color($secondary, $lightness: 0%)); + text-align: center; + border-radius: 2px; + padding: 12px 8px; + + &::after { + top: 100%; + left: 57%; + border: solid transparent; + content: " "; + position: absolute; + border-top-color: dark-light-choose(scale-color($primary, $lightness: 10%), scale-color($secondary, $lightness: 10%)); + border-width: 8px; + } + } + } +} + + +.incoming-email-modal { + .btn { + transition: none; + background-color: transparent; + margin-right: 5px; + &:hover, &.active { + color: $primary; + } + &.active { + font-weight: bold; + } + &:focus { + outline: 2px solid dark-light-diff($primary, $secondary, 90%, -60%); + } + } + .incoming-email-tabs { + margin-bottom: 15px; + } + .incoming-email-content { + height: 300px; + textarea, .incoming-email-html-part { + height: 95%; + border: none; + border-top: 1px solid dark-light-diff($primary, $secondary, 90%, -60%); + padding-top: 10px; + } + textarea { + font-family: monospace; + resize: none; + border-radius: 0px; + box-shadow: none; + } + .incoming-email-html-part { + padding: 10px 4px 4px 4px; + } + } } diff --git a/app/assets/stylesheets/common/base/topic-post.scss b/app/assets/stylesheets/common/base/topic-post.scss index 4c82cb4f8e..da4b50c2e6 100644 --- a/app/assets/stylesheets/common/base/topic-post.scss +++ b/app/assets/stylesheets/common/base/topic-post.scss @@ -141,7 +141,7 @@ aside.quote { color: dark-light-choose($secondary, $primary); padding: 10px; z-index: 401; - opacity: 0.8; + opacity: 0.9; &:before { font-family: "FontAwesome"; diff --git a/app/assets/stylesheets/common/base/upload.scss b/app/assets/stylesheets/common/base/upload.scss index 84e29bb14a..dc2a87aa10 100644 --- a/app/assets/stylesheets/common/base/upload.scss +++ b/app/assets/stylesheets/common/base/upload.scss @@ -8,3 +8,9 @@ background-repeat: no-repeat; } } + +.image-uploader.contain-image { + .uploaded-image-preview { + background-size: contain; + } +} diff --git a/app/assets/stylesheets/common/foundation/helpers.scss b/app/assets/stylesheets/common/foundation/helpers.scss index 282255d71e..2b540dca04 100644 --- a/app/assets/stylesheets/common/foundation/helpers.scss +++ b/app/assets/stylesheets/common/foundation/helpers.scss @@ -76,3 +76,11 @@ .clickable { cursor: pointer; } + + +// Buttons +// --------------------------------------------------- +.disable-no-hover:hover { + background: dark-light-choose(scale-color($primary, $lightness: 90%), scale-color($secondary, $lightness: 60%));; + color: $primary; +} diff --git a/app/assets/stylesheets/desktop/category-list.scss b/app/assets/stylesheets/desktop/category-list.scss index d33120135f..43028c62fb 100644 --- a/app/assets/stylesheets/desktop/category-list.scss +++ b/app/assets/stylesheets/desktop/category-list.scss @@ -176,3 +176,126 @@ } } } + +.category-boxes, .category-boxes-with-topics { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + margin-top: 1em; + margin-bottom: 1em; + width: 100%; + + .category-box { + display: flex; + flex-direction: row; + align-content: flex-start; + + box-sizing: border-box; + border: 2px solid blend-primary-secondary(20%); + + .mobile-view & { + width: 100%; + } + + .details { + h3 { + font-size: 1.5em; + margin-bottom: 0.5em; + margin-top: 0.25em; + } + .description { + font-size: 1.05em; + color: dark-light-choose(scale-color($primary, $lightness: 50%), scale-color($secondary, $lightness: 40%)); + } + } + + .logo { + display: block; + height: 40px; + margin: 0 auto 1em auto; + } + } + + &.no-logos { + .logo { + display: none; + } + } +} + +.category-boxes { + .category-box { + width: 23%; + margin: 0 1% 1.5em 1%; + } + .details { + text-align: center; + } + + a { + width: 100%; + padding: 1em; + } + + &.no-logos { + .category-box a { + padding: 3em 1em; + } + } +} + +.category-boxes-with-topics { + .category-box { + width: 31%; + margin: 0 1% 1.5em 1%; + padding: 0; + border-width: 0 0 0 6px; + border-style: solid; + border-color: blend-primary-secondary(20%); + } + .category-box-inner { + width: 100%; + padding: 0; + border-width: 2px 2px 2px 0; + border-style: solid; + border-color: blend-primary-secondary(20%); + } + + h3 { + font-size: 1.2em; + text-align: center; + } + + .category-box-heading { + padding: 1em 1em 0.5em 1em; + a[href] { + width: 100%; + color: $primary; + } + } + + .featured-topics { + padding: 0.5em 1em 1em 1em; + ul { + color: blend-primary-secondary(70%); + list-style: none; + padding: 0; + margin: 0; + } + li { + padding: 0; + margin-left: 1.5em; + .overflow { + max-height: 3em; + overflow: hidden; + text-overflow: ellipsis; + } + } + li:before { + content: '\f0f6'; + font-family: 'FontAwesome'; + float: left; + margin-left: -1.5em; + } + } +} diff --git a/app/assets/stylesheets/desktop/modal.scss b/app/assets/stylesheets/desktop/modal.scss index e35b93fa11..fd82268119 100644 --- a/app/assets/stylesheets/desktop/modal.scss +++ b/app/assets/stylesheets/desktop/modal.scss @@ -117,11 +117,19 @@ } } - .cannot_delete_reason { - float: right; - text-align: right; - max-width: 380px; - color: dark-light-choose(scale-color($primary, $lightness: 60%), scale-color($secondary, $lightness: 40%)); + .disable_info_wrap { + margin-top: -70px; + padding-top: 70px; + @media all and (min-width: 550px) { + padding-left: 170px; + } + + .cannot_delete_reason { + top: 4px; + right: 4px; + max-width: 380px; + min-width: 300px; + } } } diff --git a/app/assets/stylesheets/mobile/group.scss b/app/assets/stylesheets/mobile/group.scss index cfbb849340..ded66e7184 100644 --- a/app/assets/stylesheets/mobile/group.scss +++ b/app/assets/stylesheets/mobile/group.scss @@ -20,6 +20,7 @@ .group-nav.mobile-nav { margin-bottom: 15px; + float: left; } .group-activity { @@ -29,7 +30,7 @@ .group-activity-nav.mobile-nav { position: absolute; right: 0px; - top: -50px; + top: -55px; } .group-activity-outlet { diff --git a/app/assets/stylesheets/mobile/modal.scss b/app/assets/stylesheets/mobile/modal.scss index 13e41e2a25..f94a9facd5 100644 --- a/app/assets/stylesheets/mobile/modal.scss +++ b/app/assets/stylesheets/mobile/modal.scss @@ -38,7 +38,7 @@ width: 95%; } -// we need a little extra room on mobile for the +// we need a little extra room on mobile for the // stuff inside the footer to fit .modal-footer { padding-right: 0; @@ -133,6 +133,12 @@ } } } + + .disable_info_wrap .cannot_delete_reason { + top: -114px; + right: 8px; + min-width: 200px; + } } .tabbed-modal { diff --git a/app/controllers/admin/email_controller.rb b/app/controllers/admin/email_controller.rb index 077937e021..df400de93e 100644 --- a/app/controllers/admin/email_controller.rb +++ b/app/controllers/admin/email_controller.rb @@ -78,7 +78,8 @@ class Admin::EmailController < Admin::AdminController def raw_email params.require(:id) incoming_email = IncomingEmail.find(params[:id].to_i) - render json: { raw_email: incoming_email.raw } + text, html = Email.extract_parts(incoming_email.raw) + render json: { raw_email: incoming_email.raw, text_part: text, html_part: html } end def incoming diff --git a/app/controllers/admin/emojis_controller.rb b/app/controllers/admin/emojis_controller.rb index 37d12df4dd..2674936f6e 100644 --- a/app/controllers/admin/emojis_controller.rb +++ b/app/controllers/admin/emojis_controller.rb @@ -14,25 +14,50 @@ class Admin::EmojisController < Admin::AdminController .gsub(/_{2,}/, '_') .downcase - data = if Emoji.exists?(name) - failed_json.merge(errors: [I18n.t("emoji.errors.name_already_exists", name: name)]) - elsif emoji = Emoji.create_for(file, name) - emoji - else - failed_json.merge(errors: [I18n.t("emoji.errors.error_while_storing_emoji")]) - end + upload = Upload.create_for( + current_user.id, + file.tempfile, + file.original_filename, + File.size(file.tempfile.path), + image_type: 'custom_emoji' + ) + + data = + if upload.persisted? + custom_emoji = CustomEmoji.new(name: name, upload: upload) + + if custom_emoji.save + Emoji.clear_cache + { name: custom_emoji.name, url: custom_emoji.upload.url } + else + failed_json.merge(errors: custom_emoji.errors.full_messages) + end + else + failed_json.merge(errors: upload.errors.full_messages) + end MessageBus.publish("/uploads/emoji", data.as_json, user_ids: [current_user.id]) end - render json: success_json end def destroy name = params.require(:id) - Emoji[name].try(:remove) - render nothing: true + + custom_emoji = CustomEmoji.find_by(name: name) + raise Discourse::InvalidParameters unless custom_emoji + + CustomEmoji.transaction do + custom_emoji.upload.destroy! + custom_emoji.destroy! + end + + Emoji.clear_cache + + Jobs.enqueue(:rebake_custom_emoji_posts, name: name) + + render json: success_json end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0eae8c24ba..eeb1ca1e78 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -29,7 +29,7 @@ class ApplicationController < ActionController::Base unless is_api? || is_user_api? super clear_current_user - render text: "['BAD CSRF']", status: 403 + render text: "[\"BAD CSRF\"]", status: 403 end end @@ -230,8 +230,8 @@ class ApplicationController < ActionController::Base preload_anonymous_data if current_user - preload_current_user_data current_user.sync_notification_channel_position + preload_current_user_data end end diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index d11a8ad57b..71d5e7668a 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -16,10 +16,12 @@ class CategoriesController < ApplicationController @description = SiteSetting.site_description + parent_category = Category.find_by(slug: params[:parent_category_id]) || Category.find_by(id: params[:parent_category_id].to_i) + category_options = { is_homepage: current_homepage == "categories".freeze, parent_category_id: params[:parent_category_id], - include_topics: include_topics + include_topics: include_topics(parent_category) } @category_list = CategoryList.new(guardian, category_options) @@ -57,7 +59,8 @@ class CategoriesController < ApplicationController topic_options = { per_page: SiteSetting.categories_topics, - no_definitions: true + no_definitions: true, + exclude_category_ids: Category.where(suppress_from_homepage: true).pluck(:id) } result = CategoryAndTopicLists.new @@ -245,6 +248,7 @@ class CategoriesController < ApplicationController :show_subcategory_list, :num_featured_topics, :default_view, + :subcategory_list_style, :custom_fields => [params[:custom_fields].try(:keys)], :permissions => [*p.try(:keys)], :allowed_tags => [], @@ -260,9 +264,10 @@ class CategoriesController < ApplicationController @staff_action_logger = StaffActionLogger.new(current_user) end - def include_topics + def include_topics(parent_category=nil) view_context.mobile_view? || params[:include_topics] || + (parent_category && parent_category.subcategory_list_includes_topics?) || SiteSetting.desktop_category_page_style == "categories_with_featured_topics".freeze end end diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb index 431b68f143..91eeeab5b2 100644 --- a/app/controllers/list_controller.rb +++ b/app/controllers/list_controller.rb @@ -46,6 +46,7 @@ class ListController < ApplicationController :parent_category_category_top, # top pages (ie. with a period) TopTopic.periods.map { |p| :"top_#{p}" }, + TopTopic.periods.map { |p| :"top_#{p}_feed" }, TopTopic.periods.map { |p| :"category_top_#{p}" }, TopTopic.periods.map { |p| :"category_none_top_#{p}" }, TopTopic.periods.map { |p| :"parent_category_category_top_#{p}" }, @@ -168,7 +169,7 @@ class ListController < ApplicationController @link = "#{Discourse.base_url}/top" @atom_link = "#{Discourse.base_url}/top.rss" @description = I18n.t("rss_description.top") - @topic_list = TopicQuery.new(nil).list_top_for("monthly") + @topic_list = TopicQuery.new(nil).list_top_for(SiteSetting.top_page_default_timeframe.to_sym) render 'list', formats: [:rss] end @@ -232,7 +233,7 @@ class ListController < ApplicationController list.for_period = period list.more_topics_url = construct_url_with(:next, top_options) list.prev_topics_url = construct_url_with(:prev, top_options) - @rss = "top" + @rss = "top_#{period}" if use_crawler_layout? @title = I18n.t("js.filters.top.#{period}.title") @@ -252,6 +253,19 @@ class ListController < ApplicationController define_method("parent_category_category_top_#{period}") do self.send("top_#{period}", category: @category.id) end + + # rss feed + define_method("top_#{period}_feed") do |options = nil| + discourse_expires_in 1.minute + + @description = I18n.t("rss_description.top_#{period}") + @title = "#{SiteSetting.title} - #{@description}" + @link = "#{Discourse.base_url}/top/#{period}" + @atom_link = "#{Discourse.base_url}/top/#{period}.rss" + @topic_list = TopicQuery.new(nil).list_top_for(period) + + render 'list', formats: [:rss] + end end protected diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 52618c5caf..225b01f1d6 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -109,14 +109,15 @@ class PostsController < ApplicationController end def cooked - post = find_post_from_params - render json: {cooked: post.cooked} + render json: { cooked: find_post_from_params.cooked } end def raw_email + params.require(:id) post = Post.unscoped.find(params[:id].to_i) guardian.ensure_can_view_raw_email!(post) - render json: { raw_email: post.raw_email } + text, html = Email.extract_parts(post.raw_email) + render json: { raw_email: post.raw_email, text_part: text, html_part: html } end def short_link @@ -377,17 +378,19 @@ class PostsController < ApplicationController end def bookmark - post = find_post_from_params - if params[:bookmarked] == "true" + post = find_post_from_params PostAction.act(current_user, post, PostActionType.types[:bookmark]) else + post_action = PostAction.find_by(post_id: params[:post_id], user_id: current_user.id) + post = post_action.post + raise Discourse::InvalidParameters unless post_action + PostAction.remove_act(current_user, post, PostActionType.types[:bookmark]) end - tu = TopicUser.get(post.topic, current_user) - - render_json_dump(topic_bookmarked: tu.try(:bookmarked)) + topic_user = TopicUser.get(post.topic, current_user) + render_json_dump(topic_bookmarked: topic_user.try(:bookmarked)) end def wiki diff --git a/app/controllers/site_controller.rb b/app/controllers/site_controller.rb index dbbeab8e7b..f86e45b969 100644 --- a/app/controllers/site_controller.rb +++ b/app/controllers/site_controller.rb @@ -3,7 +3,7 @@ require_dependency 'site_serializer' class SiteController < ApplicationController layout false skip_before_filter :preload_json, :check_xhr - skip_before_filter :redirect_to_login_if_required, only: ['basic_info'] + skip_before_filter :redirect_to_login_if_required, only: ['basic_info', 'statistics'] def site render json: Site.json_for(guardian) @@ -42,4 +42,9 @@ class SiteController < ApplicationController # this info is always available cause it can be scraped from a 404 page render json: results end + + def statistics + return redirect_to path('/') unless SiteSetting.share_anonymized_statistics? + render json: About.fetch_cached_stats + end end diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index d33adb32ee..7614b30f5d 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -81,7 +81,8 @@ class UploadsController < ApplicationController if filename == "image.png" && SiteSetting.convert_pasted_images_to_hq_jpg jpeg_path = "#{File.dirname(tempfile.path)}/image.jpg" OptimizedImage.ensure_safe_paths!(tempfile.path, jpeg_path) - `convert #{tempfile.path} -quality #{SiteSetting.convert_pasted_images_quality} #{jpeg_path}` + + Discourse::Utils.execute_command('convert', tempfile.path, '-quality', SiteSetting.convert_pasted_images_quality.to_s, jpeg_path) # only change the format of the image when JPG is at least 5% smaller if File.size(jpeg_path) < File.size(tempfile.path) * 0.95 filename = "image.jpg" diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 1d3d315773..0fb1de4e00 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -550,7 +550,13 @@ class UsersController < ApplicationController if Guardian.new(@user).can_access_forum? @user.enqueue_welcome_message('welcome_user') if @user.send_welcome_message log_on_user(@user) - return redirect_to(wizard_path) if Wizard.user_requires_completion?(@user) + + if Wizard.user_requires_completion?(@user) + return redirect_to(wizard_path) + elsif destination_url = cookies[:destination_url] + cookies[:destination_url] = nil + return redirect_to(destination_url) + end else @needs_approval = true end @@ -581,7 +587,7 @@ class UsersController < ApplicationController if @user.active render_json_error(I18n.t('activation.activated'), status: 409) - else @user + else @email_token = @user.email_tokens.unconfirmed.active.first enqueue_activation_email render nothing: true diff --git a/app/jobs/onceoff/migrate_custom_emojis.rb b/app/jobs/onceoff/migrate_custom_emojis.rb new file mode 100644 index 0000000000..9eaff5190b --- /dev/null +++ b/app/jobs/onceoff/migrate_custom_emojis.rb @@ -0,0 +1,41 @@ +module Jobs + class MigrateCustomEmojis < Jobs::Onceoff + def execute_onceoff(args) + return if Rails.env.test? + + Dir["#{Rails.root}/#{Emoji.base_directory}/*.{png,gif}"].each do |path| + name = File.basename(path, File.extname(path)) + + File.open(path) do |file| + upload = Upload.create_for( + Discourse.system_user.id, + file, + File.basename(path), + file.size, + image_type: 'custom_emoji' + ) + + if upload.persisted? + custom_emoji = CustomEmoji.new(name: name, upload: upload) + + if !custom_emoji.save + warn("Failed to create custom emoji '#{name}': #{custom_emoji.errors.full_messages}") + end + else + warn("Failed to create upload for '#{name}' custom emoji: #{upload.errors.full_messages}") + end + end + end + + Emoji.clear_cache + + Post.where("cooked LIKE '%#{Emoji.base_url}%'").find_each do |post| + post.rebake! + end + end + + def warn(message) + Rails.logger.warn(message) + end + end +end diff --git a/app/jobs/regular/emit_web_hook_event.rb b/app/jobs/regular/emit_web_hook_event.rb index 2186ca9baa..46ce3f43bd 100644 --- a/app/jobs/regular/emit_web_hook_event.rb +++ b/app/jobs/regular/emit_web_hook_event.rb @@ -3,32 +3,24 @@ require 'excon' module Jobs class EmitWebHookEvent < Jobs::Base def execute(args) - raise Discourse::InvalidParameters.new(:web_hook_id) unless args[:web_hook_id].present? - raise Discourse::InvalidParameters.new(:event_type) unless args[:event_type].present? - - args = args.dup - - if args[:topic_id] - args[:topic_view] = TopicView.new(args[:topic_id], Discourse.system_user) + [:web_hook_id, :event_type].each do |key| + raise Discourse::InvalidParameters.new(key) unless args[key].present? end - if args[:post_id] - # deleted post so skip - return unless args[:post] = Post.find_by(id: args[:post_id]) - end + web_hook = WebHook.find_by(id: args[:web_hook_id]) + raise Discourse::InvalidParameters(:web_hook_id) if web_hook.blank? - if args[:user_id] - return unless args[:user] = User.find_by(id: args[:user_id]) - end - - web_hook = WebHook.find(args[:web_hook_id]) - - unless args[:event_type] == 'ping' + unless ping_event?(args[:event_type]) return unless web_hook.active? + return if web_hook.group_ids.present? && (args[:group_id].present? || !web_hook.group_ids.include?(args[:group_id])) + return if web_hook.category_ids.present? && (!args[:category_id].present? || !web_hook.category_ids.include?(args[:category_id])) + + event_type = args[:event_type].to_s + return unless self.send("setup_#{event_type}", args) end web_hook_request(args, web_hook) @@ -36,12 +28,56 @@ module Jobs private - def web_hook_request(args, web_hook) + def guardian + Guardian.new(Discourse.system_user) + end + def setup_post(args) + post = Post.find_by(id: args[:post_id]) + return if post.blank? + args[:payload] = WebHookPostSerializer.new(post, scope: guardian, root: false).as_json + end + + def setup_topic(args) + topic_view = (TopicView.new(args[:topic_id], Discourse.system_user) rescue nil) + return if topic_view.blank? + args[:payload] = WebHookTopicViewSerializer.new(topic_view, scope: guardian, root: false).as_json + end + + def setup_user(args) + user = User.find_by(id: args[:user_id]) + return if user.blank? + args[:payload] = WebHookUserSerializer.new(user, scope: guardian, root: false).as_json + end + + def ping_event?(event_type) + event_type.to_s == 'ping'.freeze + end + + def build_web_hook_body(args, web_hook) + body = {} + guardian = Guardian.new(Discourse.system_user) + event_type = args[:event_type].to_s + + if ping_event?(event_type) + body[:ping] = 'OK' + else + body[event_type] = args[:payload] + end + + new_body = Plugin::Filter.apply(:after_build_web_hook_body, self, body) + + MultiJson.dump(new_body) + end + + def web_hook_request(args, web_hook) uri = URI(web_hook.payload_url) - conn = Excon.new(uri.to_s, - ssl_verify_peer: web_hook.verify_certificate, - retry_limit: 0) + + conn = Excon.new( + uri.to_s, + ssl_verify_peer: web_hook.verify_certificate, + retry_limit: 0 + ) body = build_web_hook_body(args, web_hook) web_hook_event = WebHookEvent.create!(web_hook_id: web_hook.id) @@ -53,6 +89,7 @@ module Jobs else 'application/json' end + headers = { 'Accept' => '*/*', 'Connection' => 'close', @@ -64,6 +101,7 @@ module Jobs 'X-Discourse-Event-Id' => web_hook_event.id, 'X-Discourse-Event-Type' => args[:event_type] } + headers['X-Discourse-Event'] = args[:event_name].to_s if args[:event_name].present? if web_hook.secret.present? @@ -72,45 +110,23 @@ module Jobs now = Time.zone.now response = conn.post(headers: headers, body: body) + + web_hook_event.update!( + headers: MultiJson.dump(headers), + payload: body, + status: response.status, + response_headers: MultiJson.dump(response.headers), + response_body: response.body, + duration: ((Time.zone.now - now) * 1000).to_i + ) + + MessageBus.publish("/web_hook_events/#{web_hook.id}", { + web_hook_event_id: web_hook_event.id, + event_type: args[:event_type] + }, user_ids: User.human_users.staff.pluck(:id)) rescue web_hook_event.destroy! end - - web_hook_event.update_attributes!(headers: MultiJson.dump(headers), - payload: body, - status: response.status, - response_headers: MultiJson.dump(response.headers), - response_body: response.body, - duration: ((Time.zone.now - now) * 1000).to_i) - MessageBus.publish("/web_hook_events/#{web_hook.id}", { - web_hook_event_id: web_hook_event.id, - event_type: args[:event_type] - }, user_ids: User.staff.pluck(:id)) end - - def build_web_hook_body(args, web_hook) - body = {} - guardian = Guardian.new(Discourse.system_user) - - if topic_view = args[:topic_view] - body[:topic] = TopicViewSerializer.new(topic_view, scope: guardian, root: false).as_json - end - - if post = args[:post] - body[:post] = PostSerializer.new(post, scope: guardian, root: false).as_json - end - - if user = args[:user] - body[:user] = UserSerializer.new(user, scope: guardian, root: false).as_json - end - - body[:ping] = 'OK' if args[:event_type] == 'ping' - - raise Discourse::InvalidParameters.new if body.empty? - - MultiJson.dump(body) - end - end - end diff --git a/app/jobs/regular/rebake_custom_emoji_posts.rb b/app/jobs/regular/rebake_custom_emoji_posts.rb new file mode 100644 index 0000000000..d1afbc8732 --- /dev/null +++ b/app/jobs/regular/rebake_custom_emoji_posts.rb @@ -0,0 +1,8 @@ +module Jobs + class RebakeCustomEmojiPosts < Jobs::Base + def execute(args) + name = args[:name] + Post.where("raw LIKE '%:#{name}:%'").find_each { |post| post.rebake! } + end + end +end diff --git a/app/jobs/regular/resize_emoji.rb b/app/jobs/regular/resize_emoji.rb deleted file mode 100644 index fa30e629e7..0000000000 --- a/app/jobs/regular/resize_emoji.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Jobs - - class ResizeEmoji < Jobs::Base - - def execute(args) - path = args[:path] - return unless File.exists?(path) - - opts = { - allow_animation: true, - force_aspect_ratio: SiteSetting.enforce_square_emoji - } - # make sure emoji aren't too big - OptimizedImage.downsize(path, path, "100x100", opts) - end - end - -end diff --git a/app/jobs/regular/user_email.rb b/app/jobs/regular/user_email.rb index 500f8cddb4..6f316d530e 100644 --- a/app/jobs/regular/user_email.rb +++ b/app/jobs/regular/user_email.rb @@ -67,16 +67,13 @@ module Jobs signup_after_approval } - def message_for_email(user, post, type, notification, - notification_type=nil, notification_data_hash=nil, - email_token=nil, to_address=nil) - + def message_for_email(user, post, type, notification, notification_type=nil, notification_data_hash=nil, email_token=nil, to_address=nil) set_skip_context(type, user.id, to_address || user.email, post.try(:id)) return skip_message(I18n.t("email_log.anonymous_user")) if user.anonymous? return skip_message(I18n.t("email_log.suspended_not_pm")) if user.suspended? && type.to_s != "user_private_message" - return if user.staged && type == :digest + return if user.staged && type.to_s == "digest" seen_recently = (user.last_seen_at.present? && user.last_seen_at > SiteSetting.email_time_window_mins.minutes.ago) seen_recently = false if user.user_option.email_always || user.staged @@ -87,9 +84,7 @@ module Jobs return skip_message(I18n.t('email_log.seen_recently')) if seen_recently && !user.suspended? end - if post - email_args[:post] = post - end + email_args[:post] = post if post if notification || notification_type email_args[:notification_type] ||= notification_type || notification.try(:notification_type) @@ -118,18 +113,13 @@ module Jobs end skip_reason = skip_email_for_post(post, user) - return skip_message(skip_reason) if skip_reason + return skip_message(skip_reason) if skip_reason.present? # Make sure that mailer exists raise Discourse::InvalidParameters.new("type=#{type}") unless UserNotifications.respond_to?(type) - if email_token.present? - email_args[:email_token] = email_token - end - - if type.to_s == "notify_old_email" - email_args[:new_email] = user.email - end + email_args[:email_token] = email_token if email_token.present? + email_args[:new_email] = user.email if type.to_s == "notify_old_email" if EmailLog.reached_max_emails?(user) return skip_message(I18n.t('email_log.exceeded_emails_limit')) @@ -144,9 +134,7 @@ module Jobs end # Update the to address if we have a custom one - if message && to_address.present? - message.to = to_address - end + message.to = to_address if message && to_address.present? [message, nil] end @@ -179,12 +167,10 @@ module Jobs return I18n.t('email_log.topic_nil') if post.topic.blank? return I18n.t('email_log.post_user_deleted') if post.user.blank? return I18n.t('email_log.post_deleted') if post.user_deleted? - return I18n.t('email_log.user_suspended') if (user.suspended? && !post.user.try(:staff?)) + return I18n.t('email_log.user_suspended') if user.suspended? && !post.user&.staff? - if !user.user_option.email_always? && - PostTiming.where(topic_id: post.topic_id, post_number: post.post_number, user_id: user.id).present? - return I18n.t('email_log.already_read') - end + already_read = !user.user_option.email_always? && PostTiming.exists?(topic_id: post.topic_id, post_number: post.post_number, user_id: user.id) + return I18n.t('email_log.already_read') if already_read else false end diff --git a/app/jobs/scheduled/clean_up_uploads.rb b/app/jobs/scheduled/clean_up_uploads.rb index 9a12757609..263e7563b7 100644 --- a/app/jobs/scheduled/clean_up_uploads.rb +++ b/app/jobs/scheduled/clean_up_uploads.rb @@ -22,11 +22,13 @@ module Jobs .joins("LEFT JOIN user_avatars ua ON (ua.gravatar_upload_id = uploads.id OR ua.custom_upload_id = uploads.id)") .joins("LEFT JOIN user_profiles up ON up.profile_background = uploads.url OR up.card_background = uploads.url") .joins("LEFT JOIN categories c ON c.uploaded_logo_id = uploads.id OR c.uploaded_background_id = uploads.id") + .joins("LEFT JOIN custom_emojis ce ON ce.upload_id = uploads.id") .where("pu.upload_id IS NULL") .where("u.uploaded_avatar_id IS NULL") .where("ua.gravatar_upload_id IS NULL AND ua.custom_upload_id IS NULL") .where("up.profile_background IS NULL AND up.card_background IS NULL") .where("c.uploaded_logo_id IS NULL AND c.uploaded_background_id IS NULL") + .where("ce.upload_id IS NULL") .where("uploads.url NOT IN (?)", ignore_urls) result.find_each do |upload| diff --git a/app/jobs/scheduled/enqueue_digest_emails.rb b/app/jobs/scheduled/enqueue_digest_emails.rb index 8969aee37c..bab41fb142 100644 --- a/app/jobs/scheduled/enqueue_digest_emails.rb +++ b/app/jobs/scheduled/enqueue_digest_emails.rb @@ -15,18 +15,18 @@ module Jobs def target_user_ids # Users who want to receive digest email within their chosen digest email frequency query = User.real - .where(active: true, staged: false) - .joins(:user_option) .not_suspended - .where(user_options: {email_digests: true}) + .activated + .where(staged: false) + .joins(:user_option, :user_stat) + .where("user_options.email_digests") + .where("user_stats.bounce_score < #{SiteSetting.bounce_score_threshold}") .where("COALESCE(last_emailed_at, '2010-01-01') <= CURRENT_TIMESTAMP - ('1 MINUTE'::INTERVAL * user_options.digest_after_minutes)") .where("COALESCE(last_seen_at, '2010-01-01') <= CURRENT_TIMESTAMP - ('1 MINUTE'::INTERVAL * user_options.digest_after_minutes)") .where("COALESCE(last_seen_at, '2010-01-01') >= CURRENT_TIMESTAMP - ('1 DAY'::INTERVAL * #{SiteSetting.suppress_digest_email_after_days})") # If the site requires approval, make sure the user is approved - if SiteSetting.must_approve_users? - query = query.where("approved OR moderator OR admin") - end + query = query.where("approved OR moderator OR admin") if SiteSetting.must_approve_users? query.pluck(:id) end diff --git a/app/mailers/user_notifications.rb b/app/mailers/user_notifications.rb index 5c4ef82c67..b8b72b19d9 100644 --- a/app/mailers/user_notifications.rb +++ b/app/mailers/user_notifications.rb @@ -357,6 +357,12 @@ class UserNotifications < ActionMailer::Base user = opts[:user] locale = user_locale(user) + template = "user_notifications.user_#{notification_type}" + if post.topic.private_message? + template << "_pm" + template << "_staged" if user.staged? + end + # category name category = Topic.find_by(id: post.topic_id).category if opts[:show_category_in_subject] && post.topic_id && category && !category.uncategorized? @@ -384,10 +390,7 @@ class UserNotifications < ActionMailer::Base end end - reached_limit = SiteSetting.max_emails_per_day_per_user > 0 - reached_limit &&= (EmailLog.where(user_id: user.id, skipped: false) - .where('created_at > ?', 1.day.ago) - .count) >= (SiteSetting.max_emails_per_day_per_user-1) + translation_override_exists = TranslationOverride.where(locale: SiteSetting.default_locale, translation_key: "#{template}.text_body_template").exists? if opts[:use_invite_template] if post.topic.private_message? @@ -397,36 +400,42 @@ class UserNotifications < ActionMailer::Base end topic_excerpt = post.excerpt.tr("\n", " ") if post.is_first_post? && post.excerpt message = I18n.t(invite_template, username: username, topic_title: title, topic_excerpt: topic_excerpt, site_title: SiteSetting.title, site_description: SiteSetting.site_description) - html = UserNotificationRenderer.new(Rails.configuration.paths["app/views"]).render( - template: 'email/invite', - format: :html, - locals: { message: PrettyText.cook(message, sanitize: false).html_safe, - classes: RTL.new(user).css_class - } - ) - else - in_reply_to_post = post.reply_to_post if user.user_option.email_in_reply_to - html = UserNotificationRenderer.new(Rails.configuration.paths["app/views"]).render( - template: 'email/notification', - format: :html, - locals: { context_posts: context_posts, - reached_limit: reached_limit, - post: post, - in_reply_to_post: in_reply_to_post, - classes: RTL.new(user).css_class - } - ) - message = email_post_markdown(post) + (reached_limit ? "\n\n#{I18n.t "user_notifications.reached_limit", count: SiteSetting.max_emails_per_day_per_user}" : ""); - end - template = "user_notifications.user_#{notification_type}" - if post.topic.private_message? - template << "_pm" - template << "_staged" if user.staged? + unless translation_override_exists + html = UserNotificationRenderer.new(Rails.configuration.paths["app/views"]).render( + template: 'email/invite', + format: :html, + locals: { message: PrettyText.cook(message, sanitize: false).html_safe, + classes: RTL.new(user).css_class + } + ) + end + else + reached_limit = SiteSetting.max_emails_per_day_per_user > 0 + reached_limit &&= (EmailLog.where(user_id: user.id, skipped: false) + .where('created_at > ?', 1.day.ago) + .count) >= (SiteSetting.max_emails_per_day_per_user-1) + + in_reply_to_post = post.reply_to_post if user.user_option.email_in_reply_to + message = email_post_markdown(post) + (reached_limit ? "\n\n#{I18n.t "user_notifications.reached_limit", count: SiteSetting.max_emails_per_day_per_user}" : ""); + + unless translation_override_exists + html = UserNotificationRenderer.new(Rails.configuration.paths["app/views"]).render( + template: 'email/notification', + format: :html, + locals: { context_posts: context_posts, + reached_limit: reached_limit, + post: post, + in_reply_to_post: in_reply_to_post, + classes: RTL.new(user).css_class + } + ) + end end email_opts = { topic_title: title, + topic_title_url_encoded: title ? URI.encode(title) : title, message: message, url: post.url, post_id: post.id, @@ -444,13 +453,17 @@ class UserNotifications < ActionMailer::Base private_reply: post.topic.private_message?, include_respond_instructions: !(user.suspended? || user.staged?), template: template, - html_override: html, site_description: SiteSetting.site_description, site_title: SiteSetting.title, + site_title_url_encoded: URI.encode(SiteSetting.title), style: :notification, locale: locale } + unless translation_override_exists + email_opts[:html_override] = html + end + # If we have a display name, change the from address email_opts[:from_alias] = from_alias if from_alias.present? diff --git a/app/models/about.rb b/app/models/about.rb index dd87169ece..0d670183ba 100644 --- a/app/models/about.rb +++ b/app/models/about.rb @@ -35,14 +35,12 @@ class About def moderators @moderators ||= User.where(moderator: true, admin: false) - .where.not(id: Discourse::SYSTEM_USER_ID) + .human_users .order(:username_lower) end def admins - @admins ||= User.where(admin: true) - .where.not(id: Discourse::SYSTEM_USER_ID) - .order(:username_lower) + @admins ||= User.where(admin: true).human_users.order(:username_lower) end def stats diff --git a/app/models/category.rb b/app/models/category.rb index a1af77996b..6af0b8b877 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -507,6 +507,10 @@ SQL self.where(slug: category_slug, parent_category_id: nil).first end end + + def subcategory_list_includes_topics? + subcategory_list_style.end_with?("with_featured_topics") + end end # == Schema Information diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb new file mode 100644 index 0000000000..bdc2795846 --- /dev/null +++ b/app/models/custom_emoji.rb @@ -0,0 +1,6 @@ +class CustomEmoji < ActiveRecord::Base + belongs_to :upload + + validates :name, presence: true, uniqueness: true + validates :upload_id, presence: true +end diff --git a/app/models/embeddable_host.rb b/app/models/embeddable_host.rb index bc7f2f3e99..f94ce56b1b 100644 --- a/app/models/embeddable_host.rb +++ b/app/models/embeddable_host.rb @@ -40,7 +40,7 @@ class EmbeddableHost < ActiveRecord::Base def host_must_be_valid if host !~ /\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,7}(:[0-9]{1,5})?(\/.*)?\Z/i && - host !~ /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ && + host !~ /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})(:[0-9]{1,5})?(\/.*)?\Z/ && host !~ /\A([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.)?localhost(\:[0-9]{1,5})?(\/.*)?\Z/i errors.add(:host, I18n.t('errors.messages.invalid')) end diff --git a/app/models/emoji.rb b/app/models/emoji.rb index c58cff9dd3..4fee27f5f6 100644 --- a/app/models/emoji.rb +++ b/app/models/emoji.rb @@ -1,6 +1,6 @@ class Emoji # update this to clear the cache - EMOJI_VERSION = "v2" + EMOJI_VERSION = "v3" include ActiveModel::SerializerSupport @@ -14,14 +14,6 @@ class Emoji @path = path end - def remove - return if path.blank? - if File.exists?(path) - File.delete(path) rescue nil - Emoji.clear_cache - end - end - def self.all Discourse.cache.fetch(cache_key("all_emojis")) { standard | custom } end @@ -46,14 +38,6 @@ class Emoji Emoji.custom.detect { |e| e.name == name } end - def self.create_from_path(path) - extension = File.extname(path) - Emoji.new(path).tap do |e| - e.name = File.basename(path, ".*") - e.url = "#{base_url}/#{e.name}#{extension}" - end - end - def self.create_from_db_item(emoji) name = emoji["name"] filename = "#{emoji['filename'] || name}.png" @@ -63,22 +47,6 @@ class Emoji end end - def self.create_for(file, name) - extension = File.extname(file.original_filename) - path = "#{Emoji.base_directory}/#{name}#{extension}" - full_path = "#{Rails.root}/#{path}" - - # store the emoji - FileUtils.mkdir_p(Pathname.new(path).dirname) - File.open(path, "wb") { |f| f << file.tempfile.read } - # clear the cache - Emoji.clear_cache - # launch resize job - Jobs.enqueue(:resize_emoji, path: full_path) - # return created emoji - Emoji[name] - end - def self.cache_key(name) "#{name}:#{EMOJI_VERSION}:#{Plugin::CustomEmoji.cache_key}" end @@ -124,9 +92,12 @@ class Emoji def self.load_custom result = [] - Dir.glob(File.join(Emoji.base_directory, "*.{png,gif}")) - .sort - .each { |emoji| result << Emoji.create_from_path(emoji) } + CustomEmoji.all.each do |emoji| + result << Emoji.new.tap do |e| + e.name = emoji.name + e.url = emoji.upload.url + end + end Plugin::CustomEmoji.emojis.each do |name, url| result << Emoji.new.tap do |e| diff --git a/app/models/global_setting.rb b/app/models/global_setting.rb index 85abcce23b..8ecfd75004 100644 --- a/app/models/global_setting.rb +++ b/app/models/global_setting.rb @@ -11,6 +11,8 @@ class GlobalSetting # for legacy reasons REDIS_SECRET_KEY = 'SECRET_TOKEN' + REDIS_VALIDATE_SECONDS = 30 + # In Rails secret_key_base is used to encrypt the cookie store # the cookie store contains session data # Discourse also uses this secret key to digest user auth tokens @@ -19,9 +21,22 @@ class GlobalSetting # - generate a token on the fly if needed and cache in redis # - enforce rules about token format falling back to redis if needed def self.safe_secret_key_base + + if @safe_secret_key_base && @token_in_redis && (@token_last_validated + REDIS_VALIDATE_SECONDS) < Time.now + @token_last_validated = Time.now + token = $redis.without_namespace.get(REDIS_SECRET_KEY) + if token.nil? + $redis.without_namespace.set(REDIS_SECRET_KEY, @safe_secret_key_base) + end + end + @safe_secret_key_base ||= begin token = secret_key_base if token.blank? || token !~ VALID_SECRET_KEY + + @token_in_redis = true + @token_last_validated = Time.now + token = $redis.without_namespace.get(REDIS_SECRET_KEY) unless token && token =~ VALID_SECRET_KEY token = SecureRandom.hex(64) @@ -39,8 +54,21 @@ class GlobalSetting default_provider = FileProvider.from(File.expand_path('../../../config/discourse_defaults.conf', __FILE__)) default_provider.keys.concat(@provider.keys).uniq.each do |key| default = default_provider.lookup(key, nil) + + instance_variable_set("@#{key}_cache", nil) + define_singleton_method(key) do - provider.lookup(key, default) + val = instance_variable_get("@#{key}_cache") + unless val.nil? + val == :missing ? nil : val + else + val = provider.lookup(key, default) + if val.nil? + val = :missing + end + instance_variable_set("@#{key}_cache", val) + val == :missing ? nil : val + end end end end diff --git a/app/models/invite_redeemer.rb b/app/models/invite_redeemer.rb index d12f0c57bb..6f1406b06a 100644 --- a/app/models/invite_redeemer.rb +++ b/app/models/invite_redeemer.rb @@ -62,6 +62,7 @@ InviteRedeemer = Struct.new(:invite, :username, :name, :password) do send_welcome_message notify_invitee send_password_instructions + enqueue_activation_mail delete_duplicate_invites end @@ -126,6 +127,13 @@ InviteRedeemer = Struct.new(:invite, :username, :name, :password) do end end + def enqueue_activation_mail + if invited_user.has_password? + email_token = invited_user.email_tokens.create(email: invited_user.email) + Jobs.enqueue(:critical_user_email, type: :signup, user_id: invited_user.id, email_token: email_token.token) + end + end + def notify_invitee if inviter = invite.invited_by inviter.notifications.create(notification_type: Notification.types[:invitee_accepted], diff --git a/app/models/notification.rb b/app/models/notification.rb index cdac6ed46e..96e3e43f9e 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -12,10 +12,11 @@ class Notification < ActiveRecord::Base scope :visible , lambda { joins('LEFT JOIN topics ON notifications.topic_id = topics.id') .where('topics.id IS NULL OR topics.deleted_at IS NULL') } - after_save :refresh_notification_count - after_destroy :refresh_notification_count - after_commit :send_email + # This is super weird because the tests fail if we don't specify `on: :destroy` + # TODO: Revert back to default in Rails 5 + after_commit :refresh_notification_count, on: :destroy + after_commit :refresh_notification_count, on: [:create, :update] def self.ensure_consistency! Notification.exec_sql(" diff --git a/app/models/optimized_image.rb b/app/models/optimized_image.rb index 8af90fded9..a2e247d67e 100644 --- a/app/models/optimized_image.rb +++ b/app/models/optimized_image.rb @@ -215,8 +215,11 @@ class OptimizedImage < ActiveRecord::Base end def self.convert_with(instructions, to) - `#{instructions.join(" ")} &> /dev/null` - return false if $?.exitstatus != 0 + begin + Discourse::Utils.execute_command(*instructions) + rescue + return false + end ImageOptim.new.optimize_image!(to) true diff --git a/app/models/topic.rb b/app/models/topic.rb index 93f3cfab50..4077ecd515 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -833,7 +833,7 @@ SQL .update_all(dismissed_banner_key: nil) self.archetype = Archetype.banner - self.add_moderator_post(user, I18n.t("archetypes.banner.message.make")) + self.add_small_action(user, "banner.enabled") self.save MessageBus.publish('/site/banner', banner) @@ -841,7 +841,7 @@ SQL def remove_banner!(user) self.archetype = Archetype.default - self.add_moderator_post(user, I18n.t("archetypes.banner.message.remove")) + self.add_small_action(user, "banner.disabled") self.save MessageBus.publish('/site/banner', nil) diff --git a/app/models/upload.rb b/app/models/upload.rb index d6119abc13..d9aa27eaf3 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -57,7 +57,12 @@ class Upload < ActiveRecord::Base end # list of image types that will be cropped - CROPPED_IMAGE_TYPES ||= %w{avatar profile_background card_background} + CROPPED_IMAGE_TYPES ||= %w{ + avatar + profile_background + card_background + custom_emoji + } WHITELISTED_SVG_ELEMENTS ||= %w{ circle @@ -92,7 +97,7 @@ class Upload < ActiveRecord::Base # options # - content_type # - origin (url) - # - image_type ("avatar", "profile_background", "card_background") + # - image_type ("avatar", "profile_background", "card_background", "custom_emoji") # - is_attachment_for_group_message (boolean) def self.create_for(user_id, file, filename, filesize, options = {}) upload = Upload.new @@ -145,6 +150,8 @@ class Upload < ActiveRecord::Base max_width = 590 * max_pixel_ratio width, height = ImageSizer.resize(w, h, max_width: max_width, max_height: max_width) OptimizedImage.downsize(file.path, file.path, "#{width}x#{height}", filename: filename, allow_animation: allow_animation) + when "custom_emoji" + OptimizedImage.downsize(file.path, file.path, "100x100", filename: filename, allow_animation: allow_animation) end end @@ -246,7 +253,7 @@ class Upload < ActiveRecord::Base end def self.fix_image_orientation(path) - `convert #{path} -auto-orient #{path}` + Discourse::Utils.execute_command('convert', path, '-auto-orient', path) end def self.migrate_to_new_scheme(limit=nil) diff --git a/app/models/user.rb b/app/models/user.rb index f6c297da9b..9a359bd00a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -93,7 +93,6 @@ class User < ActiveRecord::Base after_create :create_user_profile after_create :ensure_in_trust_level_group after_create :set_default_categories_preferences - after_create :trigger_user_created_event before_save :update_username_lower before_save :ensure_password_is_hashed @@ -105,6 +104,7 @@ class User < ActiveRecord::Base after_save :badge_grant after_save :expire_old_email_tokens after_save :index_search + after_commit :trigger_user_created_event, on: :create before_destroy do # These tables don't have primary keys, so destroying them with activerecord is tricky: @@ -124,8 +124,10 @@ class User < ActiveRecord::Base # set to true to optimize creation and save for imports attr_accessor :import_mode + scope :human_users, -> { where('users.id > 0') } + # excluding fake users like the system user or anonymous users - scope :real, -> { where('users.id > 0').where('NOT EXISTS( + scope :real, -> { human_users.where('NOT EXISTS( SELECT 1 FROM user_custom_fields ucf WHERE @@ -1062,11 +1064,6 @@ class User < ActiveRecord::Base end end - def trigger_user_created_event - DiscourseEvent.trigger(:user_created, self) - true - end - private def previous_visit_at_update_required?(timestamp) @@ -1080,6 +1077,11 @@ class User < ActiveRecord::Base end end + def trigger_user_created_event + DiscourseEvent.trigger(:user_created, self) + true + end + end # == Schema Information diff --git a/app/models/web_hook.rb b/app/models/web_hook.rb index 4eed81e6be..4159dfbc7c 100644 --- a/app/models/web_hook.rb +++ b/app/models/web_hook.rb @@ -41,11 +41,11 @@ class WebHook < ActiveRecord::Base end def self.enqueue_topic_hooks(event, topic, user=nil) - WebHook.enqueue_hooks(:topic, topic_id: topic.id, user_id: user&.id, category_id: topic&.category_id, event_name: event.to_s) + WebHook.enqueue_hooks(:topic, topic_id: topic.id, category_id: topic&.category_id, event_name: event.to_s) end def self.enqueue_post_hooks(event, post, user=nil) - WebHook.enqueue_hooks(:post, post_id: post.id, topic_id: post&.topic_id, user_id: user&.id, category_id: post&.topic&.category_id, event_name: event.to_s) + WebHook.enqueue_hooks(:post, post_id: post.id, category_id: post&.topic&.category_id, event_name: event.to_s) end %i(topic_destroyed topic_recovered).each do |event| @@ -61,6 +61,7 @@ class WebHook < ActiveRecord::Base %i(post_created post_destroyed post_recovered).each do |event| + DiscourseEvent.on(event) do |post, _, user| WebHook.enqueue_post_hooks(event, post, user) end diff --git a/app/serializers/admin_detailed_user_serializer.rb b/app/serializers/admin_detailed_user_serializer.rb index 563ae1821e..60c9ea55f2 100644 --- a/app/serializers/admin_detailed_user_serializer.rb +++ b/app/serializers/admin_detailed_user_serializer.rb @@ -91,4 +91,8 @@ class AdminDetailedUserSerializer < AdminUserSerializer scope.can_view_action_logs?(object) end + def post_count + object.posts.count + end + end diff --git a/app/serializers/basic_category_serializer.rb b/app/serializers/basic_category_serializer.rb index ab1cbac4a0..c96fb58b19 100644 --- a/app/serializers/basic_category_serializer.rb +++ b/app/serializers/basic_category_serializer.rb @@ -22,7 +22,8 @@ class BasicCategorySerializer < ApplicationSerializer :sort_ascending, :show_subcategory_list, :num_featured_topics, - :default_view + :default_view, + :subcategory_list_style has_one :uploaded_logo, embed: :object, serializer: CategoryUploadSerializer has_one :uploaded_background, embed: :object, serializer: CategoryUploadSerializer diff --git a/app/serializers/web_hook_post_serializer.rb b/app/serializers/web_hook_post_serializer.rb new file mode 100644 index 0000000000..221c398fa7 --- /dev/null +++ b/app/serializers/web_hook_post_serializer.rb @@ -0,0 +1,17 @@ +class WebHookPostSerializer < PostSerializer + def include_can_edit? + false + end + + def can_delete + false + end + + def can_recover + false + end + + def can_wiki + false + end +end diff --git a/app/serializers/web_hook_topic_view_serializer.rb b/app/serializers/web_hook_topic_view_serializer.rb new file mode 100644 index 0000000000..75c99aeb14 --- /dev/null +++ b/app/serializers/web_hook_topic_view_serializer.rb @@ -0,0 +1,11 @@ +require_dependency 'pinned_check' + +class WebHookTopicViewSerializer < TopicViewSerializer + def include_post_stream? + false + end + + def include_timeline_lookup? + false + end +end diff --git a/app/serializers/web_hook_user_serializer.rb b/app/serializers/web_hook_user_serializer.rb new file mode 100644 index 0000000000..9e6ad411ca --- /dev/null +++ b/app/serializers/web_hook_user_serializer.rb @@ -0,0 +1,5 @@ +class WebHookUserSerializer < UserSerializer + # remove staff attributes + def staff_attributes(*attrs) + end +end diff --git a/app/services/user_blocker.rb b/app/services/user_blocker.rb index 01b5896e88..fe0091425e 100644 --- a/app/services/user_blocker.rb +++ b/app/services/user_blocker.rb @@ -20,7 +20,7 @@ class UserBlocker message_type = @opts[:message] || :blocked_by_staff post = SystemMessage.create(@user, message_type) if post && @by_user - StaffActionLogger.new(@by_user).log_block_user(@user, {context: "#{message_type}: '#{post.topic&.title rescue ''}'"}) + StaffActionLogger.new(@by_user).log_block_user(@user, {context: "#{message_type}: '#{post.topic&.title rescue ''}' #{@opts[:reason]}"}) end end else diff --git a/app/services/user_destroyer.rb b/app/services/user_destroyer.rb index 4b56229a34..9af5731fc9 100644 --- a/app/services/user_destroyer.rb +++ b/app/services/user_destroyer.rb @@ -15,8 +15,8 @@ class UserDestroyer # Returns a frozen instance of the User if the delete succeeded. def destroy(user, opts={}) raise Discourse::InvalidParameters.new('user is nil') unless user and user.is_a?(User) - @guardian.ensure_can_delete_user!(user) raise PostsExistError if !opts[:delete_posts] && user.posts.count != 0 + @guardian.ensure_can_delete_user!(user) User.transaction do diff --git a/app/services/user_updater.rb b/app/services/user_updater.rb index 4d1f6f4498..cbb3c479c4 100644 --- a/app/services/user_updater.rb +++ b/app/services/user_updater.rb @@ -96,15 +96,16 @@ class UserUpdater user.custom_fields = user.custom_fields.merge(fields) end + saved = nil + User.transaction do if attributes.key?(:muted_usernames) update_muted_users(attributes[:muted_usernames]) end saved = (!save_options || user.user_option.save) && user_profile.save && user.save - if saved - DiscourseEvent.trigger(:user_updated, user) + if saved # log name changes if attributes[:name].present? && old_user_name.downcase != attributes.fetch(:name).downcase StaffActionLogger.new(@actor).log_name_change(user.id, old_user_name, attributes.fetch(:name)) @@ -112,8 +113,10 @@ class UserUpdater StaffActionLogger.new(@actor).log_name_change(user.id, old_user_name, "") end end - saved end + + DiscourseEvent.trigger(:user_updated, user) if saved + saved end def update_muted_users(usernames) diff --git a/config/application.rb b/config/application.rb index 49b35de474..258ca0c276 100644 --- a/config/application.rb +++ b/config/application.rb @@ -185,6 +185,8 @@ module Discourse require_dependency 'group' require_dependency 'user_field' require_dependency 'post_action_type' + # Ensure that Discourse event triggers for web hooks are loaded + require_dependency 'web_hook' # So open id logs somewhere sane OpenID::Util.logger = Rails.logger diff --git a/config/initializers/100-wrap_parameters.rb b/config/initializers/100-wrap_parameters.rb index 02e47b12b8..999df20181 100644 --- a/config/initializers/100-wrap_parameters.rb +++ b/config/initializers/100-wrap_parameters.rb @@ -12,4 +12,3 @@ end ActiveSupport.on_load(:active_record) do self.include_root_in_json = false end - diff --git a/config/locales/client.ar.yml b/config/locales/client.ar.yml index ea06c24722..eacfd7ac81 100644 --- a/config/locales/client.ar.yml +++ b/config/locales/client.ar.yml @@ -9,8 +9,8 @@ ar: js: number: format: - separator: "." - delimiter: "," + separator: "٫" + delimiter: "٬" human: storage_units: format: '%n% u' @@ -187,28 +187,28 @@ ar: split_topic: "قسم هذا الموضوع في %{when}" invited_user: "دعى %{who} %{when}" invited_group: "دعى %{who} %{when}" - removed_user: "أزال %{who} في %{when}" - removed_group: "أزال %{who} في %{when}" + removed_user: "أزال %{who} %{when}" + removed_group: "أزال %{who} %{when}" autoclosed: - enabled: 'أُغلق في %{when}' - disabled: 'فُتح في %{when}' + enabled: 'أُغلق %{when}' + disabled: 'فُتح %{when}' closed: - enabled: 'أغلقه في %{when}' - disabled: 'فتحه في %{when}' + enabled: 'أغلقه %{when}' + disabled: 'فتحه %{when}' archived: - enabled: 'أرشفه في %{when}' - disabled: 'أزال أرشفته في %{when}' + enabled: 'أرشفه %{when}' + disabled: 'أزال أرشفته %{when}' pinned: - enabled: 'ثبّته في %{when}' - disabled: 'أزال تثبيته في %{when}' + enabled: 'ثبّته %{when}' + disabled: 'أزال تثبيته %{when}' pinned_globally: - enabled: 'ثبّته عموميا في %{when}' - disabled: 'أزال تثبيته في %{when}' + enabled: 'ثبّته عموميا %{when}' + disabled: 'أزال تثبيته %{when}' visible: - enabled: 'أدرجه في %{when}' - disabled: 'أزال إدراجه في %{when}' + enabled: 'أدرجه %{when}' + disabled: 'أزال إدراجه %{when}' topic_admin_menu: "عمليات المدير" - wizard_required: "حان وقت اعداد منتداك! شغل معالج الإعداد!" + wizard_required: "مرحبًا في دسكورس الجديد! فلنبدأ مستخدمين مرشد الإعداد ✨" emails_are_disabled: "لقد عطّل أحد المدراء الرّسائل الصادرة للجميع. لن تُرسل إشعارات عبر البريد الإلكتروني أيا كان نوعها." bootstrap_mode_enabled: "الموقع اﻷن مفعل بالطريقة التمهيدية لكى تتمكن من اطلاق موقعك الجديد بسهولة. سيسجل كل الأعضاء الجدد بمستوى ثقة 1 وسيكون اختيار ارسال الملخص اليومى عن طريق البريد الالكترونى مفعل. سيتم الغاء تفعيل الطريقة التمهيدية تلقائيا عندما يتخطى عدد اﻷعضاء %{min_users} عضو." bootstrap_mode_disabled: "سيتم الغاء تفعيل الطريقة التمهيدية خلال ال 24 ساعة القادمة" @@ -236,7 +236,7 @@ ar: sign_up: "سجّل حسابا" log_in: "تسجيل الدخول " age: "العمر" - joined: "انضم" + joined: "انضم في" admin_title: "المدير" flags_title: "بلاغات" show_more: "أظهر المزيد" @@ -334,7 +334,7 @@ ar: other: "{{count}} موضوع جديد." click_to_show: "انقر للعرض." preview: "معاينة" - cancel: "ألغ" + cancel: "إلغاء" save: "احفظ التعديلات" saving: "يحفظ..." saved: "حُفظت!" @@ -365,7 +365,7 @@ ar: title: "تحتاج موافقة" none: "لا مشاركات لمراجعتها." edit: "حرر" - cancel: "ألغِ" + cancel: "إلغاء" view_pending: "اعرض المشاركات المعلّقة" has_pending_posts: zero: "ليس في هذا الموضوع أيّة مشاركات تحتاج مراجعة" @@ -560,11 +560,11 @@ ar: toggle_ordering: "تبديل التحكم في الترتيب" subcategories: "أقسام فرعية" topic_sentence: - zero: "%{count} موضوع" - one: "موضوع" + zero: "لا مواضيع" + one: "موضوع واحد" two: "موضوعان" few: "%{count} مواضيع" - many: "%{count} موضوع" + many: "%{count} موضوعًا" other: "%{count} موضوع" topic_stat_sentence: zero: "لا مواضيع جديدة في ال%{unit} الماضي." @@ -597,7 +597,7 @@ ar: edit: "تعديل التفضيلات" download_archive: button_text: "تحميل مواضيعي" - confirm: "هل أنت متأكد من رغبتك في تحميل جميع مشاركاتك ؟" + confirm: "أمتأكّد من تنزيل مشاركاتك؟" success: "بدأ التحميل, سيتم إعلامك برسالة عند اكتمال العملية." rate_limit_error: "المشاركات يمكن تحميلها لمرة واحدة في اليوم , الرجاء المحاولة غدا." new_private_message: "رسالة جديدة" @@ -614,18 +614,18 @@ ar: statistics: "احصائيات" desktop_notifications: label: "تنبيهات سطح المكتب" - not_supported: "عذراً , التنبيهات غير مدعومة على هذا المتصفح" - perm_default: "تفعيل التنبيهات" + not_supported: "نأسف، لا يدعم المتصفّح الإشعارات." + perm_default: "فعّل الإشعارات" perm_denied_btn: "الوصول مرفوض" perm_denied_expl: "لقد رفضت صلاحية عرض الإشعارات. اسمح بظهور الإشعارات وذلك من إعدادات المتصفح." - disable: "إيقاف التنبيهات " - enable: "تفعيل التنبيهات" + disable: "عطّل الإشعارات" + enable: "فعّل الإشعارات" each_browser_note: "ملاحظة: عليك تغيير هذا الإعداد في كل متصفح تستخدمه." dismiss_notifications: "تجاهل الكل" dismiss_notifications_tooltip: "جعل جميع التنبيهات الغيرة مقروءة الى مقروءة. " first_notification: "إشعارك الأول! قم بالضغط عليه للبدء." - disable_jump_reply: "لاتذهب إلى مشاركتي بعد الرد" - dynamic_favicon: "إعرض عدد المواضيع الجديدة والمحدثة في أيقونة المتصفح" + disable_jump_reply: "لا تنتقل إلى مشاركتي بعدما أردّ" + dynamic_favicon: "أظهر عدد المواضيع الجديدة/المحدّثة في أيقونة المتصفّح" external_links_in_new_tab: "فتح الروابط الخارجية في ألسنة جديدة" enable_quoting: "فعل خاصية إقتباس النصوص المظللة" change: "تغيير" @@ -636,7 +636,7 @@ ar: blocked_tooltip: "هذا المستخدم محظور" suspended_notice: "هذا المستخدم موقوف حتى تاريخ {{date}}" suspended_reason: "السبب:" - github_profile: "Github" + github_profile: "غِت‌هَب" email_activity_summary: "ملخص النشاط" mailing_list_mode: label: "وضع القائمة البريدية" @@ -646,7 +646,7 @@ ar: هذه الرسائل لا تشمل المواضيع والفئات المكتومة. daily: "أرسل تحديثات يومية" individual: "أرسل لي بريدا لكل مشاركة جديدة" - individual_no_echo: "ارسل بريد الكتروني لكل مشاركة جديدة ما عدا مواضيعي" + individual_no_echo: "أرسل بريدًا لكلّ مشاركة جديدة عدا مشاركاتي" many_per_day: "أرسل لي بريدا لكل مشاركة جديدة (تقريبا {{dailyEmailEstimate}} يوميا)" few_per_day: "أرسل لي بريدا لكل مشاركة جديدة (تقريبا إثنتان يوميا)" tag_settings: "الوسوم" @@ -667,7 +667,7 @@ ar: muted_categories: "المكتومة" muted_categories_instructions: "لن يتم إشعارك بأي جديد عن المواضيع الجديدة في هذه التصنيفات، ولن تظهر مواضيع هذه التصنيفات في قائمة المواضيع المنشورة مؤخراً." delete_account: "حذف الحساب" - delete_account_confirm: "هل انت متاكد من انك تريد حذف حسابك نهائيا؟ لايمكن التراجع عن هذا العمل!" + delete_account_confirm: "أمتأكّد من حذف حسابك للأبد؟ هذا إجراء لا عودة فيه!" deleted_yourself: "تم حذف حسابك بنجاح" delete_yourself_not_allowed: "لايمكنك حذف حسابك الان , تواصل مع المدير ليحذف حسابك " unread_message_count: "الرسائل" @@ -709,17 +709,17 @@ ar: choose: "ادخل رمز سري" change_about: title: "تعديل ملفي الشخصي" - error: "حدث خطأ عند تغيير هذه القيمة." + error: "حدث عطل في تغيير هذه القيمة." change_username: title: "تغيير اسم المستخدم" confirm: "عند تغييرك أسم المستخدم, جميع الاقتباسات السابقة من مشاركاتك و ذكر اسم المستخدم الخاص بك ستصبح غير صحيحة ولا تشير الى ملفك الشخصي. هل انت متأكد تماماً من اختيارك؟" - taken: "عذراً، هذا الإسم مُستخدم مسبقاً." - error: "حدث خطأ عند تغيير اسم المستخدم." - invalid: "اسم المستخدم غير صالح. يجب ان يحتوي على ارقام وحروف فقط " + taken: "نأسف، اسم المستخدم مأخوذ." + error: "حدث عطل في تغيير اسم المستخدم." + invalid: "اسم المستخدم غير صالح. يمكنه احتواء الأرقام والأحرف فحسب" change_email: - title: "تغيير البريد الالكتروني" - taken: "نأسف، البريد الالكتروني غير متاح." - error: "حدث خطأ عند تغيير البريد الالكتروني. ربما يكون هذا البريد مستخدم من قبل؟" + title: "غيّر البريد الإلكترونيّ" + taken: "نأسف، البريد الإلكترونيّ غير متوفّر." + error: "حدث عطل في تغيير البريد الإلكترونيّ. لربّما هناك من يستخدم هذا العنوان بالفعل؟" success: "لقد أرسلنا بريدا إلى هذا البريد. من فضلك اتّبع تعليمات التأكيد." change_avatar: title: "غير صورتك الشخصية" @@ -741,7 +741,7 @@ ar: instructions: "سيتم وضع الخلفية في المنتصف بعرض 590px" email: title: "البريد الإلكتروني" - instructions: "سيكون مخفي عن الجميع" + instructions: "لا يظهر للعموم" ok: "سنرسل لك بريدا للتأكيد" invalid: "من فضلك أدخل بريدا إلكترونيا صالحا" authenticated: "تم توثيق بريدك الإلكتروني بواسطة {{provider}}" @@ -761,18 +761,18 @@ ar: ok: "يبدو اسمك جيدا" username: title: "اسم المستخدم" - instructions: "غير مكرر , بدون مسافات , قصير" + instructions: "فريد دون مسافات وقصير" short_instructions: "يمكن للغير الإشارة إليك ب‍@{{username}}" available: "اسم المستخدم متاح." not_available: "غير متاح. جرّب {{suggestion}} ؟" not_available_no_suggestion: "غير متاح" - too_short: "اسم المستخدم قصير جداً" - too_long: "اسم المستخدم طويل جداً" + too_short: "اسم المستخدم قصير جدًّا" + too_long: "اسم المستخدم طويل جدًّا" checking: "يتم التاكد من توفر اسم المستخدم..." prefilled: "البريد الالكتروني مطابق لـ اسم المستخدم المسّجل." locale: - title: "لغة الموقع." - instructions: "اللغة المستخدمة تغيرت. لتفعيل اللغة الجديدة قم بتحديث الصفحة. " + title: "لغة الواجهة" + instructions: "لغة الواجهة الرّسومية. ستتغيّر عندما تُنعش الصّفحة." default: "(الافتراضية)" any: "أي" password_confirmation: @@ -808,14 +808,14 @@ ar: every_two_weeks: "كل أسبوعين" include_tl0_in_digests: "في إيميلات تلخيص المحتوى إرفق مشاركات الأعضاء الجدد." email_in_reply_to: " بالإشعار الألكتروني إرفق مقتطفات من الردود." - email_direct: "تلقي رسالة إلكترونية عند اقتباس مشاركة لك أو الرد على عليها أو في حالة ذكر اسمك @username" - email_private_messages: "إرسل إشعار بالبريد الإلكتروني عندما يرسل لك شخصاً رسالة خاصة." - email_always: "إرسل التنبيهات على بريدي الإلكتروني حتى وإن كنت متواجد في الموقع ." - other_settings: "اخرى" + email_direct: "أرسل إليّ بريدًا عندما يقتبس أحد كلامي، أو يرّد على إحدى مشاركاتي، أو يذكر @اسمي أو يدعوني إلى أحد المواضيع" + email_private_messages: "أرسل إليّ بريدًا عندما يبعث أحدهم رسالة إليّ" + email_always: "أرسل إليّ الإخطارات عبر البريد حتّى ولو كنت متّصلًا" + other_settings: "أخرى" categories_settings: "الأقسام" new_topic_duration: label: " \nإعتبر المواضيع جديدة في حال" - not_viewed: "لم أشاهدها بعد. " + not_viewed: "لم أطالعها بعد" last_here: "تم إنشائها منذ اخر زيارة لي. " after_1_day: "أُنشئت في اليوم الماضي" after_2_days: "أُنشئت في اليومين الماضيين" @@ -826,13 +826,13 @@ ar: never: "ابداً" immediately: "حالاً" after_30_seconds: "بعد 30 ثانية" - after_1_minute: "بعد 1 دقيقة" - after_2_minutes: "بعد 2 دقائق" + after_1_minute: "بعد دقيقة واحدة" + after_2_minutes: "بعد دقيقتين" after_3_minutes: "بعد 3 دقائق" after_4_minutes: "بعد 4 دقائق" after_5_minutes: "بعد 5 دقائق" after_10_minutes: "بعد 10 دقائق" - notification_level_when_replying: "عندما أشارك في موضوع، اجعل ذلك الموضوع" + notification_level_when_replying: "إن شاركت في موضوع ما، اجعله" invited: search: "نوع البحث عن الدعوات" title: "دعوة" @@ -867,32 +867,32 @@ ar: account_age_days: "عمر الحساب بالأيام" create: "أرسل دعوة" generate_link: "انسخ رابط الدعوة" - link_generated: "تم إنشاء رابط الدعوة بنجاح!" - valid_for: "رابط الدعوة صحيح فقط للبريد الإلكتروني %{email}" + link_generated: "وُلّد رابط الدّعوة بنجاح!" + valid_for: "رابط الدعوة صالح للبريد الإلكترونيّ هذا فقط: %{email}" bulk_invite: none: "لم تقم بدعوة احد الى هنا حتى الآن، يمكنك إرسال دعوه واحدة او مجموعة دعوات عن طريق ملف CSV." text: "الدعوة من ملف" success: "رُفع الملف بنجاح. سيصلك إشعارا عبر رسالة عند اكتمال العملية." - error: "عذراً، الملف يجب ان يكون على صيغة CSV." + error: "نأسف، يجب أن يكون الملفّ بنسق CSV." password: - title: "الرمز السري. " - too_short: "الرمز السري قصير جداً." - common: "الرمز السري ضعيف!" - same_as_username: "الرمز السري مُطابق لاسم المستخدم." - same_as_email: "الرمز السري مطابق للبريد الإلكتروني." - ok: "الرمز السري جيّد. " + title: "كلمة السّرّ" + too_short: "كلمة السّرّ قصيرة جدًّا." + common: "كلمة السّرّ هذه شائعة." + same_as_username: "كلمة السّرّ تطابق اسم المستخدم." + same_as_email: "كلمة السّر تطابق البريد الإلكترونيّ." + ok: "تبدو كلمة السّر جيّدة." instructions: "يجب أن تكون على الأقل %{count} أحرف او أرقام" summary: title: "ملخص" - stats: "إحصائيات العضو:" + stats: "إحصائيّات" time_read: "< الوقت الذي امضاه في الموقع" topic_count: - zero: "< إجمالي المواضيع" - one: "< إجمالي المواضيع" - two: "< إجمالي المواضيع" - few: "< إجمالي المواضيع" - many: "< إجمالي المواضيع" - other: "< إجمالي المواضيع" + zero: "عدد المواضيع المنشأة" + one: "عدد المواضيع المنشأة" + two: "عدد المواضيع المنشأة" + few: "عدد المواضيع المنشأة" + many: "عدد المواضيع المنشأة" + other: "عدد المواضيع المنشأة" post_count: zero: "< إجمالي المواضيع" one: " < اجمالي المشاركات" @@ -936,20 +936,20 @@ ar: many: "المفضلة" other: "المفضلة" top_replies: "أفضل الردود" - no_replies: "لَم ينشر أي رد بعد." - more_replies: "المزيد من الردود" + no_replies: "لا ردود بعد." + more_replies: "ردود أخرى" top_topics: "أفضل المواضيع" - no_topics: "لَم ينشر أي موضوع بعد. " - more_topics: "المزيد من المواضيع" - top_badges: "افضل الاوسمه" - no_badges: "لم يحصل على اي وسام بعد. " + no_topics: "لا مواضيع بعد." + more_topics: "مواضيع أخرى" + top_badges: "أفضل الشّارات" + no_badges: "لا شارات بعد." more_badges: "أوسمة أخرى .. " - top_links: "أفضل الروابط التي اضافها:" - no_links: "ليس هناك اي روابط بعد." + top_links: "أفضل الرّوابط" + no_links: "لا روابط بعد." most_liked_by: "الأعضاء المُعجبين بمشاركاتِه:" most_liked_users: "الأعضاء الذين تعجبهُ مشاركاتِهم:" most_replied_to_users: "الأعضاء الذين يتفاعل معهم غالباً:" - no_likes: "لم يتلقى أي إعجاب بعد." + no_likes: "لا إعجابات بعد." associated_accounts: "الحسابات المرتبطة" ip_address: title: "عنوان IP الأخير" @@ -988,11 +988,11 @@ ar: again: "أعد المحاولة" fixed: "تحميل" close: "اغلاق" - assets_changed_confirm: "لقد تم تحديث الموقع قبل قليل، هل تريد تحديث الصفحة لتصفح الموقع بآخر نسخة؟ " + assets_changed_confirm: "حُدّث الموقع لتوّه. أتريد إنعاش الصّفحة ورؤية أحدث إصدارة؟" logout: "لقد تم تسجيل خروجك" refresh: "تحديث" read_only_mode: - enabled: "الموقع حالياً في وضع القراءة فقط، هذا يعني انه لا يمكنك الآن إنشاء مواضيع او إضافة ردود او تقديم إعجاب بمشاركة. " + enabled: "هذا الموقع في وضع القراءة فقط. نأمل أن تتابع تصفّحه، ولكنّ الرّدّ، والإعجاب وغيرها من إجراءات معطّلة حاليًّا." login_disabled: "تسجيل الدخول معطّل عندما يكون الموقع في حالة القراءة فقط" logout_disabled: "تسجيل الخروج معطّل عندما يكون الموقع في حاله القراءة فقط" too_few_topics_and_posts_notice: "دعونا الحصول على هذه المناقشة بدأت! يوجد حاليا%{currentTopics} / %{requiredTopics} المواضيع و %{currentPosts} / %{requiredPosts} المشاركات. الزوار الجدد بحاجة إلى بعض الأحاديث لقراءة والرد على." @@ -1001,7 +1001,7 @@ ar: logs_error_rate_notice: reached: "%{relativeAge}%{rate} وصل الحد الأعلى لإعدادت الموقع %{siteSettingRate}." exceeded: "%{relativeAge}%{rate} يتجاوز الحد الأعلى لإعدادت الموقع %{siteSettingRate}." - learn_more: "اقرأ اكثر .." + learn_more: "اطّلع على المزيد..." all_time: 'المجموع' all_time_desc: 'عدد المواضيع المنشأة' year: 'عام' @@ -1011,11 +1011,11 @@ ar: week: 'أسبوع' week_desc: ' المواضيع التي كتبت خلال 7 أيام الماضية' day: 'يوم' - first_post: الموضوع الأول + first_post: أوّل مشاركة mute: كتم unmute: إلغاء الكتم - last_post: أخر مشاركة - last_reply_lowercase: آخر رد + last_post: آخر مشاركة + last_reply_lowercase: آخر ردّ replies_lowercase: zero: الردود one: الردود @@ -1037,57 +1037,57 @@ ar: enable: 'لخّص هذا الموضوع' disable: 'أظهر كل المشاركات' deleted_filter: - enabled_description: "هذا الموضوع يحوي على مشاركات محذوفة تم اخفائها " - disabled_description: "المشاركات المحذوفة في هذا الموضوع ممكن مشاهدتها " - enable: "إخفاء المشاركات المحذوفة" - disable: "عرض المشاركات المحذوفة" + enabled_description: "في هذا الموضوع مشاركات محذوفة قد أُخفيت." + disabled_description: "المشاركات المحذوفة في الموضوع معروضة." + enable: "أخفِ المشاركات المحذوفة" + disable: "أظهر المشاركات المحذوفة" private_message_info: title: " رسالة خاصة" invite: " إدعو اخرين" - remove_allowed_user: "هل تريد حقا ازالة {{name}} من الرسائل الخاصة ؟" - remove_allowed_group: "هل تريد حقا ازالة {{name}} من هذه الرسالة ?" + remove_allowed_user: "أمتأكّد من إزالة {{name}} من هذه الرّسالة؟" + remove_allowed_group: "أمتأكّد من إزالة {{name}} من هذه الرّسالة؟" email: 'البريد الإلكتروني' username: 'إسم المستخدم' last_seen: 'شوهدت' created: 'مكتوبة' - created_lowercase: 'نُشر منذ' + created_lowercase: 'أُنشئ' trust_level: 'مستوى التقة' - search_hint: 'اسم مستخدم او بريد الكتروني او عنوان ايبي' + search_hint: 'اسم المستخدم، أو بريد إلكترونيّ أو عنوان IP' create_account: + disclaimer: "التّسجيل يعني موافقتك على سياسة الخصوصيّة وبنود الخدمة." title: "إنشاء حساب جديد" failed: "حدث خطأ ما, ربما بريدك الالكتروني مسجل مسبقا, جرب رابط نسيان كلمة المرور " forgot_password: title: " إعادة تعيين كلمة المرور" - action: "لقد نسيت رمزي السري" - invite: "ادخل اسم مستخدمك او بريدك الالكتروني وسنقوم بإرسال اعاذة ضبط كلمة المرور على بريدك" + action: "نسيتُ كلمة السّرّ" + invite: "أدخل اسم المستخدم أو البريد الإلكترونيّ وسنرسل بريدًا لتصفير كلمة السّرّ." reset: " إعادة تعين الرمز السري" - complete_username: "اذا كان اسم المسنخدم موجود %{username}, سيتم ارسال رسالة لبريدك لإعادة ضبط كلمة المرور " - complete_email: "اذا كان الحساب متطابق %{email}, سوف تستلم بريد الالكتروني يحوي على التعليمات لإعادة ضبط كلمة المرور" - complete_username_found: "وجدنا حساب متطابق مع المستخدم %{username}, سوف تستلم بريد الالكتروني يحوي على التعليمات لإعادة ضبط كلمة المرور" - complete_email_found: "وجدنا حساب متطابق مع %{email}, سوف تستلم بريد الالكتروني يحوي على التعليمات لإعادة ضبط كلمة المرور" + complete_username: "إن تطابق حساب ما مع اسم المستخدم %{username}، فيفترض أن تستلم قريبًا بريدًا به إرشادات تصفير كلمة السّرّ." + complete_email: "إن تطابق حساب ما مع %{email}، فيفترض أن تستلم قريبًا بريدًا به إرشادات تصفير كلمة السّرّ." + complete_username_found: "عثرنا على حساب يطابق اسم المستخدم %{username}. يفترض أن تستلم قريبًا بريدًا به إرشادات تصفير كلمة السر." + complete_email_found: "عثرنا على حساب يطابق %{email}. يفترض أن تستلم قريبًا بريدًا به إرشادات تصفير كلمة السر." complete_username_not_found: "لايوجد حساب متطابق مع هذا المستخدم %{username}" complete_email_not_found: "لايوجد حساب متطابق مع %{email}" login: title: "تسجيل الدخول" username: "المستخدم" - password: "كلمة المرور" + password: "كلمة السّرّ" email_placeholder: "البريد الإلكتروني أو اسم المستخدم" - caps_lock_warning: "حساسية الأحرف الإنقليزية Caps Lock في وضع التشغيل" + caps_lock_warning: "مفتاح Caps Lock مفعّل" error: "خطأ مجهول" rate_limit: "الرجاء اﻹنتظارقبل محاولة تسجيل الدخول مجدداً." - blank_username_or_password: "من فضلك أدخل اسم المستخدم أو البريد الإلكتروني وكلمة المرور." - reset_password: 'صفّر كلمة المرور' + blank_username_or_password: "رجاءً أدخل اسم المستخدم (أو البريد الإلكترونيّ) وكلمة السّرّ." + reset_password: 'صفّر كلمة السّرّ' logging_in: "...تسجيل الدخول " or: "أو " authenticating: "جارِ التحقق .. " - awaiting_confirmation: "ما زال حسابك غير مفعّل، استخدم رابط نسيان كلمة المرور لإرسال بريد إلكتروني تفعيلي آخر." - awaiting_approval: "لم يوافق أحد أعضاء الطاقم على حسابك بعد. سيُرسل إليك بريد حالما يتم ذلك." + awaiting_approval: "لم يوافق أيّ من أعضاء الطّاقم على حسابك بعد. سيُرسل إليك بريد حالما يتمّ ذلك." requires_invite: "المَعذرة، الوصول لهذا الموقع خاص بالمدعويين فقط." not_activated: "لا يُمكنك تسجيل الدخول حتى تقوم بتفعيل الحساب. لقد سبق و أن أرسلنا بريد إلكتروني إلى {{sentTo}} لتفعيل حسابك. الرجاء اتباع التعليمات المرسلة لتفعيل الحساب." not_allowed_from_ip_address: "لا يمكنك تسجيل الدخول من خلال هذا العنوان الرقمي - IP." admin_not_allowed_from_ip_address: "لا يمكنك تسجيل الدخول كمدير من خلال هذا العنوان الرقمي - IP." - resend_activation_email: "اضغط هنا لإرسال رسالة إلكترونية أخرى لتفعيل الحساب." - sent_activation_email_again: "لقد قمنا بإرسال رسالة التفعيل مرة أُخرى إلى {{currentEmail}} قد يستغرق وصول الإيميل عدة دقائق. لاتنسى أن تتأكد من مجلد Spam أيضاً. " + resend_activation_email: "انقر هنا لإرسال بريد التّفعيل مرّة أخرى." + sent_activation_email_again: "لقد أرسلنا بريد تفعيل آخر إلى {{currentEmail}}. قد يستغرق وصوله بضعة دقائق. تحقّق من فحص مجلّد السّخام." to_continue: "من فضلك قم بتسجيل دُخولك" preferences: "يتوجب عليك تسجيل الدخول لتغيير إعداداتك الشخصية." forgot: "لا أذكر معلومات حسابي" @@ -1153,14 +1153,21 @@ ar: saved_local_draft_tip: "حُفظ محليا" similar_topics: "موضوعك يشابه..." drafts_offline: "مسودات محفوظة " + group_mentioned: + zero: "الإشارة إلى {{group}} تعني عدم إخطار أحد. أمتأكّد؟" + one: "الإشارة إلى {{group}} تعني إخطار شخص واحد. أمتأكّد؟" + two: "الإشارة إلى {{group}} تعني إخطار شخصين. أمتأكّد؟" + few: "الإشارة إلى {{group}} تعني إخطار {{count}} أشخاص. أمتأكّد؟" + many: "الإشارة إلى {{group}} تعني إخطار {{count}} شخصًا. أمتأكّد؟" + other: "الإشارة إلى {{group}} تعني إخطار {{count}} شخص. أمتأكّد؟" duplicate_link: "يبدو أن الرابط المشير إلى {{domain}} قد نشره @{{username}} في الموضوع في رد له {{ago}} – أمتأكد من نشره مجددا؟" error: title_missing: "العنوان مطلوب" title_too_short: "العنوان يجب أن يكون اكثر {{min}} حرف" title_too_long: "العنوان يجب أن لا يكون أكثر من {{max}} حرف" - post_missing: "لا يمكن للمشاركة أن تكون خالية" + post_missing: "لا يمكن أن تكون المشاركة خالية" post_length: "التعليق يجب أن يكون أكثر {{min}} حرف" - try_like: 'هل جربت زر ؟' + try_like: 'هل جرّبت زرّ ؟' category_missing: "يجب اختيار احد الأقسام" save_edit: "حفظ التحرير" reply_original: "التعليق على الموضوع الاصلي" @@ -1169,17 +1176,17 @@ ar: cancel: "إلغاء" create_topic: "إنشاء موضوع" create_pm: "رسالة" - title: "او اضغط على Ctrl+Enter" + title: "أو اضغط Ctrl+Enter" users_placeholder: "أضف مستخدما" title_placeholder: "بجملة واحدة، ما الذي تود النقاش عنه؟" edit_reason_placeholder: "لماذا تعدّل النص؟" show_edit_reason: "(أضف سبب التعديل)" reply_placeholder: "اكتب ما تريد هنا. استخدم Markdown، أو BBCode، أو HTML للتنسيق. اسحب الصور أو ألصقها." - view_new_post: "الاطلاع على أحدث مشاركاتك" + view_new_post: "اعرض المشاركة الجديدة." saving: "يحفظ" saved: "حُفظ!" saved_draft: "جاري إضافة المسودة. اضغط للاستئناف" - uploading: "جارِ التحميل..." + uploading: "يرفع..." show_preview: 'أظهر المعاينة »' hide_preview: '« أخفِ المعاينة' quote_post_title: "اقتبس كامل المشاركة" @@ -1209,11 +1216,11 @@ ar: toggler: "اخف او اظهر صندوق التحرير" modal_ok: "حسنا" modal_cancel: "ألغِ" - cant_send_pm: "آسفون، لا يمكنك إرسال الرسائل إلى %{username} ." + cant_send_pm: "نأسف، لا يمكنك إرسال الرّسائل إلى %{username}." yourself_confirm: - title: "هل نسيت أن تضيف المرسل اليهم؟" + title: "أنسيت إضافة المستلمين؟" body: "حاليا هذة الرسالة مرسلة اليك فقط!" - admin_options_title: "اختياري اضافة اعدادات الموضوع" + admin_options_title: "إعدادات الطّاقم الاختياريّة لهذا الموضوع" auto_close: label: "وقت الإغلاق التلقائي للموضوع" error: "من فضلك أدخل قيمة صالحة." @@ -1268,10 +1275,10 @@ ar: private_message: 'أرسل {{username}} إليك رسالة خاصة في "{{topic}}" - {{site_title}}' linked: '{{username}} رتبط بمشاركتك من "{{topic}}" - {{site_title}}' upload_selector: - title: "اضف صورة" - title_with_attachments: "اضف صورة او ملف" - from_my_computer: "عن طريق جهازي" - from_the_web: "عن طريق الويب" + title: "أضف صورة" + title_with_attachments: "أضف صورة أو ملفّ" + from_my_computer: "من جهازي" + from_the_web: "من الوبّ" remote_tip: "رابط لصورة" remote_tip_with_attachments: "رابط لصورة أو ملف {{authorized_extensions}}" local_tip: "إختر صور من جهازك ." @@ -1289,7 +1296,7 @@ ar: most_liked: "الأكثر إعجابا" select_all: "أختر الكل" clear_all: "إلغ إختيار الكل" - too_short: "مصطلح البحث قصير جدا." + too_short: "عبارة البحث قصيرة جدًّا." result_count: zero: "لا نتائج ل‍ \"{{term}}\"" one: "نتيجة واحدة ل‍ \"{{term}}\"" @@ -1301,16 +1308,16 @@ ar: no_results: "لا نتائج." no_more_results: "لا نتائج أخرى." searching: "يبحث..." - post_format: "#{{post_number}} بواسطة {{username}}" + post_format: "#{{post_number}} كتبها {{username}}" context: - user: "البحث عن مواضيع @{{username}}" + user: "ابحث عن مواضيع @{{username}}" category: "ابحث في فئة #{{category}}" topic: "ابحث في هذا الموضوع" private_messages: "البحث في الرسائل الخاصة" advanced: - title: البحث التفصيلي + title: بحث متقدّم posted_by: - label: نُشرت بواسطة + label: نشرها in_category: label: في الفئة in_group: @@ -1320,26 +1327,28 @@ ar: with_tags: label: مع أوسمة filters: - label: استرجع فقط المواضيع/المشاركات التي... - likes: أعجبني - posted: شاركت في + label: ابحث عن المواضيع والمنشورات التي... + likes: أعجبتني + posted: شاركت فيها watching: التي أراقبها tracking: التي اتابعها - private: من ضمن رسائلي - bookmarks: أضفت للمفضلات + private: موجودة في رسائلي + bookmarks: أضفتها للعلامات first: تلك المشاركة الاولى + seen: قرأتها + unseen: لم أقرأها statuses: - label: عندما المواضيع + label: بشرط أن تكون المواضيع open: مفتوحة closed: مغلقة - archived: محفوظة - noreplies: لا تحتوي على رد - single_user: تحتوي على مستخدم واحد + archived: مؤرشفة + noreplies: ليس فيها أيّ ردّ + single_user: تحتوي مستخدما واحدا post: count: label: عدد المشاركات الأدنى time: - label: ا’رْسِلت + label: المُرسَلة before: قبل after: بعد hamburger_menu: "انتقل إلى قائمة مواضيع أو فئة أخرى" @@ -1375,7 +1384,6 @@ ar: few: "حددت {{count}} مواضيع." many: "حددت {{count}} موضوعا." other: "حددت {{count}} موضوع." - change_tags: "غيّر الوسوم" choose_new_tags: "اختر وسوم جديدة لهذه المواضيع:" changed_tags: "تغيرت وسوم هذه المواضيع." none: @@ -1408,12 +1416,12 @@ ar: stop_notifications: "ستستقبل الأن إشعارات أقل لـ{{title}}" change_notification_state: "حالة إشعارك الحالي هي " filter_to: - zero: "عدد الردود في الموضوع" - one: "رد في الموضوع" - two: "الردود في الموضوع" - few: "الردود في الموضوع" - many: "الردود في الموضوع " - other: "الردود في الموضوع " + zero: "لا مشاركات في الموضوع" + one: "مشاركة واحدة في الموضوع" + two: "مشاركتان في الموضوع" + few: "{{count}} مشاركات في الموضوع" + many: "{{count}} مشاركة في الموضوع" + other: "{{count}} مشاركة في الموضوع" create: 'موضوع جديد' create_long: 'كتابة موضوع جديد' private_message: 'أرسل رسالة خاصة' @@ -1449,7 +1457,7 @@ ar: title: "فشل تحميل الموضوع" description: "آسفون، تعذر علينا تحميل هذا الموضوع، قد يرجع ذلك إلى مشكلة بالاتصال. من فضلك حاول مجددا. أخبرنا بالمشكلة إن استمر حدوثها." not_found: - title: "لم يتم العثور على الموضوع" + title: "لم يُعثر على الموضوع" description: "آسفون، لم نجد هذا الموضوع. ربما أزاله أحد المشرفين؟" total_unread_posts: zero: "لا مشاركات غير مقروءة في هذا الموضوع" @@ -1485,14 +1493,14 @@ ar: toggle_information: "أظهر/أخف تفاصيل الموضوع" read_more_in_category: "أتريد قراءة المزيد؟ تصفح المواضيع الأخرى في {{catLink}} أو {{latestLink}}." read_more: "أتريد قراءة المزيد؟ {{catLink}} أو {{latestLink}}." - read_more_MF: "{UNREAD, plural, zero {} one {تبقى {BOTH, select, true {موضوع واحد غير مقروء و} false {موضوع واحد غير مقروء} other {}}} two {تبقى {BOTH, select, true {موضوعان غير مقروءان و} false {موضوعان غير مقروءان} other {}}} few {تبقت {BOTH, select, true {# مواضيع غير مقروءة و} false {# مواضيع غير مقروءة} other {}}} many {تبقى {BOTH, select, true {# موضوعا غير مقروء و} false {# موضوعا غير مقروء} other {}}} other {تبقى {BOTH, select, true {# موضوع غير مقروء و} false {# موضوع غير مقروء} other {}}}}{NEW, plural, zero {} one {{UNREAD, plural, zero {تبقى } one {} two {} few {} many {} other {}}موضوع واحد جديد} two {{UNREAD, plural, zero {تبقى } one {} two {} few {} many {} other {}}موضوعان جديدان} few {{UNREAD, plural, zero {تبقت } one {} two {} few {} many {} other {}}# مواضيع جديدة} many {{UNREAD, plural, zero {تبقى } one {} two {} few {} many {} other {}}# موضوعا جديدا} other {{UNREAD, plural, zero {تبقى } one {} two {} few {} many {} other {}}# موضوع جديد}}، أو {CATEGORY, select, true {تصفّح المواضيع الأخرى في {catLink}} false {{latestLink}} other {}}" + read_more_MF: "{UNREAD, plural, zero {} one {تبقى موضوع واحد غير مقروء} two {تبقى موضوعان غير مقروءان} few {تبقت # مواضيع غير مقروءة} many {تبقى # موضوعا غير مقروء} other {تبقى # موضوع غير مقروء}}{BOTH, select, true { و} false {} other {}}{NEW, plural, zero {} one {{UNREAD, plural, zero {تبقى } one {} two {} few {} many {} other {}}موضوع واحد جديد} two {{UNREAD, plural, zero {تبقى } one {} two {} few {} many {} other {}}موضوعان جديدان} few {{UNREAD, plural, zero {تبقت } one {} two {} few {} many {} other {}}# مواضيع جديدة} many {{UNREAD, plural, zero {تبقى } one {} two {} few {} many {} other {}}# موضوعا جديدا} other {{UNREAD, plural, zero {تبقى } one {} two {} few {} many {} other {}}# موضوع جديد}}، أو {CATEGORY, select, true {تصفّح المواضيع الأخرى في {catLink}} false {{latestLink}} other {}}" browse_all_categories: تصفّح كل الأقسام view_latest_topics: اعرض أحدث المواضيع suggest_create_topic: لمَ لا تكتب موضوعًا؟ jump_reply_up: انتقل إلى أول رد jump_reply_down: انتقل إلى آخر رد deleted: "الموضوع محذوف" - auto_close_notice: "سيُغلق الموضوع آليا بعد %{timeLeft}." + auto_close_notice: "سيُغلق الموضوع آليًّا %{timeLeft}." auto_close_notice_based_on_last_post: "سيُغلق الموضوع بعد %{duration} من آخر رد." auto_close_title: 'إعدادات الإغلاق الآلي' auto_close_save: "احفظ" @@ -1535,13 +1543,13 @@ ar: title: "مُراقب" description: "سيصلك إشعار لكل رد جديد لهذه الرسالة، وسيظهر عدد الردود الجديدة." watching: - title: "مُراقب" + title: "مراقَبًا" description: "سيصلك إشعار لكل رد جديد لهذا الموضوع، وسيظهر عدد الردود الجديدة." tracking_pm: title: "مُتابع" description: "سيظهر عدد الردود الجديدة لهذه الرسالة. سيصلك إشعار إن أشار أحد إلى @اسمك أو رد عليك." tracking: - title: "مُتابع" + title: "متابَعًا" description: "سيظهر عدد الردود الجديدة لهذا الموضوع. سيصلك إشعار إن أشار أحد إلى @اسمك أو رد عليك." regular: title: "الوضع العادي" @@ -1641,7 +1649,7 @@ ar: title: 'دعوة' username_placeholder: "اسم المستخدم" action: 'أرسل دعوة' - help: 'دعوة المستخدمين لهذا الموضوع عن طرق البريد الإلكتروني أو الأشعارات' + help: 'ادعُ الغير إلى هذا الموضوع عبر البريد الإلكترونيّ أو الإشعارات' to_forum: "سيتم ارسال رسالة بريد الكتروني ﻷصدقائك للمشاركة في الموقع , هذه العملية لا تتطلب تسجيل الدخول ." sso_enabled: "أدخل اسم مَن تريد دعوته إلى هذا الموضوع." to_topic_blank: "أدخل اسم مَن تريد دعوته إلى هذا الموضوع أو بريده." @@ -1686,7 +1694,7 @@ ar: many: "الرجاء اختيار الموضوع الذي تود نقل الـ{{count}} مشاركة إليه." other: "الرجاء اختيار الموضوع الذي تود نقل الـ{{count}} مشاركة إليه." merge_posts: - title: "قم بدمج المشاركات المختارة" + title: "ادمج المشاركات المحدّدة" action: "ادمج المشاركات المحددة" error: "حدث خطأ في دمج المشاركات المحددة." change_owner: @@ -1708,7 +1716,7 @@ ar: action: "تغيير الطابع الزمني" invalid_timestamp: "الطابع الزمني لا يمكن أن يكون في المستقبل." error: "هناك خطأ في نغيير الطابع الزمني للموضوع." - instructions: "من فضلك اختر الطابع الزمني الجديد للموضوع. ستُحدث المشاركات فيه لألا يختلف فرق تاريخ نشرها ووقته." + instructions: "من فضلك اختر الطابع الزمني الجديد للموضوع. ستُحدّث المشاركات فيه لألا يختلف فرق تاريخ نشرها ووقته." multi_select: select: 'حددها' selected: 'محددة ({{count}})' @@ -1733,7 +1741,7 @@ ar: post_number: "المشاركة {{number}}" last_edited_on: "آخر تعديل على المشاركة في " reply_as_new_topic: "التعليق على الموضوع الاصلي" - continue_discussion: "إكمال النقاش على {{postLink}}" + continue_discussion: "إكمالا للنّقاش في {{postLink}}:" follow_quote: "الذهاب إلى المشاركة المقتبسة" show_full: "عرض كامل المشاركة" show_hidden: 'عرض المحتوى المخفي.' @@ -1768,20 +1776,20 @@ ar: many: "{{count}} إعجابا" other: "{{count}} إعجاب" has_likes_title: - zero: "لم تعجب هذه المشاركة أحد" + zero: "لم تُعجب هذه المشاركة أحد" one: "أعجبت هذه المشاركة شخصا واحدا" two: "أعجبت هذه المشاركة شخصين" few: "أعجبت هذه المشاركة {{count}} أشخاص" many: "أعجبت هذه المشاركة {{count}} شخصا" - other: "{{count}} أشخاص أعجبوا بهذه المشاركة" - has_likes_title_only_you: "أنت أعجبت بهذه المشاركة" + other: "أعجبت هذه المشاركة {{count}} شخص" + has_likes_title_only_you: "أعجبتك هذه المشاركة" has_likes_title_you: zero: "أعجبتك هذه المشاركة" - one: "أعجبت هذه المشاركة شخصا واحدا غيرك" + one: "أعجبت هذه المشاركة شخصًا واحدًا غيرك" two: "أعجبت هذه المشاركة شخصين غيرك" few: "أعجبت هذه المشاركة {{count}} أشخاص غيرك" - many: "أعجبت هذه المشاركة {{count}} شخصا غيرك" - other: "أنت و {{count}} شخص أخرون أعجبتم بهذه المشاركة ." + many: "أعجبت هذه المشاركة {{count}} شخصًا غيرك" + other: "أعجبت هذه المشاركة {{count}} شخص غيرك" errors: create: "آسفون، حدثت مشكلة في إنشاء المشاركة. من فضلك حاول مجددا." edit: "آسفون، حدثت مشكلة في تعديل المشاركة. من فضلك حاول مجددا." @@ -2027,7 +2035,7 @@ ar: settings: 'اعدادات' topic_template: "إطار الموضوع" tags: "الوسوم" - tags_allowed_tags: "العلامات الوصفية التي تستخدم فقط في هذا القسم:" + tags_allowed_tags: "ما يمكن استخدامه من وسوم في هذه الفئة فقط:" tags_allowed_tag_groups: "مجموعات العلامات الوصفية التي تستخدم فقط في هذا القسم:" tags_placeholder: "(اختياري) قائمة العلامات الوصفية المسموح بها" tag_groups_placeholder: "(اختياري) قائمة مجموعات العلامات الوصفية المسموح بها" @@ -2062,7 +2070,7 @@ ar: auto_close_units: "ساعات" email_in: "تعيين بريد إلكتروني خاص:" email_in_allow_strangers: "قبول بريد إلكتروني من مستخدمين لا يملكون حسابات" - email_in_disabled: "إضافة مواضيع جديدة من خلال البريد الإلكتروني موقوف في الوقت الحالي من خلال إعدادات الموقع. لتفعيل إضافة مواضيع جديدة من خلال البريد الإلكتروني," + email_in_disabled: "عُطّل إرسال المشاركات عبر البريد الإلكترونيّ من إعدادات الموقع. لتفعيل نشر المشاركات الجديدة عبر البريد،" email_in_disabled_click: 'قم بتفعيل خيار "email in" في الإعدادات' suppress_from_homepage: "كتم هذه الفئة من الصفحة الرئيسية" allow_badges_label: "السماح بالحصول على الأوسمة في هذا التصنيف" @@ -2086,7 +2094,7 @@ ar: description: "ستتابع آليا كل مواضيع هذه الفئات. ستصلك إشعارات إن أشار أحدهم إلى @اسمك أو رد عليك، وسيظهر عدّاد للمشاركات الجديدة." regular: title: "منتظم" - description: "سوف تُنبه اذا قام أحد بالاشارة لاسمك \"@name\" أو الرد عليك." + description: "ستستقبل إشعارًا إن أشار أحد إلى @اسمك أو ردّ عليك." muted: title: "مكتومة" description: "لن يتم إشعارك بأي مشاركات جديدة في هذه التصنيفات ولن يتم عرضها في قائمة المواضيع المنشورة مؤخراً." @@ -2123,12 +2131,12 @@ ar: custom_placeholder_notify_moderators: "ممكن تزودنا بمعلومات أكثر عن سبب عدم ارتياحك حول هذه المشاركة؟ زودنا ببعض الروابط و الأمثلة قدر الإمكان." custom_message: at_least: - zero: "عدد الأحرف يجب ان لا يقل عن {{count}} حرف" - one: "عدد الأحرف يجب ان لا يقل عن {{count}} حرف" - two: "عدد الأحرف يجب ان لا يقل عن {{count}} حرف" - few: "عدد الأحرف يجب ان لا يقل عن {{count}} حروف" - many: "عدد الأحرف يجب ان لا يقل عن {{count}} حرف" - other: "عدد الأحرف يجب ان لا يقل عن {{count}} حرف" + zero: "لا تُدخل أيّ محرف" + one: "أدخل محرفًا واحدًا على الأقلّ" + two: "أدخل محرفين على الأقلّ" + few: "أدخل {{count}} محارف على الأقلّ" + many: "أدخل {{count}} محرفًا على الأقلّ" + other: "أدخل {{count}} محرف على الأقلّ" flagging_topic: title: "شكرا لمساعدتنا في ابقاء مجتمعنا نضيفا" action: "التبليغ عن الموضوع" @@ -2231,13 +2239,13 @@ ar: few: "الأخيرة ({{count}})" many: "الأخيرة ({{count}})" other: "الأخيرة ({{count}})" - help: "المواضيع التي أضيفت لها ردود مؤخراً" + help: "المواضيع التي فيها مشاركات حديثة" hot: title: "نَشط" help: "مختارات من مواضيع ساخنة" read: title: "المقروءة" - help: "مواضيع قمت بقراءتها بترتيب آخر قراءة" + help: "المواضيع التي قرأتها بترتيب آخر قراءة لها" search: title: "بحث" help: "بحث في كل المواضيع" @@ -2254,7 +2262,7 @@ ar: few: "غير المقروءة ({{count}})" many: "غير المقروءة ({{count}})" other: "غير المقروءة ({{count}})" - help: "مواضيع أنت تشاهدها بمشاركات غير مقروءة " + help: "المواضيع التي تتابعها (أو تراقبها) والتي فيها مشاركات غير مقروءة" lower_title_with_count: zero: "1 غير مقررء " one: "1 غير مقروء" @@ -2284,7 +2292,7 @@ ar: title: "مشاركاتي" help: "مواضيع شاركت بها " bookmarks: - title: "المفضلة" + title: "العلامات" help: "مواضيع قمت بتفضيلها" category: title: "{{categoryName}}" @@ -2451,7 +2459,7 @@ ar: description: "ستتابع آليا كل مواضيع هذا الوسم. سيظهر عدّاد للمشاركات غير المقروءة والجديدة بجانب الموضوع." regular: title: "موضوع عادي" - description: ".سيتم إشعارك إذا ذكر أحد ما اسمك أو رد على مشاركاتك" + description: "ستستقبل إشعارًا إن أشار أحد إلى @اسمك أو ردّ على مشاركتك." muted: title: "مكتوم" description: "لن يتم إشعارك بأي جديد يخص هذا الموضوع ولن يظهرهذا الموضوع في تبويب المواضيع الغير مقروءة." @@ -2833,7 +2841,7 @@ ar: undo: "تراجع" undo_title: "التراجع عن تغيير اللن الى اللون السابق" revert: "تراجع" - revert_title: "اعادة ضبط اللون الى اللون الافتراضي للموقع" + revert_title: "صفّر هذا اللون إلى مخطّط ألوان دسكورس الافتراضيّ." primary: name: 'الأساسي' secondary: @@ -3357,7 +3365,7 @@ ar: enabled: تفعيل الشعار icon: أيقونة image: صورة - icon_help: "إستخدم فئة الخط او رابط الى صورة" + icon_help: "استخدم صنف Font Awesome أو عنوانًا إلى صورة" query: علامة استفهام (SQL) target_posts: إستعلام يستهدف المشاركات auto_revoke: إلغاء الاستعلام اليومي @@ -3377,7 +3385,7 @@ ar: sql_error_header: "كان هناك خطأ ما في الاستعلام." error_help: "انظر الرابط التالي للمساعدة باستفسارات الوسام." bad_count_warning: - header: "تحذير !!" + header: "تحذير!" text: "هناك عينات ممنوحة ضائعة. حدث هذا عندما أعادت شارة الإستعلام user IDs أو post IDs التي لم تكن موجودة. هذا ربما بسبب نتيجة غير متوقعة في وقت لاحق - رجائا أنقر مرتين للتأكد من إستعلامك-" no_grant_count: "لا توجد اوسمه لتمنح " grant_count: @@ -3399,10 +3407,10 @@ ar: add: "أضافة وجه تعبيري جديد ؟" name: "الأسم" image: "صورة" - delete_confirm: "هل أنت متأكد من انك تريد حذف هذا :%{name}: الوجه التعبيري ؟" + delete_confirm: "أمتأكّد من حذف الإيموجي :%{name}: هذا؟" embedding: get_started: "إذا أردت تضمين Discourse في موقع اخر، أبدأ بإضافة مضيف." - confirm_delete: "هل انت متأكد من انك تريد حذف هذا المضيف ؟" + confirm_delete: "أمتأكّد من حذف هذا المضيف؟" sample: "استخدم كود HTML التالي لموقعك لإنشاء وتضمين موضوع discourse. استبدل REPLACE_ME مع canonical URL لصفحة قمت بتضمينها فيه." title: "تضمين" host: "أسمع بالمضيفين" @@ -3446,18 +3454,18 @@ ar: next: "التالي" step: "%{current} من %{total}" upload: "رفع" - uploading: "جاري رفع الملفات.." + uploading: "يرفع..." quit: "ربما لاحقا" staff_count: - zero: "شركتك لديها %{count} من الموظفين" - one: "مجموعتك لديها 1 موظف فقط" - two: "مجموعتك لديها %{count} من الموظفين" - few: "مجموعتك لديها %{count} من الموظفين" - many: "مجموعتك لديها %{count} من الموظفين" - other: "مجموعتك لديها %{count} من الموظفين" + zero: "ليس في المجتمع أيّ أعضاء طاقم." + one: "في المجتمع عضو طاقم واحد." + two: "في المجتمع عضوا طاقم." + few: "في المجتمع %{count} أعضاء طاقم." + many: "في المجتمع %{count} عضو طاقم." + other: "في المجتمع %{count} عضو طاقم." invites: add_user: "أضف" - none_added: "لم تقم بدعوة أي موظفين. هل أنت متأكد انك تريد المتابعة؟" + none_added: "لم تدعو أيّ عضو طاقم. أمتأكّد من المتابعة؟" roles: admin: "مدير" moderator: "مشرف" diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml index ab1b365875..8dc7f4753d 100644 --- a/config/locales/client.de.yml +++ b/config/locales/client.de.yml @@ -136,7 +136,7 @@ de: enabled: 'sichtbar gemacht, %{when}' disabled: 'unsichtbar gemacht, %{when}' topic_admin_menu: "Thema administrieren" - wizard_required: "Es ist an der Zeit, Dein Forum einzurichten! Einrichtungs-Assistenten starten!" + wizard_required: "Willkommen bei deinem neuen Discourse! Lass uns mit dem Setup-Assistenten ✨ starten" emails_are_disabled: "Die ausgehende E-Mail-Kommunikation wurde von einem Administrator global deaktiviert. Es werden keinerlei Benachrichtigungen per E-Mail verschickt." bootstrap_mode_enabled: "Damit du mit deiner Seite einfacher loslegen kannst, befindest du dich im Starthilfe-Modus. Alle neuen Benutzer erhalten die Vertrauensstufe 1 und bekommen eine tägliche E-Mail-Zusammenfassung. Der Modus wird automatisch deaktiviert, sobald sich mindestens %{min_users} Benutzer angemeldet haben." bootstrap_mode_disabled: "Der Starthilfe-Modus wird innerhalb der nächsten 24 Stunden deaktiviert." @@ -928,7 +928,7 @@ de: logging_in: "Anmeldung läuft…" or: "Oder" authenticating: "Authentifiziere…" - awaiting_confirmation: "Dein Konto ist noch nicht aktiviert. Verwende den 'Passwort vergessen'-Link, um eine weitere E-Mail mit Anweisungen zur Aktivierung zu erhalten." + awaiting_activation: "Dein Konto ist noch nicht aktiviert. Verwende den 'Passwort vergessen'-Link, um eine weitere E-Mail mit Anweisungen zur Aktivierung zu erhalten." awaiting_approval: "Dein Konto wurde noch nicht von einem Team-Mitglied genehmigt. Du bekommst eine E-Mail, sobald das geschehen ist." requires_invite: "Entschuldige, der Zugriff auf dieses Forum ist nur mit einer Einladung möglich." not_activated: "Du kannst dich noch nicht anmelden. Wir haben dir schon eine E-Mail zur Aktivierung an {{sentTo}} geschickt. Bitte folge den Anweisungen in dieser E-Mail, um dein Benutzerkonto zu aktivieren." @@ -965,6 +965,7 @@ de: accept_title: "Einladung" welcome_to: "Willkommen bei %{site_name}!" invited_by: "Du wurdest eingeladen von: " + social_login_available: "Du wirst dich auch über andere sozialen Netzwerken mit dieser E-Mail-Adresse anmelden können." your_email: "Die E-Mail-Adresse deines Benutzerkontos ist %{email}" accept_invite: "Einladung annehmen" success: "Dein Konto wurde erstellt und du bist jetzt angemeldet." @@ -1191,6 +1192,8 @@ de: first: sind die allerersten Beiträge pinned: sind angeheftet unpinned: sind nicht angeheftet + seen: Habe ich gelesen + unseen: Habe ich nicht gelesen wiki: sind Wiki statuses: label: Wo Themen @@ -1235,8 +1238,10 @@ de: selected: one: "Du hast ein Thema ausgewählt." other: "Du hast {{count}} Themen ausgewählt." - change_tags: "Schlagwörter ändern" + change_tags: "Schlagwörter ersetzen" + append_tags: "Schlagwörter hinzufügen" choose_new_tags: "Neue Schlagwörter für die gewählten Themen wählen:" + choose_append_tags: "Wähle neue Schlagwörter, die diesen Themen hinzugefügt werden sollen:" changed_tags: "Die Schlagwörter der gewählten Themen wurden geändert." none: unread: "Du hast alle Themen gelesen." @@ -1729,6 +1734,17 @@ de: side_by_side_markdown: title: "Zeige die Originaltexte zum Vergleich nebeneinander an" button: 'Quelltext' + raw_email: + displays: + raw: + title: "Zeige den Quelltext der E-Mail" + button: 'Quelltext' + text_part: + title: "Zeige den Text-Teil der E-Mail" + button: 'Text' + html_part: + title: "Zeige den HTML-Teil der E-Mail" + button: 'HTML' category: can: 'kann… ' none: '(keine Kategorie)' @@ -1780,8 +1796,12 @@ de: email_in_disabled: "Das Erstellen von neuen Themen per E-Mail ist in den Website-Einstellungen deaktiviert. Um das Erstellen von neuen Themen per E-Mail zu erlauben," email_in_disabled_click: 'aktiviere die Einstellung „email in“.' suppress_from_homepage: "Löse diese Kategorie von der Startseite." + show_subcategory_list: "Zeige Liste von Unterkategorien oberhalb von Themen in dieser Kategorie" + num_featured_topics: "Anzahl der Themen, die auf der Kategorien-Seite angezeigt werden" + subcategory_num_featured_topics: "Anzahl beworbener Themen, die auf der Seite der übergeordneten Kategorie angezeigt werden:" all_topics_wiki: "Mache neue Themen standardmäßig zu Wikis." sort_order: "Standardsortierung:" + default_view: "Standardansicht:" allow_badges_label: "Erlaube das Verleihen von Abzeichen in dieser Kategorie." edit_permissions: "Berechtigungen bearbeiten" add_permission: "Berechtigung hinzufügen" @@ -1916,7 +1936,7 @@ de: history: "Verlauf" changed_by: "von {{author}}" raw_email: - title: "Unverarbeitete E-Mail" + title: "Eingegangene E-Mail" not_available: "Nicht verfügbar!" categories_list: "Liste der Kategorien" filters: @@ -2319,6 +2339,8 @@ de: add_owners: Eigentümer hinzufügen incoming_email: "Benutzerdefinierte Adresse für eingehende E-Mails" incoming_email_placeholder: "E-Mail-Adresse eingeben" + none_selected: "Wähle eine Gruppe, um loszulegen" + no_custom_groups: "Erstelle eine neue benutzerdefinierte Gruppe" api: generate_master: "Master API Key erzeugen" none: "Es gibt momentan keine aktiven API-Keys" @@ -2454,7 +2476,8 @@ de: without_uploads: "Ja (ohne Dateien)" download: label: "Herunterladen" - title: "Backup herunterladen" + title: "Sende E-Mail mit Download-Link" + alert: "Ein Link zum Download dieses Backups wurde dir per E-Mail geschickt." destroy: title: "Das Backup löschen" confirm: "Möchtest du wirklich das Backup löschen?" @@ -2810,6 +2833,7 @@ de: refresh_browsers_message: "Nachricht wurde an alle Clients gesendet!" show_public_profile: "Zeige öffentliches Profil" impersonate: 'Nutzersicht' + action_logs: "Aktionsprotokoll" ip_lookup: "IP-Abfrage" log_out: "Abmelden" logged_out: "Der Benutzer wurde auf allen Geräten abgemeldet" diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 59e857c30d..cd3f3d15b1 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -162,6 +162,9 @@ en: visible: enabled: 'listed %{when}' disabled: 'unlisted %{when}' + banner: + enabled: 'made this a banner %{when}. It will appear at the top of every page until it is dismissed by the user.' + disabled: 'removed this banner %{when}. It will no longer appear at the top of every page.' topic_admin_menu: "topic admin actions" @@ -1316,6 +1319,8 @@ en: first: are the very first post pinned: are pinned unpinned: are not pinned + seen: I've read + unseen: I've not read wiki: are wiki statuses: label: Where topics @@ -1918,6 +1923,18 @@ en: title: "Show the raw source diffs side-by-side" button: 'Raw' + raw_email: + displays: + raw: + title: "Show the raw email" + button: 'Raw' + text_part: + title: "Show the text part of the email" + button: 'Text' + html_part: + title: "Show the html part of the email" + button: 'HTML' + category: can: 'can… ' none: '(no category)' @@ -1973,8 +1990,9 @@ en: num_featured_topics: "Number of topics shown on the categories page:" subcategory_num_featured_topics: "Number of featured topics on parent category's page:" all_topics_wiki: "Make new topics wikis by default." - sort_order: "Default Sort:" - default_view: "Default View:" + subcategory_list_style: "Subcategory List Style:" + sort_order: "Topic List Sort By:" + default_view: "Default Topic List:" allow_badges_label: "Allow badges to be awarded in this category" edit_permissions: "Edit Permissions" add_permission: "Add Permission" @@ -2012,6 +2030,11 @@ en: created: "Created" sort_ascending: 'Ascending' sort_descending: 'Descending' + subcategory_list_styles: + rows: "Rows" + rows_with_featured_topics: "Rows with featured topics" + boxes: "Boxes" + boxes_with_featured_topics: "Boxes with featured topics" flagging: title: 'Thanks for helping to keep our community civil!' @@ -2123,7 +2146,7 @@ en: changed_by: "by {{author}}" raw_email: - title: "Raw Email" + title: "Incoming Email" not_available: "Not available!" categories_list: "Categories List" @@ -2554,6 +2577,8 @@ en: add_owners: Add owners incoming_email: "Custom incoming email address" incoming_email_placeholder: "enter email address" + none_selected: "Select a group to get started" + no_custom_groups: "Create a new custom group" api: generate_master: "Generate Master API Key" diff --git a/config/locales/client.et.yml b/config/locales/client.et.yml index 2b928b360b..d34bb44eef 100644 --- a/config/locales/client.et.yml +++ b/config/locales/client.et.yml @@ -214,6 +214,7 @@ et: like_count: "Meeldimisi" topic_count: "Teemad" post_count: "Postitused" + user_count: "Kasutajaid" active_user_count: "Aktiivsed kasutajad" contact: "Võta meiega ühendust" contact_info: "Kriitilise vea või edasilükkamatu probleemi korral võta palun meiega ühendust aadressil %{contact_info}." @@ -504,7 +505,7 @@ et: disable: "Keela teavitused" enable: "Luba teavitused" each_browser_note: "Märkus: see säte tuleb muuta igas kasutusel olevas brauseris." - dismiss_notifications: "Lükka kõik tagasi" + dismiss_notifications: "Ignoreeri kõiki" dismiss_notifications_tooltip: "Märgi kõik lugemata teavitused loetuks" first_notification: "Sinu esimene teavitus! Vali see et alustada." disable_jump_reply: "Ära hüppa minu postitusse peale vastamist" @@ -624,6 +625,7 @@ et: instructions: "Taustapildidd tsentreeritakse ja on vaikimisi 590 pikslit laiad." email: title: "Meiliaadress" + instructions: "ei näidata kunagi avalikult" ok: "Saadame sulle kinnituseks meili" invalid: "Sisesta palun korrektne meiliaadress" authenticated: "Sinu meil on autenditud {{provider}} poolt" @@ -633,14 +635,17 @@ et: other: "Saadame meili vaid siis, kui pole Sind viimase {{count}} minuti jooksul näinud." name: title: "Nimi" + instructions: "sinu täisnimi (mittekohustuslik)" instructions_required: "Sinu täisnimi" too_short: "Sinu antud nimi on liiga lühike" ok: "Paistab, et nimega on asjad korras" username: title: "Kasutajanimi" + instructions: "unikaalne, tühikuteta, lühike" short_instructions: "Inimesed võivad sind mainda nimega @{{username}}" available: "Sinu poolt valitud kasutajanimi on vaba" not_available: "Pole saadaval. Proovime {{suggestion}}?" + not_available_no_suggestion: "Pole saadaval" too_short: "Sinu poolt valitud kasutajanimi on liiga lühike" too_long: "Sinu poolt valitud kasutajanimi on liiga pikk" checking: "Teen kindlaks, kas kasutajanimi on vaba..." @@ -741,8 +746,10 @@ et: link_generated: "Kutse link edukalt genereeritud!" valid_for: "Kutse link kehtib vaid meiliaadressile: %{email}" bulk_invite: + none: "Sa pole veel kedagi siia kutsunud. Saada üksikuid kutseid või paljudele korraga laadides üles CSV faili." text: "Masskutse Failist" success: "Fail edukalt üles laetud. Sulle saabub teade, kui protsess on lõpule jõudnud." + error: "Vabandust, fail peab olema CSV vormingus." password: title: "Parool" too_short: "Parool on liiga lühike." @@ -750,6 +757,7 @@ et: same_as_username: "Parool ühtib sinu kasutajanimega." same_as_email: "Parool ühtib sinu meiliaadressiga." ok: "See parool on sobilik." + instructions: "vähemalt %{count} tähemärki" summary: title: "Kokkuvõte" stats: "Statistika" @@ -931,6 +939,7 @@ et: to_continue: "Palun logi sisse" preferences: "Oma kasutajaeelistuste muutmiseks pead olema sisse logitud." forgot: "Ma ei mäleta oma konto üksikasju" + not_approved: "Kontot pole veel kinnitatud. Teid teavitatakse e-post teel, kui sisselogimine on võimaldatud." google: title: "Google abil" message: "Autentimine Google abil (veendu, et hüpikaknad oleks lubatud)" @@ -952,6 +961,17 @@ et: github: title: "GitHub abil" message: "Autentimine GitHub abil (veendu, et hüpikaknad oleks lubatud)" + invites: + accept_title: "Kutse" + welcome_to: "Teretulemast saidile %{site_name}!" + invited_by: "Teid kutsus:" + social_login_available: "Saate sisse logida ka sotsiaalvõrgustike abil, mis kasutavad seda meiliaadressi." + your_email: "Teie konto meiliaadress on %{email}." + accept_invite: "Võta kutse vastu" + success: "Teie konto on loodud ning olete nüüd sisse logitud." + password_label: "Määra parool (mittekohustuslik)" + password_reset: + continue: "Edasi saidile %{site_name}" emoji_set: apple_international: "Apple/International" google: "Google" @@ -1200,12 +1220,12 @@ et: unlist_topics: "Eemalda teemad loetelust" reset_read: "Nulli loetud" delete: "Kustuta teemad" - dismiss: "Lükka tagasi" - dismiss_read: "Lükka tagasi kõik lugemata" - dismiss_button: "Lükkan tagasi..." - dismiss_tooltip: "Lükka tagasi ainult uued postitused või lõpeta teemade jälgimine" + dismiss: "Ignoreeri" + dismiss_read: "Ignoreeri lugemata" + dismiss_button: "Ignoreeri..." + dismiss_tooltip: "Ignoreeri ainult uusi postitusi või lõpeta teemade jälgimine" also_dismiss_topics: "Lõpeta nende teemade jälgimine. Soovin, et neid enam kunagi kui lugemata teemasid esile ei tõstetaks" - dismiss_new: "Lükka tagasi uued" + dismiss_new: "Ignoreeri uusi" toggle: "lülita teemade massiline ära märkimine ümber" actions: "Masstoimingud" change_category: "Muuda foorumit" @@ -1216,8 +1236,10 @@ et: selected: one: "Märkisid ära 1 teema." other: "Märkisid ära {{count}} teemat." - change_tags: "Muuda silte" + change_tags: "Asenda sildid" + append_tags: "Lisa sildid" choose_new_tags: "Vali teemadele uued sildid:" + choose_append_tags: "Vali uued sildid, mida nendele teemadele lisada:" changed_tags: "Nende teemade silte on muudetud." none: unread: "Sul ei ole lugemata teemasid." @@ -1323,6 +1345,7 @@ et: go_bottom: "alla" go: "mine" jump_bottom: "hüppa viimase postituse juurde" + jump_prompt: "mine..." jump_prompt_of: "%{count} postitusest" jump_prompt_long: "Millise postituse juurde soovid hüpata?" jump_bottom_with_number: "hüppa postituse %{post_number} juurde" @@ -1393,6 +1416,9 @@ et: pin_globally: "Tõsta teema esile igal pool" make_banner: "Tee teema bänneriks" remove_banner: "Eemalda teema bännerist" + reply: + title: 'Vasta' + help: 'kirjuta sellele teemale vastus' clear_pin: title: "Kustuta esiletõstmine" help: "Eemalda sellelt teemalt esiletõstetu staatus nii, et ta enam ei ilmuks teemade loetelu tipus" @@ -1518,8 +1544,10 @@ et: edit: "Redigeerin {{link}} {{replyAvatar}} {{username}}" edit_reason: "Põhjus:" post_number: "postitus {{number}}" + wiki_last_edited_on: "viimati muudeti wikit" last_edited_on: "postitus viimati muudetud" reply_as_new_topic: "Vasta viitega teemale" + reply_as_new_private_message: "Vasta uue sõnumina samadele adressaatidele" continue_discussion: "Jätkates vestlust viitelt {{postLink}}:" follow_quote: "mine tsiteeritud postituse juurde" show_full: "Näita kogu postitust" @@ -1552,6 +1580,7 @@ et: file_too_large: "Vabandame. see fail on liiga suur (maksimum on {{max_size_kb}}kB). Miks mitte laadida see suur fail mõnda failijagamisteenusesse pilves ja jagada viidet selleni?" too_many_uploads: "Vabandame, faile saab üles laadida vaid ühekaupa." too_many_dragged_and_dropped_files: "Vabandame, faile saab üles laadida vaid kuni 10 korraga." + upload_not_authorized: "Vabandust, fail mida püüad üles laadida, ei ole lubatud (lubatud faililaiendid: {{authorized_extensions}})." image_upload_not_allowed_for_new_user: "Vabandame, uued kasutajad ei saa pilte üles laadida." attachment_upload_not_allowed_for_new_user: "Vabandame, uued kasutajad ei saa manuseid üles laadida." attachment_download_requires_login: "Vabandame, manuste allalaadimiseks pead olema sisse logitud." @@ -1562,6 +1591,8 @@ et: via_email: "see postitus saabus meili teel" via_auto_generated_email: "see postitus saabus automaatselt genereeritud meili teel" whisper: "see postitus on vaikne sosin moderaatoritele" + wiki: + about: "see postitus on wiki" archetypes: save: 'Salvesta suvandid' few_likes_left: "Aitäh poolehoiu jagamise eest! Tänaseks on vaid mõned meeldimised jäänud jagada." @@ -1688,14 +1719,19 @@ et: hide: "Peida redaktsioon" show: "Näita redaktsiooni" revert: "Ennista selleks redaktsiooniks" + edit_wiki: "Muuda wikit" + edit_post: "Muuda postitust" comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" displays: inline: title: "Näita renderdatud väljundit koos lisamiste ja eemaldamistega tekstisiseselt" + button: 'HTML' side_by_side: title: "Näita renderdatud väljundi erinevusi kõrvuti" + button: 'HTML' side_by_side_markdown: title: "Näita töötlemata lähteandmete erinevusi kõrvuti" + button: 'Töötlemata' category: can: 'saab… ' none: '(foorum puudub)' @@ -1747,6 +1783,7 @@ et: email_in_disabled: "Uute teemade avamine meili teel on saidi sätetes välja lülitatud. Avamiseks" email_in_disabled_click: 'aktiveeri säte "sissetulev meil".' suppress_from_homepage: "Eemalda see foorum avalehelt." + show_subcategory_list: "Näita selles foorumis alamfoorumite nimekirja teemadest üleval pool." all_topics_wiki: "Tee uued teemad vaikimisi wikideks." sort_order: "Vaikejärjestus" allow_badges_label: "Luba selles foorumis autasustamist märgistega" @@ -1870,6 +1907,9 @@ et: one: "vaatamine" other: "vaatamisi" replies: "Vastuseid" + views_long: + one: "seda teemat on vaadatud 1 kord" + other: "seda teemat on vaadatud {{number}} korda" activity: "Aktiivsus" likes: "Meeldimisi" likes_lowercase: @@ -1998,8 +2038,8 @@ et: show_incoming_updated_topics: '. Näita uuendatud teemasid' search: '/ Otsi' help: '? Ava klaviatuuri abimenüü' - dismiss_new_posts: 'x, r Lükka Uued/Postitused tagasi' - dismiss_topics: 'x, t Lükka teemad tagasi' + dismiss_new_posts: 'x, r Ignoreeri uusi/postitusi' + dismiss_topics: 'x, t Ignoreeri teemasid' log_out: 'shift+z shift+z Logi välja' actions: title: 'Tegevused' @@ -2176,6 +2216,8 @@ et: backups: "varundusi" traffic_short: "Liiklus" traffic: "Rakenduse veebipäringud" + page_views: "Vaatamisi" + page_views_short: "Vaatamisi" show_traffic_report: "Näita liikluse detailraportit" reports: today: "Täna" @@ -2222,7 +2264,7 @@ et: disagree_flag_unhide_post: "Ei nõustu (näita postitust)" disagree_flag_unhide_post_title: "Eemalda sellelt postituselt kõik tähised ja tee ta jälle nähtavaks" disagree_flag: "Ei nõustu" - disagree_flag_title: "Lükka see tähis tagasi kui mittekorrektne või kehtetu" + disagree_flag_title: "Ignoreeri seda tähist kui mittekorrektset või kehtetut" clear_topic_flags: "Tehtud" clear_topic_flags_title: "Teemat on uuritud a probleemid lahendatud. Tähiste eemaldamiseks kliki \"Valmis\"." more: "(veel vastuseid...)" @@ -2318,6 +2360,7 @@ et: warn_local_payload_url: "Näib, et püüad seada veebihaaki lokaalsele URL-le. Lokaalsele aadressile saadetud sündmus võib esile kusuda kõrvalnähte või ootamatusi. Kas jätkame?" secret_invalid: "Salavõti ei tohi sisaldada tühikuid." secret_too_short: "Salavõti peab olema vähemalt 12 sümbolit pikk." + secret_placeholder: "Mittekohustuslik tekst, mida kasutatakse allkirja genereerimiseks" event_type_missing: "Pead seadistama vähemalt ühe sündmuse liigi." content_type: "Sisutüüp" secret: "Salavõti" @@ -2657,9 +2700,17 @@ et: revoke_admin: "võta admin-õigus ära" grant_moderation: "anna modereerimisõigus" revoke_moderation: "võta modereerimisõigus ära" + backup_create: "loo varukoopia" deleted_tag: "kustutatud silt" renamed_tag: "ümbernimetatud silt" revoke_email: "kutsu meil tagasi" + lock_trust_level: "lukusta usaldustase" + unlock_trust_level: "eemalda usaldustaseme lukustus" + activate_user: "aktiveeri kasutaja" + deactivate_user: "deaktiveeri kasutaja" + change_readonly_mode: "muuda kirjutuskaitstud režiimi" + backup_download: "lae varukoopia alla" + backup_destroy: "hävita varukoopia" screened_emails: title: "Varjestatud meilid" description: "Kui keegi üritab uut kontot luua, siis kontrollitakse järgmisi meiliaadresse ja vastavuse korral registreerimine peatatakse või tehakse mõni muu toiming." @@ -2769,6 +2820,7 @@ et: refresh_browsers_message: "Sõnum saadetud kõigile klientidele!" show_public_profile: "Näita avalikku profiili" impersonate: 'Kehasta' + action_logs: "Toimingute logi" ip_lookup: "IP otsimine" log_out: "Logi välja" logged_out: "Kasutaja logiti välja kõigil seadmetel" diff --git a/config/locales/client.fi.yml b/config/locales/client.fi.yml index af1c9b86d7..b33ea527a0 100644 --- a/config/locales/client.fi.yml +++ b/config/locales/client.fi.yml @@ -136,7 +136,7 @@ fi: enabled: 'listasi %{when}' disabled: 'poisti listauksista %{when}' topic_admin_menu: "ketjun ylläpitotoimet" - wizard_required: "Konfiguroidaan foorumisi! Aloita ohjattu asennus!" + wizard_required: "Tervetuloa uuteen Discourseesi! Aloitetaan ohjattu asennus ✨" emails_are_disabled: "Ylläpitäjä on estänyt kaiken lähtevän sähköpostiliikenteen. Mitään sähköposti-ilmoituksia ei lähetetä." bootstrap_mode_enabled: "Jotta uuden palsta käynnistäminen olisi helpompaa, on sivusto asetettu aloitustilaan. Kaikki uudet käyttäjät siirretään automaattisesti luottamustasolle 1 ja heille lähetetään sähköpostitiivistelmät päivittäin. Tämä tila poistetaan automaattisesti, kun käyttäjien määrä ylittää %{min_users}." bootstrap_mode_disabled: "Aloitustila poistetaan seuraavan 24 tunnin aikana." @@ -929,7 +929,7 @@ fi: logging_in: "Kirjaudutaan..." or: "Tai" authenticating: "Autentikoidaan..." - awaiting_confirmation: "Käyttäjätilisi odottaa vahvistusta. Käytä salasana unohtui -linkkiä lähettääksesi uuden vahvistusviestin." + awaiting_activation: "Tilisi odottaa aktivointia; unohdin salasanani -linkin kautta voit pyytää uuden aktivointisähköpostin." awaiting_approval: "Henkilökunta ei ole vielä hyväksynyt käyttäjätiliäsi. Saat sähköpostiviestin, kun tunnuksesi on hyväksytty." requires_invite: "Pahoittelut, tämä palsta on vain kutsutuille käyttäjille." not_activated: "Et voi vielä kirjautua sisään. Lähetimme aiemmin vahvistusviestin osoitteeseen {{sentTo}}. Seuraa viestin ohjeita ottaaksesi tunnuksen käyttöön." @@ -1193,6 +1193,8 @@ fi: first: jotka ovat ketjun avausviestejä pinned: jotka on kiinnitettyjä unpinned: jotka eivät ole kiinnitettyjä + seen: jotka olen lukenut + unseen: joita en ole lukenut wiki: ovat wiki-viestejä statuses: label: Ketju/Ketjuun @@ -1733,6 +1735,17 @@ fi: side_by_side_markdown: title: "Näytä viestien lähdekoodit vierekkäin" button: 'Raaka' + raw_email: + displays: + raw: + title: "Näytä raaka sähköposti" + button: 'Raaka' + text_part: + title: "Näytä sähköpostin tekstiosa" + button: 'Teksti' + html_part: + title: "Näytä sähköpostin HTML-osa" + button: 'HTML' category: can: 'voivat… ' none: '(ei aluetta)' @@ -1785,8 +1798,11 @@ fi: email_in_disabled_click: 'ota käyttöön "email in" asetus.' suppress_from_homepage: "Vaimenna alue kotisivulta." show_subcategory_list: "Näytä lista tytäralueista ketjujen yläpuolella tällä alueella." + num_featured_topics: "Kuinka monta ketjua näytetään Keskustelualueet-sivulla:" + subcategory_num_featured_topics: "Kuinka monta ketjua näytetään emoalueen sivulla:" all_topics_wiki: "Tee uusista ketjuista wiki-viestejä oletuksena." sort_order: "Oletusjärjestys:" + default_view: "Oletusnäkymä:" allow_badges_label: "Salli ansiomerkkien myöntäminen tältä alueelta" edit_permissions: "Muokkaa oikeuksia" add_permission: "Lisää oikeus" @@ -1795,7 +1811,7 @@ fi: default_position: "Oletuspaikka" position_disabled: "Alueet näytetään aktiivisuusjärjestyksessä. Muokataksesi järjestystä," position_disabled_click: 'ota käyttöön "pysyvä aluejärjestys" asetuksista.' - parent: "Ylempi alue" + parent: "Emoalue" notifications: watching: title: "Tarkkaile" @@ -1925,7 +1941,7 @@ fi: history: "Historia" changed_by: "käyttäjältä {{author}}" raw_email: - title: "Alkuperäinen sähköposti" + title: "Saapuva sähköposti" not_available: "Ei käytettävissä!" categories_list: "Lista alueista" filters: @@ -2144,9 +2160,9 @@ fi: about: "Lisää tunnisteita ryhmiin, jotta niitä on helpompi hallita" new: "Uusi ryhmä" tags_label: "Tunnisteet tässä ryhmässä" - parent_tag_label: "Ylempi tunniste:" + parent_tag_label: "Emotunniste:" parent_tag_placeholder: "Valinnainen" - parent_tag_description: "Tämän ryhmän tunnisteita voi käyttää vain, jos ylempi tunniste on asetettu" + parent_tag_description: "Tämän ryhmän tunnisteita voi käyttää vain, jos emotunniste on asetettu" one_per_topic_label: "Rajoita tästä ryhmästä yhteen tunnisteeseen per ketju" new_name: "Uusi ryhmä tunnisteita" save: "Tallenna" @@ -2328,6 +2344,8 @@ fi: add_owners: Lisää omistajia incoming_email: "Saapuvan sähköpostin osoite" incoming_email_placeholder: "aseta sähköpostiosoite" + none_selected: "Aloita valitsemalla ryhmä" + no_custom_groups: "Luo uusi mukautettu ryhmä" api: generate_master: "Luo rajapinnan pääavain" none: "Aktiivisia API avaimia ei ole määritelty." @@ -2345,12 +2363,73 @@ fi: web_hooks: title: "Webhookit" none: "Webhookeja ei ole nyt." + instruction: "Webhookien kautta Discourse ilmoittaa ulkoiselle palvelulle, kun sivustollasi tapahtuu määrätty tapahtuma. Kun webhook laukeaa, POST-pyyntö lähetetään annettuihin URL:eihin." + detailed_instruction: "POST-pyyntö lähetetään annettuun URL:ään, kun valittu tapahtuma tapahtuu." new: "Uusi Webhook" create: "Luo" save: "Tallenna" destroy: "Poista" description: "Kuvaus" + controls: "Hallinta" go_back: "Takaisin listaan" + payload_url: "Tietosisällön URL" + payload_url_placeholder: "https://example.com/postreceive" + warn_local_payload_url: "Näyttää, että yrität asettaa webhookin paikalliseen URL:ään. Paikalliseen osoitteeseen toimitetulla tapahtumalla voi olla sivuvaikutuksia tai se voi käyttäytyä odottamattomasti. Jatketaanko?" + secret_invalid: "Salausavaimessa ei voi olla tyhjämerkkejä." + secret_too_short: "Salausavaimessa tulee olla ainakin 12 merkkiä." + secret_placeholder: "Valinnainen merkkijono, käytetään luotaessa allekirjoitusta" + event_type_missing: "Ainakin yksi tapahtumatyyppi täytyy asettaa." + content_type: "Sisällön tyyppi" + secret: "Salausavain" + event_chooser: "Minkä tapahtumien haluat laukaisevan tämän webhookin?" + wildcard_event: "Lähetä kaikesta." + individual_event: "Valitse tietyt tapahtumat." + verify_certificate: "Tarkasta tietosisällön URL:in TLS-sertifikaatti" + active: "Toiminnassa" + active_notice: "Toimitamme tiedot tapahtumasta, kun se tapahtuu." + categories_filter_instructions: "Webhookit laukaistaan vain, jos tapahtuma liittyy määrättyihin alueisiin. Jätä tyhjäksi, jos haluat webhookien laukeavan alueesta riippumatta." + categories_filter: "Laukaisevat alueet" + groups_filter_instructions: "Webhookit laukaistaan vain, jos tapahtuma liittyy määrättyihin ryhmiin. Jätä tyhjäksi, jos haluat webhookien laukeavan ryhmistä riippumatta." + groups_filter: "Laukaisevat ryhmät" + delete_confirm: "Poista tämä webhook?" + topic_event: + name: "Ketjutapahtuma" + details: "Luodaan uusi ketju, ketju päivitetään, muutetaan tai poistetaan" + post_event: + name: "Viestitapahtuma" + details: "Luodaan uusi vastaus, muokataan, poistetaan tai palautetaan." + user_event: + name: "Käyttäjätapahtuma" + details: "Luodaan uusi käyttäjä, käyttäjä hyväksytään tai päivittyy." + delivery_status: + title: "Toimituksen tila" + inactive: "Ei toiminnassa" + failed: "Epäonnistui" + successful: "Onnistui" + events: + none: "Liittyviä tapahtumia ei ole." + redeliver: "Toimita uudelleen" + incoming: + one: "Yksi uusi tapahtuma." + other: "{{count}} uutta tapahtumaa." + completed_in: + one: "Suoritettiin 1 sekunnissa." + other: "Suoritettiin {{count}} sekunnissa." + request: "Pyyntö" + response: "Vastaus" + redeliver_confirm: "Oletko varma, että haluat toimittaa uudelleen saman tietosisällön?" + headers: "Otsikot" + payload: "Tietosisältö" + body: "Runko" + go_list: "Siirry listaan" + go_details: "Muokkaa webhookia" + go_events: "Siirry tapahtumiin" + ping: "Ping" + status: "Tilan koodi" + event_id: "ID" + timestamp: "Luotu" + completion: "Suorituksen kesto" + actions: "Toiminnot" plugins: title: "Lisäosat" installed: "Asennetut lisäosat" @@ -2402,7 +2481,8 @@ fi: without_uploads: "Kyllä (älä sisällytä tiedostoja)" download: label: "Lataa" - title: "Lataa varmuuskopio" + title: "Lähetä sähköposti, jossa on latauslinkki" + alert: "Varmuuskopion latauslinkki on lähetetty sähköpostiisi." destroy: title: "Poista varmuuskopio" confirm: "Oletko varma, että haluat tuhota tämän varmuuskopion?" @@ -2758,6 +2838,7 @@ fi: refresh_browsers_message: "Viesti lähetetty kaikille asiakkaille!" show_public_profile: "Näytä julkinen profiili" impersonate: 'Esiinny käyttäjänä' + action_logs: "Toimintaloki" ip_lookup: "IP haku" log_out: "Kirjaa ulos" logged_out: "Käyttäjä on kirjautunut ulos kaikilla laitteilla" diff --git a/config/locales/client.he.yml b/config/locales/client.he.yml index d595569fce..9408f8f7aa 100644 --- a/config/locales/client.he.yml +++ b/config/locales/client.he.yml @@ -136,7 +136,7 @@ he: enabled: 'נכנס לרשימה %{when}' disabled: 'הוצא מהרשימה %{when}' topic_admin_menu: "פעולות ניהול לנושא" - wizard_required: "הגיע הזמן לכוונן את הפורום שלכם! התחילו את אשף ההקמה!" + wizard_required: "ברוכים הבאים לסידקורס החדש שלכם! בואו נתחיל עם אשף ההתקנה ✨" emails_are_disabled: "כל הדוא\"ל היוצא נוטרל באופן גורף על ידי מנהל אתר. שום הודעת דוא\"ל, מכל סוג שהוא, לא תשלח." bootstrap_mode_enabled: "כדי להקל על הקמת האתר החדש שלכם, אתם במצב איתחול-ראשוני. כל המשתמשים החדשים יקבלו רמת אמון 1 ויקבלו תמצות יומי במייל. אפשרות זו תכובה אוטומטית כאשר יהיו יותר מ %{min_users} משתמשים." bootstrap_mode_disabled: "מצב איתחול-ראשוני יכובה ב 24 השעות הקרובות." @@ -928,7 +928,7 @@ he: logging_in: "מתחבר...." or: "או" authenticating: "מאשר..." - awaiting_confirmation: "החשבון שלך ממתין להפעלה. ניתן להשתמש בקישור \"שכחתי סיסמה\" כדי לשלוח דואר אלקטרוני נוסף." + awaiting_activation: "החשבון שלכם ממתין להפעלה, השתמשו בקישור ה\"שכחתי סיסמה\" כדי ליצור עוד מייל הפעלה." awaiting_approval: "החשבון שלך עדיין לא אושר על ידי חבר צוות. יישלח אליך דואר אלקטרוני כשהוא יאושר." requires_invite: "סליחה, גישה לפורום הזה היא בהזמנה בלבד." not_activated: "אינך יכול להתחבר עדיין. שלחנו לך דואר אלקטרוני להפעלת החשבון לכתובת: {{sentTo}}. יש לעקוב אחר ההוראות בדואר כדי להפעיל את החשבון." @@ -1192,6 +1192,8 @@ he: first: הפוסטים הראשונים pinned: נעוצים unpinned: לא נעוצים + seen: קראתי + unseen: לא קראתי wiki: הם ויקי statuses: label: כאשר נושאים @@ -1734,6 +1736,17 @@ he: side_by_side_markdown: title: "הציגו את ההבדלי המקור הגולמיים זה לצד זה" button: 'גולמי' + raw_email: + displays: + raw: + title: "הצגת מייל גולמי" + button: 'גולמי' + text_part: + title: "הצגת טקסט כחלק מהמייל" + button: 'טקסט' + html_part: + title: "הצגת חלק ה HTML של המייל" + button: 'HTML' category: can: 'יכול… ' none: '(ללא קטגוריה)' @@ -1786,8 +1799,11 @@ he: email_in_disabled_click: 'אפשרו את את ההגדרה "דוא"ל נכנס"' suppress_from_homepage: "הרחיקו קטגוריה זו מהעמוד הראשי." show_subcategory_list: "הצגת רשימת קטגוריות משנה מעל נושאים בקטגוריה זו." + num_featured_topics: "מספר הנושאים המוצגים בדף הקטגוריות:" + subcategory_num_featured_topics: "מספר הנושאים המומלצים בדף קטגוריית ההורה:" all_topics_wiki: "כברירת מחדל נושאים חדשים יהיו וויקי." sort_order: "סידור ברירת מחדל:" + default_view: "תצוגת ברירת מחדל:" allow_badges_label: "הרשו לעיטורים להיות מוענקים בקטגוריה זו" edit_permissions: "ערוך הרשאות" add_permission: "הוסף הרשאה" @@ -1926,7 +1942,7 @@ he: history: "היסטוריה" changed_by: "מאת {{author}}" raw_email: - title: "גלם הדוא\"ל" + title: "מייל נכנס" not_available: "לא זמין!" categories_list: "רשימת קטגוריות" filters: @@ -2329,6 +2345,8 @@ he: add_owners: הוספת בעלים incoming_email: "התאימו אישית כתובת מייל נכנס" incoming_email_placeholder: "הכניסו כתובת מייל" + none_selected: "בחירת קבוצה כדי להתחיל" + no_custom_groups: "יצירת קבוצה מותאמת אישית" api: generate_master: "ייצר מפתח מאסטר ל-API" none: "אין מפתחות API פעילים כרגע." @@ -2464,7 +2482,8 @@ he: without_uploads: "כן (ללא הכללת קבצים)" download: label: "הורדה" - title: "הורד את הגיבוי" + title: "שליחת מייל עם לינק להורדה" + alert: "קישור להורדת גיבוי זה נשלח אליכם." destroy: title: "הסר את הגיבוי" confirm: "אתם בטוחים שברצונכם להשמיד את הגיבוי הזה?" diff --git a/config/locales/client.it.yml b/config/locales/client.it.yml index 4f0bb74a80..daa8596b0c 100644 --- a/config/locales/client.it.yml +++ b/config/locales/client.it.yml @@ -136,7 +136,7 @@ it: enabled: 'listato %{when}' disabled: 'delistato %{when}' topic_admin_menu: "azioni amministrative sull'argomento" - wizard_required: "E' il momento di configurare il tuo forum! Avvia la configurazione guidata!" + wizard_required: "Benvenuto al tuo nuovo Discourse! Inizia la procedura guidata di configurazione ✨" emails_are_disabled: "Tutte le email in uscita sono state disabilitate a livello globale da un amministratore. Non sarà inviata nessun tipo di notifica via email." bootstrap_mode_enabled: "Per aiutarti ad avviare il tuo nuovo sito, adesso sei in modalità bootstrap. Tutti i nuovi utenti saranno automaticamente promossi al livello 1 e riceveranno il riassunto quotidiano degli aggiornamenti via email. Questa modalità sarà disattivata automaticamente quando avrai più di %{min_users} utenti." bootstrap_mode_disabled: "La modalità bootstrap sarà disattivata entro 24 ore." @@ -645,6 +645,7 @@ it: short_instructions: "Gli utenti possono citarti scrivendo @{{username}}" available: "Il nome utente è disponibile" not_available: "Non disponibile. Prova {{suggestion}}?" + not_available_no_suggestion: "Non disponibile" too_short: "Il nome utente è troppo corto" too_long: "Il nome utente è troppo lungo" checking: "Controllo la disponibilità del nome utente..." @@ -1883,7 +1884,7 @@ it: other: "visite" replies: "Risposte" views_long: - one: "questo argomento è stato visto 1 volta" + one: "questo argomento è stato visto una volta" other: "questo argomento è stato visto {{number}} volte" activity: "Attività" likes: "Mi piace" @@ -1985,7 +1986,7 @@ it: lightbox: download: "scarica" keyboard_shortcuts_help: - title: 'Scorciatorie Tastiera' + title: 'Scorciatoie Tastiera' jump_to: title: 'Salta A' home: 'g, h Home' @@ -2189,8 +2190,8 @@ it: backups: "backup" traffic_short: "Traffico" traffic: "Richieste web dell'applicazione" - page_views: "Visualizzazioni di pagina" - page_views_short: "Visualizzazioni di pagina" + page_views: "Pagine Viste" + page_views_short: "Pagine Viste" show_traffic_report: "Mostra rapporto di traffico dettagliato" reports: today: "Oggi" @@ -2341,7 +2342,7 @@ it: individual_event: "Seleziona eventi singoli." verify_certificate: "Verifica il certificato TLS della URL payload" active: "Attivo" - groups_filter: "Gruppi triggered" + groups_filter: "Gruppi Innescati" delete_confirm: "Eliminare questo webhook?" topic_event: name: "Evento Argomento" @@ -2854,7 +2855,7 @@ it: deactivate_explanation: "Un utente disattivato deve riconvalidare la propria email." suspended_explanation: "Un utente sospeso non può connettersi." block_explanation: "Un utente bloccato non può pubblicare messaggi o iniziare argomenti." - staged_explanation: "Un utente staged può solo postare via email in specifici topic." + staged_explanation: "Un utente temporaneo può pubblicare via email solo in alcuni argomenti." bounce_score_explanation: none: "L'indirizzo email non ha causato nessun errore di ritorno recentemente." some: "Sono stati ricevuti alcuni errori di ritorno per quell'indirizzo email." diff --git a/config/locales/client.ko.yml b/config/locales/client.ko.yml index 7388d6e9be..039792f9fc 100644 --- a/config/locales/client.ko.yml +++ b/config/locales/client.ko.yml @@ -300,12 +300,16 @@ ko: change_group_setting: "그룹 설정 변경" add_user_to_group: "사용자 추가" remove_user_from_group: "사용자 삭제" + make_user_group_owner: "소유자로 지정하기" + remove_user_as_group_owner: "소유자 지정 취소하기" groups: logs: title: "로그" when: "언제" action: "액션" + target_user: "대상 사용자" subject: "주제" + details: "자세한 내용" from: "부터" to: "까지" edit: @@ -317,12 +321,33 @@ ko: title: "멤버십 요청" body: "@%{groupName} 에 멤버십을 요청합니다." name_placeholder: "그룹 이름, 공백 없이 username 규칙과 동일하게 입력하세요." + public: "사용자들이 그룹을 자유롭게 참여/탈퇴 가능하게 합니다. (그룹은 반드시 공개되어야 함)" + empty: + posts: "이 그룹에는 아직 멤버들이 포스트를 작성하지 않았습니다." + members: "이 그룹에는 구성원이 없습니다." + mentions: "이 그룹에서는 언급이 없습니다." + messages: "이 그룹에 대한 메시지는 없습니다." + topics: "이 그룹의 구성원이 작성한 주제글이 없습니다." + logs: "이 그룹에 대한 기록이 없습니다." add: "추가" + join: "그룹 참여하기" + leave: "그룹 나가기" + request: "그룹 참여 요청하기" + closed_group: 닫힌 그룹 + is_group_user: "당신은 이 그룹의 구성원입니다." + allow_membership_requests: "사용자가 그룹 소유자에게 가입 요청을 하는 것을 허용합니다. (모든 유저가 그룹을 맨션할 수 있어야 함)" + membership: "회원제" + name: "이름" + user_count: "멤버 수" + bio: "이 그룹에 대하여" selector_placeholder: "멤버 추가" owner: "소유자" visible: "모든 사용자에게 보이는 그룹입니다." + index: + title: "그룹" title: other: "그룹" + activity: "활동" members: "멤버" topics: "주제" posts: "게시글" @@ -342,6 +367,8 @@ ko: watching: title: "알림 : 주시 중" description: "이 메시지에 새로운 답글이 있을 때 알림을 받게 되며 새로운 답글의 개수는 표시됩니다." + watching_first_post: + title: "첫번째 글 보기" tracking: title: "알림 : 새 글 표시 중" description: "누군가 당신의 @아이디 로 언급했거나 당신의 글에 답글이 달릴 때 알림을 받게 됩니다." @@ -351,6 +378,7 @@ ko: muted: title: "알림 : 끔" description: "이 메시지에 대해 어떠한 알림도 받지 않지 않습니다." + flair_url_placeholder: "(선택) 이미지 URL 또는 Font Awesome 아이콘 클래스" user_action_groups: '1': "선사한 '좋아요'" '2': "받은 '좋아요'" diff --git a/config/locales/client.nl.yml b/config/locales/client.nl.yml index 2295401f49..0b81c7d261 100644 --- a/config/locales/client.nl.yml +++ b/config/locales/client.nl.yml @@ -136,7 +136,7 @@ nl: enabled: 'zichtbaar gemaakt op %{when}' disabled: 'onzichtbaar gemaakt op %{when}' topic_admin_menu: "beheeracties voor topic" - wizard_required: "Het is tijd om uw forum te configureren! Start de configuratiewizard!" + wizard_required: "Welkom bij uw nieuwe Discourse! Laten we beginnen met de configuratiewizard ✨" emails_are_disabled: "Alle uitgaande e-mail is uitgeschakeld door een beheerder. Er zal geen enkele e-mailmelding worden verstuurd." bootstrap_mode_enabled: "Om het lanceren van uw website makkelijker te maken, bevindt u zich in bootstrapmodus. Aan alle nieuwe gebruikers wordt vertrouwensniveau 1 toegekend, en dagelijkse e-mailsamenvattingen zijn voor hen ingeschakeld. Dit wordt automatisch uitgeschakeld wanneer het totale gebruikersaantal %{min_users} gebruikers overschrijdt." bootstrap_mode_disabled: "De bootstrapmodus zal in de komende 24 uur worden uitgeschakeld." @@ -330,7 +330,7 @@ nl: remove_user_as_group_owner: "Eigenaar intrekken" groups: logs: - title: "Logs" + title: "Logboeken" when: "Wanneer" action: "Actie" acting_user: "Uitvoerende gebruiker" @@ -419,8 +419,8 @@ nl: flair_preview_image: "Afbeeldingsvoorbeeld" flair_note: "Opmerking: flair is alleen zichtbaar voor de primaire groep van een gebruiker." user_action_groups: - '1': "Likes gegeven" - '2': "Likes ontvangen" + '1': "Gegeven likes" + '2': "Ontvangen likes" '3': "Favorieten" '4': "Topics" '5': "Antwoorden" @@ -447,8 +447,8 @@ nl: position: "Positie" posts: "Berichten" topics: "Topics" - latest: "Laatste" - latest_by: "laatste door" + latest: "Nieuwste" + latest_by: "nieuwste door" toggle_ordering: "sorteermethode omschakelen" subcategories: "Subcategorieën" topic_sentence: @@ -539,7 +539,7 @@ nl: tracked_tags: "Gevolgd" tracked_tags_instructions: "U volgt automatisch alle topics met deze tags. Het aantal nieuwe berichten verschijnt naast het topic." muted_tags: "Genegeerd" - muted_tags_instructions: "U ontvangt geen meldingen over nieuwe topics met deze tags, en ze verschijnen niet in Recent." + muted_tags_instructions: "U ontvangt geen meldingen over nieuwe topics met deze tags, en ze verschijnen niet in Nieuwste." watched_categories: "In de gaten gehouden" watched_categories_instructions: "U houdt automatisch alle nieuwe topics in deze categorieën in de gaten. U ontvangt meldingen bij alle nieuwe berichten en topics, en het aantal nieuwe berichten verschijnt ook naast het topic." tracked_categories: "Gevolgd" @@ -549,7 +549,7 @@ nl: watched_first_post_tags: "Eerste bericht in de gaten houden" watched_first_post_tags_instructions: "U ontvangt een melding bij het eerste bericht in elk nieuw topic met deze tags." muted_categories: "Genegeerd" - muted_categories_instructions: "U ontvangt geen melding over nieuwe topics en berichten in deze categorieën, en ze verschijnen niet in Recent." + muted_categories_instructions: "U ontvangt geen melding over nieuwe topics en berichten in deze categorieën, en ze verschijnen niet in Nieuwste." delete_account: "Mijn account verwijderen" delete_account_confirm: "Weet u zeker dat u uw account definitief wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt!" deleted_yourself: "Uw account is met succes verwijderd." @@ -928,7 +928,7 @@ nl: logging_in: "Aanmelden..." or: "Of" authenticating: "Authenticeren..." - awaiting_confirmation: "Uw account wacht op activering; gebruik de koppeling 'Wachtwoord vergeten' om een nieuwe activeringsmail te ontvangen." + awaiting_activation: "Uw account wacht op activering; gebruik de koppeling 'Wachtwoord vergeten' om een nieuwe activeringsmail te ontvangen." awaiting_approval: "Uw account is nog niet door een staflid goedgekeurd. U ontvangt een e-mail zodra dat is gebeurd." requires_invite: "Sorry. toegang tot dit forum werkt alleen via uitnodiging." not_activated: "U kunt zich nog niet aanmelden. We hebben een activeringsmail naar {{sentTo}} gestuurd. Volg de instructies in dat e-mailbericht om uw account te activeren." @@ -981,7 +981,7 @@ nl: category_page_style: categories_only: "Alleen categorieën" categories_with_featured_topics: "Categorieën met aanbevolen topics" - categories_and_latest_topics: "Categorieën en recente topics" + categories_and_latest_topics: "Categorieën en nieuwste topics" shortcut_modifier_key: shift: 'Shift' ctrl: 'Ctrl' @@ -1150,7 +1150,7 @@ nl: search: sort_by: "Sorteren op" relevance: "Relevantie" - latest_post: "Laatste bericht" + latest_post: "Nieuwste bericht" most_viewed: "Meest bekeken" most_liked: "Meest geliket" select_all: "Alles selecteren" @@ -1192,6 +1192,8 @@ nl: first: die het eerste bericht zijn pinned: die zijn vastgemaakt unpinned: die niet zijn vastgemaakt + seen: die ik heb gelezen + unseen: die ik niet heb gelezen wiki: die een wiki zijn statuses: label: Waarin topics @@ -1246,7 +1248,7 @@ nl: new: "U hebt geen nieuwe topics." read: "U hebt nog geen topics gelezen." posted: "U hebt nog niet in een topic gereageerd." - latest: "Er zijn geen recente topics. Dat is jammer." + latest: "Er zijn geen nieuwste topics. Dat is jammer." hot: "Er zijn geen populaire topics." bookmarks: "U hebt nog geen bladwijzers voor topics gemaakt." category: "Er zijn geen topics in {{category}}." @@ -1256,7 +1258,7 @@ nl: new: '

    Hier verschijnen uw nieuwe topics.

    Standaard worden topics als nieuw beschouwd en verschijnt de indicator nieuw als deze de afgelopen 2 dagen zijn aangemaakt.

    Bezoek uw voorkeuren om dit te wijzigen.

    ' unread: '

    Hier verschijnen uw ongelezen topics.

    Standaard worden topics als ongelezen beschouwd en verschijnt het aantal ongelezen 1 als u:

    Of als u het topic expliciet op Gevolgd of In de gaten gehouden hebt gezet via de meldingsinstellingen onder elk topic.

    Bezoek uw voorkeuren om dit te wijzigen.

    ' bottom: - latest: "Er zijn geen recente topics." + latest: "Er zijn geen nieuwste topics meer." hot: "Er zijn geen populaire topics meer." posted: "Er zijn geen topics meer geplaatst." read: "Er zijn geen gelezen topics meer." @@ -1322,7 +1324,7 @@ nl: read_more: "Wilt u meer lezen? {{catLink}} of {{latestLink}}." read_more_MF: "Er { UNREAD, plural, =0 {} one { is 1 ongelezen } other { zijn # ongelezen } } { NEW, plural, =0 {} one { {BOTH, select, true{and } false {is } other{}} 1 nieuw topic} other { {BOTH, select, true{and } false {zijn } other{}} # nieuwe topics} } over, of {CATEGORY, select, true {blader door andere topics in {catLink}} false {{latestLink}} other {}}" browse_all_categories: Alle categorieën bekijken - view_latest_topics: bekijk recente topics + view_latest_topics: bekijk de nieuwste topics suggest_create_topic: Waarom maakt u geen topic aan? jump_reply_up: naar eerder antwoord springen jump_reply_down: naar later antwoord springen @@ -1393,7 +1395,7 @@ nl: description: "U ontvangt geen enkele melding over dit bericht." muted: title: "Genegeerd" - description: "U ontvangt geen enkele melding over dit topic, en het zal niet in Recent verschijnen." + description: "U ontvangt geen enkele melding over dit topic, en het verschijnt niet in Nieuwste." actions: recover: "Topic verwijderen ongedaan maken" delete: "Topic verwijderen" @@ -1545,7 +1547,7 @@ nl: edit_reason: "Reden: " post_number: "bericht {{number}}" wiki_last_edited_on: "wiki laatst bewerkt op" - last_edited_on: "bericht gewijzigd op" + last_edited_on: "bericht laatst bewerkt op" reply_as_new_topic: "Antwoorden als gekoppeld topic" reply_as_new_private_message: "Antwoorden als nieuw bericht naar dezelfde ontvangers" continue_discussion: "Voortzetting van de discussie {{postLink}}:" @@ -1568,7 +1570,7 @@ nl: other: "{{count}} likes" has_likes_title: one: "1 persoon heeft dit bericht geliket" - other: "{{count}} personen hebben dit bericht geliketd" + other: "{{count}} personen hebben dit bericht geliket" has_likes_title_only_you: "u hebt dit bericht geliket" has_likes_title_you: one: "u en 1 andere persoon hebben dit bericht geliket" @@ -1732,6 +1734,17 @@ nl: side_by_side_markdown: title: "De bronverschillen naast elkaar tonen" button: 'Onbewerkt' + raw_email: + displays: + raw: + title: "Het onbewerkte e-mailbericht tonen" + button: 'Onbewerkt' + text_part: + title: "Het tekstgedeelte van het e-mailbericht tonen" + button: 'Tekst' + html_part: + title: "Het HTML-gedeelte van het e-mailbericht tonen" + button: 'HTML' category: can: 'kan...' none: '(geen categorie)' @@ -1782,10 +1795,13 @@ nl: email_in_allow_strangers: "E-mails van anonieme gebruikers zonder account accepteren" email_in_disabled: "Het plaatsen van nieuwe topics via e-mail is uitgeschakeld in de webite-instellingen. Om het plaatsen van nieuwe topics via e-mail mogelijk te maken, " email_in_disabled_click: 'schakelt u de instelling ''e-mail in'' in.' - suppress_from_homepage: "Deze categorie op de homepage negeren" + suppress_from_homepage: "Deze categorie op de startpagina negeren" show_subcategory_list: "Subcategorielijsten boven topics tonen in deze categorie" + num_featured_topics: "Aantal getoonde topics op de categoriepagina:" + subcategory_num_featured_topics: "Aantal aanbevolen topics op pagina van bovenliggende categorie:" all_topics_wiki: "Standaard wiki's van nieuwe topics maken" sort_order: "Standaardsortering:" + default_view: "Standaardweergave:" allow_badges_label: "Badges laten toekennen in deze categorie" edit_permissions: "Toestemmingen wijzigen" add_permission: "Toestemming toevoegen" @@ -1810,7 +1826,7 @@ nl: description: "U ontvangt een melding als iemand uw @naam noemt of een bericht van u beantwoordt." muted: title: "Genegeerd" - description: "U ontvangt geen enkele melding over nieuwe topics in deze categorieën, en ze verschijnen niet in Recent." + description: "U ontvangt geen enkele melding over nieuwe topics in deze categorieën, en ze verschijnen niet in Nieuwste." sort_options: default: "standaard" likes: "Likes" @@ -1887,7 +1903,7 @@ nl: help: "Dit topic is voor u losgemaakt; het wordt in normale volgorde weergegeven" pinned_globally: title: "Globaal vastgemaakt" - help: "Dit topic is globaal vastgemaakt; het wordt boven in Recent en de categorie ervan weergegeven" + help: "Dit topic is globaal vastgemaakt; het wordt boven in Nieuwste en de categorie ervan weergegeven" pinned: title: "Vastgemaakt" help: "Dit topic is voor u vastgemaakt; het wordt boven in de categorie ervan weergegeven" @@ -1924,17 +1940,17 @@ nl: history: "Geschiedenis" changed_by: "door {{author}}" raw_email: - title: "Broncode van e-mail" + title: "Inkomende e-mail" not_available: "Niet beschikbaar!" categories_list: "Categorielijst" filters: with_topics: "%{filter}-topics" with_category: "%{filter}-topics in %{category}" latest: - title: "Laatste" + title: "Nieuwste" title_with_count: - one: "Laatste (1)" - other: "Laatste ({{count}})" + one: "Nieuwste (1)" + other: "Nieuwste ({{count}})" help: "topics met recente berichten" hot: title: "Populair" @@ -1979,7 +1995,7 @@ nl: title_with_count: one: "{{categoryName}} (1)" other: "{{categoryName}} ({{count}})" - help: "recente topics in de categorie {{categoryName}}" + help: "nieuwste topics in de categorie {{categoryName}}" top: title: "Top" help: "de meest actieve topics van het afgelopen jaar, maand, week of dag" @@ -2014,7 +2030,7 @@ nl: jump_to: title: 'Snel naar' home: 'g, h Hoofdpagina' - latest: 'g, l Recent' + latest: 'g, l Nieuwste' new: 'g, n Nieuw' unread: 'g, u Ongelezen' categories: 'g, c Categorieën' @@ -2157,13 +2173,13 @@ nl: new: "U hebt geen nieuwe topics." read: "U hebt nog geen topics gelezen." posted: "U hebt nog geen berichten in topics geplaatst." - latest: "Er zijn geen recente topics." + latest: "Er zijn geen nieuwste topics." hot: "Er zijn geen populaire topics." bookmarks: "U hebt nog geen topics met bladwijzers." top: "Er zijn geen toptopics." search: "Er zijn geen zoekresultaten." bottom: - latest: "Er zijn geen recente topics meer." + latest: "Er zijn geen nieuwste topics meer." hot: "Er zijn geen populaire topics meer." posted: "Er zijn geen geplaatste topics meer." read: "Er zijn geen gelezen topics meer." @@ -2197,7 +2213,7 @@ nl: stale_data: "Er is de laatste tijd niet op updates gecontroleerd. Zorg dat sidekiq actief is." version_check_pending: "Blijkbaar hebt u onlangs een upgrade uitgevoerd. Fantastisch!" installed_version: "Geïnstalleerd" - latest_version: "Recent" + latest_version: "Nieuwste" problems_found: "Er zijn een aantal problemen met uw installatie van Discourse gevonden:" last_checked: "Laatst gecontroleerd" refresh_problems: "Opnieuw laden" @@ -2327,6 +2343,8 @@ nl: add_owners: Eigenaren toevoegen incoming_email: "Aangepast adres voor inkomende e-mail" incoming_email_placeholder: "voer e-mailadres in" + none_selected: "Selecteer een groep om te beginnen" + no_custom_groups: "Een nieuwe aangepaste groep maken" api: generate_master: "Master-API-sleutel genereren" none: "Er zijn op dit moment geen actieve API-sleutels." @@ -2462,7 +2480,8 @@ nl: without_uploads: "Ja (geen bestanden bijvoegen)" download: label: "Downloaden" - title: "De back-up downloaden" + title: "E-mail met downloadkoppeling verzenden" + alert: "Er is een koppeling voor het downloaden van deze back-up naar u verzonden via e-mail." destroy: title: "De back-up verwijderen" confirm: "Weet u zeker dat u deze back-up wilt verwijderen?" @@ -2482,9 +2501,9 @@ nl: button_title: user: "Volledige gebruikerslijst exporteren in CSV-indeling" staff_action: "Volledig stafactielogboek exporteren in CSV-indeling" - screened_email: "Volledige gescreende e-maillijst exporteren in CSV-indeling" - screened_ip: "Volledige gescreende IP-lijst exporteren in CSV-indeling" - screened_url: "Volledige gescreende URL-lijst exporteren in CSV-indeling" + screened_email: "Volledige lijst van gecontroleerde e-mails exporteren in CSV-indeling" + screened_ip: "Volledige lijst van gecontroleerde IP-adressen exporteren in CSV-indeling" + screened_url: "Volledige lijst van gecontroleerde URL's exporteren in CSV-indeling" export_json: button_text: "Exporteren" invite: @@ -2585,7 +2604,7 @@ nl: test_error: "Er is een probleem opgetreden bij het versturen van de testmail. Controleer uw mailinstellingen, controleer of uw host geen mailverbindingen blokkeert, en probeer het daarna opnieuw." sent: "Verzonden" skipped: "Overgeslagen" - bounced: "Gebounced" + bounced: "Gebouncet" received: "Ontvangen" rejected: "Geweigerd " sent_at: "Verzonden op" @@ -2710,21 +2729,21 @@ nl: backup_download: "back-up downloaden" backup_destroy: "back-up verwijderen" screened_emails: - title: "Gescreende e-mails" + title: "Gecontroleerde e-mails" description: "Als iemand een nieuwe account probeert aan te maken, worden de volgende e-mailadressen gecontroleerd en de registratie geblokkeerd, of een andere actie uitgevoerd." email: "E-mailadres" actions: allow: "Toestaan" screened_urls: - title: "Gescreende URL's" + title: "Gecontroleerde URL's" description: "De hier vermelde URL's zijn gebruikt in berichten van gebruikers die als spammer zijn gemarkeerd." url: "URL" domain: "Domein" screened_ips: - title: "Gescreende IP-adressen" + title: "Gecontroleerde IP-adressen" description: 'IP-adressen die in de gaten worden gehouden. Gebruik ''Toestaan'' om IP-adressen op een witte lijst te zetten.' delete_confirm: "Weet u zeker dat u de regel voor %{ip_address} wilt verwijderen?" - roll_up_confirm: "Weet u zeker dat u regelmatig gescreende IP-adressen in subnetten wilt samenvoegen?" + roll_up_confirm: "Weet u zeker dat u regelmatig gecontroleerde IP-adressen in subnetten wilt samenvoegen?" rolled_up_some_subnets: "Verbannen IP-adressen zijn zojuist tot deze subnetten samengevoegd: %{subnets}." rolled_up_no_subnet: "Er was niets om samen te voegen." actions: diff --git a/config/locales/client.pl_PL.yml b/config/locales/client.pl_PL.yml index 4c53e13304..cbaa5c2d1a 100644 --- a/config/locales/client.pl_PL.yml +++ b/config/locales/client.pl_PL.yml @@ -172,7 +172,7 @@ pl_PL: enabled: 'wylistowanie %{when}' disabled: 'odlistowanie %{when}' topic_admin_menu: "akcje administratora" - wizard_required: "Teraz czas na konfigurację twojego forum! Rozpocznij Kreator Konfiguracji!" + wizard_required: "Witaj na Twoim nowym Discourse! Zacznij od kreatora konfiguracji ✨" emails_are_disabled: "Wysyłanie e-maili zostało globalnie wyłączone przez administrację. Powiadomienia e-mail nie będą dostarczane." bootstrap_mode_enabled: "Aby ułatwić uruchomienie Twojego nowego serwisu, znajdujesz się w trybie bootstrap. Wszyscy nowi użytkownicy otrzymają 1. poziom zaufania i będą otrzymywać codzienne podsumowania drogą mailową. To się zmieni, gdy liczba użytkowników przekroczy liczbę %{min_users}." bootstrap_mode_disabled: "Tryb Bootstrap zostanie wyłączony w ciągu najbliższych 24 godzin." @@ -1006,7 +1006,7 @@ pl_PL: logging_in: "Uwierzytelnianie…" or: "Lub" authenticating: "Uwierzytelnianie…" - awaiting_confirmation: "Twoje konto czeka na aktywację. Użyj odnośnika przypomnienia hasła, aby otrzymać kolejny email aktywujący konta." + awaiting_activation: "Twoje konto czeka na aktywację. Użyj linku przypomnienia hasła, aby otrzymać kolejny email aktywujący." awaiting_approval: "Twoje konto jeszcze nie zostało zatwierdzone przez osoby z obsługi. Otrzymasz email gdy zostanie zatwierdzone." requires_invite: "Przepraszamy, dostęp do tego forum jest tylko za zaproszeniem." not_activated: "Nie możesz się jeszcze zalogować. Wysłaliśmy email aktywujący konto na adres {{sentTo}}. W celu aktywacji konta postępuj zgodnie z instrukcjami otrzymanymi w emailu." @@ -1276,6 +1276,8 @@ pl_PL: first: 'tylko najnowsze posty ' pinned: są przypięte unpinned: są nie przypięte + seen: Przeczytałem + unseen: Nie przeczytałem wiki: są postami wiki statuses: label: Tematy gdzie @@ -1898,6 +1900,17 @@ pl_PL: side_by_side_markdown: title: "Pokaż porównanie źródeł w formie tekstowej obok siebie" button: 'Źródło' + raw_email: + displays: + raw: + title: "Pokaż surowy email" + button: 'Surowy' + text_part: + title: "Pokaż część tekstową emaila" + button: 'Tekst' + html_part: + title: "Pokaż część html emaila" + button: 'HTML' category: can: 'może… ' none: '(brak kategorii)' @@ -1950,8 +1963,10 @@ pl_PL: email_in_disabled_click: 'Kliknij tu, aby włączyć.' suppress_from_homepage: "Nie wyświetlaj tej kategorii na stronie głównej." show_subcategory_list: "Pokaż listę subkategorii powyżej tematów w tej kategorii." + num_featured_topics: "Liczba wątków do wyświetlenia na stronie kategorii:" all_topics_wiki: "Stwórz nowe tematy domyślnie jako wiki" sort_order: "Domyślnie sortuj:" + default_view: "Domyślny Widok:" allow_badges_label: "Włącz przyznawanie odznak na podstawie aktywności w tej kategorii" edit_permissions: "Edytuj uprawnienia" add_permission: "Dodaj uprawnienie" @@ -2103,7 +2118,7 @@ pl_PL: history: "Historia" changed_by: "przez {{author}}" raw_email: - title: "Źródło emaila" + title: "Email przychodzący" not_available: "Niedostępne!" categories_list: "Lista Kategorii" filters: @@ -2536,6 +2551,8 @@ pl_PL: add_owners: Dodaj właścicieli incoming_email: "Niestandardowy adres poczty przychodzącej" incoming_email_placeholder: "podaj adres e-mail" + none_selected: "Wybierz grupę, aby rozpocząć" + no_custom_groups: "Utwórz nową grupę" api: generate_master: "Generuj Master API Key" none: "Nie ma teraz aktywnych kluczy API." @@ -2673,7 +2690,8 @@ pl_PL: without_uploads: "Tak (bez załączników)" download: label: "Pobierz" - title: "Pobierz kopię zapasową" + title: "Wyślij email z linkiem do pobrania" + alert: "Link do pobrania tej kopii zapasowej został wysłany do ciebie emailem." destroy: title: "Usuń kopię zapasową" confirm: "Czy na pewno chcesz zniszczyć tą kopię zapasową?" diff --git a/config/locales/client.pt_BR.yml b/config/locales/client.pt_BR.yml index 5e78321bd4..15037e2f9d 100644 --- a/config/locales/client.pt_BR.yml +++ b/config/locales/client.pt_BR.yml @@ -10,7 +10,7 @@ pt_BR: number: format: separator: "," - delimiter: "," + delimiter: "." human: storage_units: format: '%n %u' @@ -100,7 +100,7 @@ pt_BR: one: "1 ano depois" other: "%{count} anos depois" previous_month: 'Mês Anterior' - next_month: 'Próximo Mês' + next_month: 'Mês Seguinte' share: topic: 'compartilhe o link desse tópico' post: 'mensagem #%{postNumber}' @@ -136,7 +136,7 @@ pt_BR: enabled: 'listou %{when}' disabled: 'desalistou %{when}' topic_admin_menu: "ações administrativas do tópico" - wizard_required: "Chegou a hora de configurar seu fórum! Começar o Assistente de Configuração!" + wizard_required: "Bem vindo ao seu novo Discourse! Vamos começar com o assistente de configuração ✨" emails_are_disabled: "Todo o envio de email foi globalmente desabilitado por algum administrador. Nenhum email de notificações de qualquer tipo será enviado." bootstrap_mode_enabled: "Para facilitar o lançamento do seu novo site, você esta no modo de inicialização. A todos os novos usuários, será concedido o nível de confiança 1 e eles terão o resumo diário de atualizações por email ativado. Isso será automaticamente desativado quando a contagem total de usuários exceder %{min_users} usuários." bootstrap_mode_disabled: "O modo de inicialização será desativado nas próximas 24 horas." @@ -645,6 +645,7 @@ pt_BR: short_instructions: "As pessoas podem mencionar você usando @{{username}}." available: "Seu nome de usuário está disponível" not_available: "Não está disponível. Tente {{suggestion}}?" + not_available_no_suggestion: "Não disponível" too_short: "Seu nome de usuário é muito curto" too_long: "Seu nome de usuário é muito longo" checking: "Verificando disponibilidade do Nome de Usuário..." @@ -745,8 +746,10 @@ pt_BR: link_generated: "Link de convite gerado com sucesso!" valid_for: "Link de convite é válido apenas para esse endereço de email: %{email}" bulk_invite: + none: "Você ainda não convidou ninguém para cá. Envie convites individuais, ou convide várias pessoas de uma só vez, fazendo a importação de um arquivo CSV." text: "Convidar em massa a partir de arquivo" success: "Arquivo enviado com sucesso, você será notificado por mensagem quando o processo estiver completo." + error: "Pedimos desculpas, o arquivo deve estar no formato CSV." password: title: "Senha" too_short: "A sua senha é muito curta." @@ -925,7 +928,7 @@ pt_BR: logging_in: "Entrando..." or: "Ou" authenticating: "Autenticando..." - awaiting_confirmation: "A sua conta está aguardando ativação, utilize o link 'Esqueci a Senha' para pedir um novo link para ativar o email." + awaiting_activation: "Sua conta está aguardando ativação, utilize o link \"Esqueci minha senha\" para enviar um novo email de ativação." awaiting_approval: "Sua conta ainda não foi aprovada por um membro da equipe. Você receberá um email quando sua conta for aprovada." requires_invite: "Desculpe, o acesso a este fórum é permitido somente por convite de outro membro." not_activated: "Você não pode entrar ainda. Nós lhe enviamos um email de ativação anteriormente no endereço {{sentTo}}. Por favor siga as instruções contidas neste email para ativar a sua conta." @@ -958,6 +961,15 @@ pt_BR: github: title: "com GitHub" message: "Autenticando com GitHub (certifique-se de que os bloqueadores de popup estejam desativados)" + invites: + accept_title: "Convite" + welcome_to: "Bem vindo a %{site_name}!" + invited_by: "Você foi convidado por:" + social_login_available: "Em breve, você poderá entrar com qualquer login de redes sociais usando este email." + your_email: "O endereço de email da sua conta é %{email}." + accept_invite: "Aceitar Convite" + success: "Sua conta foi criada e você já está logado." + password_label: "Configurar Senha (opcional)" password_reset: continue: "Continuar para %{site_name}" emoji_set: @@ -1180,6 +1192,8 @@ pt_BR: first: são a primeira publicação pinned: está fixado unpinned: não está fixado + seen: Eu li + unseen: Eu não li wiki: é uma wiki statuses: label: Onde os tópicos @@ -1769,8 +1783,11 @@ pt_BR: email_in_disabled: "Postar novos tópicos via email está desabilitado nas Configurações do Site. Para habilitar respostas em novos tópicos via email," email_in_disabled_click: 'habilitar a configuração de "email em".' suppress_from_homepage: "Suprimir esta categoria da página inicial." + show_subcategory_list: "Exibir lista de subcategorias acima dos tópicos nesta categoria." + num_featured_topics: "Número de tópicos exibidos na página de Categorias:" all_topics_wiki: "Tornar novos tópicos wikis por padrão." sort_order: "Ordenação Padrão:" + default_view: "Visualização Padrão:" allow_badges_label: "Permitir a concessão de emblemas nessa categoria" edit_permissions: "Editar Permissões" add_permission: "Adicionar Permissões" @@ -2312,6 +2329,8 @@ pt_BR: add_owners: Adicionar proprietários incoming_email: "Endereço de email de entrada personalizado" incoming_email_placeholder: "Insira um endereço de email" + none_selected: "Selecione um grupo para começar" + no_custom_groups: "Crie um novo grupo" api: generate_master: "Gerar chave Mestra de API" none: "Não existem chaves API ativas no momento." @@ -2447,7 +2466,8 @@ pt_BR: without_uploads: "Sim (não inclua arquivos)" download: label: "Download" - title: "Download do backup" + title: "Enviar email com link para download" + alert: "Um link para fazer o download deste backup foi enviado a você por email." destroy: title: "Remove o backup" confirm: "Tem certeza de que quer destruir este backup?" @@ -2803,6 +2823,7 @@ pt_BR: refresh_browsers_message: "Mensagem enviada para todos os clientes!" show_public_profile: "Mostrar Perfil Público" impersonate: 'Personificar' + action_logs: "Registro de Atividades" ip_lookup: "Pesquisa do IP" log_out: "Log Out" logged_out: "Usuário foi desconectado em todos os dipositivos" diff --git a/config/locales/client.ru.yml b/config/locales/client.ru.yml index f66164e948..67c7f60ebd 100644 --- a/config/locales/client.ru.yml +++ b/config/locales/client.ru.yml @@ -172,7 +172,7 @@ ru: enabled: 'Включил в списки %{when}' disabled: 'Исключил из списков %{when}' topic_admin_menu: "действия администратора над темой" - wizard_required: "Пришло время для настройки вашего форума!Запустить Мастер Установки!" + wizard_required: "Добро пожаловать в ваш новый Discourse! Начните с мастера настройки ✨" emails_are_disabled: "Все исходящие письма были глобально отключены администратором. Уведомления любого вида не будут отправляться на почту." bootstrap_mode_enabled: "Чтобы облегчить развитие вашего нового сайта в самом начале, был включен режим запуска. В этом режиме, всем новым пользователям будет автоматически присвоен 1й уровень доверия при регистрации и включена ежедневная почтовая рассылка сводки новостей. Режим запуска будет выключен автоматически, как только количество зарегистрированных пользователей достигнет %{min_users}." bootstrap_mode_disabled: "Режим запуска будет отключен в течение 24 часов." @@ -204,7 +204,7 @@ ru: admin_title: "Админка" flags_title: "Жалобы" show_more: "показать дальше" - show_help: "Cправка" + show_help: "Расширенный поиск" links: "Ссылки" links_lowercase: one: "ссылка" @@ -1217,7 +1217,7 @@ ru: linked: '{{username}} ссылается на ваш пост в теме: "{{topic}}" - {{site_title}}' upload_selector: title: "Add an image" - title_with_attachments: "Add an image or a file" + title_with_attachments: "Добавить изображение или файл" from_my_computer: "С моего устройства" from_the_web: "С интернета" remote_tip: "ссылка на изображение" @@ -1276,6 +1276,8 @@ ru: first: Только первые сообщения в темах pinned: Закреплены unpinned: Не закреплены + seen: Отметить прочитанным + unseen: Отметить непрочитанным wiki: Являются вики statuses: label: Характеристика темы @@ -1300,23 +1302,23 @@ ru: new_messages_marker: "последний визит" bulk: select_all: "Выбрать все" - clear_all: "Очистить все" - unlist_topics: "Исключить из списков" + clear_all: "Отменить выбор" + unlist_topics: "Исключить из всех списков тем" reset_read: "Сбросить прочтённые" delete: "Удалить темы" - dismiss: "OK" + dismiss: "Отложить" dismiss_read: "Отклонить все непрочитанные" dismiss_button: "Отложить..." dismiss_tooltip: "Отложить новые сообщения или перестать следить за этими темами" also_dismiss_topics: "Перестать следить за этими темами, чтобы они никогда больше не высвечивались как непрочитанные" dismiss_new: "Отложить новые" toggle: "Вкл./выкл. выбор нескольких тем" - actions: "Массовое действие" + actions: "Массовые действия" change_category: "Изменить раздел" close_topics: "Закрыть темы" archive_topics: "Архивировать темы" - notification_level: "Изменить уровень оповещения" - choose_new_category: "Выберите новый раздел для тем:" + notification_level: "Изменить настройки уведомлений" + choose_new_category: "Выберите новый раздел для этих тем:" selected: one: "Вы выбрали {{count}} тему." few: "Вы выбрали {{count}} темы." @@ -1324,9 +1326,9 @@ ru: other: "Вы выбрали {{count}} тем." change_tags: "Заменить теги" append_tags: "Добавить теги" - choose_new_tags: "Выбрать новые тэги для выбранных тем:" - choose_append_tags: "Выберите новые теги для добавления к этим темам:" - changed_tags: "Теги этой темы были изменены." + choose_new_tags: "Выберите новые тэги для этих тем:" + choose_append_tags: "Выберите теги для добавления к этим темам:" + changed_tags: "Теги этих тем изменены." none: unread: "У вас нет непрочитанных тем." new: "У вас нет новых тем." @@ -1663,6 +1665,7 @@ ru: wiki_last_edited_on: "вики редактировалось" last_edited_on: "последний раз сообщение редактировалось" reply_as_new_topic: "Ответить в новой связанной теме" + reply_as_new_private_message: "Ответить новым сообщением тем же адресатам" continue_discussion: "Продолжить обсуждение из {{postLink}}:" follow_quote: "перейти к цитируемому сообщению" show_full: "Показать полный текст" @@ -1897,6 +1900,17 @@ ru: side_by_side_markdown: title: "Показать отличия редакций бок о бок" button: 'Необработанный' + raw_email: + displays: + raw: + title: "Показать исходное письмо" + button: 'Исходник' + text_part: + title: "Показать текстовую версию письма" + button: 'Текст' + html_part: + title: "Показать HTML версию письма" + button: 'HTML' category: can: 'может… ' none: '(вне раздела)' @@ -1948,8 +1962,10 @@ ru: email_in_disabled: "Создание новых тем через электронную почту отключено в настройках сайта. Чтобы разрешить создание новых тем через электронную почту," email_in_disabled_click: 'активируйте настройку "email in".' suppress_from_homepage: "Не отображать этот раздел на главной странице." + num_featured_topics: "Количество тем на странице разделов" all_topics_wiki: "Создавать новые темы в вики-формате по умолчанию." sort_order: "Порядок сортировки:" + default_view: "Вид по умолчанию:" allow_badges_label: "Разрешить вручение наград в этом разделе" edit_permissions: "Изменить права доступа" add_permission: "Добавить права" @@ -2103,7 +2119,7 @@ ru: history: "История" changed_by: "автором {{author}}" raw_email: - title: "Исходное письмо" + title: "Входящее сообщение" not_available: "Не доступно!" categories_list: "Список разделов" filters: @@ -2536,6 +2552,8 @@ ru: add_owners: Добавить владельцев incoming_email: "Специальный входящий адрес e-mail" incoming_email_placeholder: "введите e-mail" + none_selected: "Чтобы начать, выберите группу!" + no_custom_groups: "Создать новую кастомную группу" api: generate_master: "Сгенерировать ключ API" none: "Отсутствует ключ API." @@ -2675,7 +2693,8 @@ ru: without_uploads: "Да (исключить файлы)" download: label: "Скачать" - title: "Скачать резервную копию" + title: "Послать письмо со ссылкой для скачивания" + alert: "Вам была отправлена ссылка для скачивания бэкапа." destroy: title: "Удалить резервную копию" confirm: "Вы уверены, что хотите уничтожить резервную копию?" @@ -2953,7 +2972,7 @@ ru: text: "Группировка" title: "Создание новой записи бана целой подсети если уже имеется хотя бы 'min_ban_entries_for_roll_up' записей отдельных IP адресов." logster: - title: "Журнаш ошибок" + title: "Журнал ошибок" impersonate: title: "Войти от имени пользователя" help: "Используйте этот инструмент, чтобы войти от имени пользователя. Может быть полезно для отладки. После этого необходимо выйти и зайти под своей учетной записью снова." diff --git a/config/locales/client.sk.yml b/config/locales/client.sk.yml index 8ab7a4ac57..642b3ad0d4 100644 --- a/config/locales/client.sk.yml +++ b/config/locales/client.sk.yml @@ -176,7 +176,7 @@ sk: sign_up: "Registrácia" log_in: "Prihlásenie" age: "Vek" - joined: "Registovaný" + joined: "Registrovaný" admin_title: "Administrácia" flags_title: "Nahlásenie" show_more: "zobraz viac" @@ -186,7 +186,7 @@ sk: one: "odkaz" few: "odkazy" other: "odkazy" - faq: "FAQ" + faq: "Časté otázky" guidelines: "Pokyny" privacy_policy: "Ochrana súkromia" privacy: "Súkromie" @@ -228,6 +228,7 @@ sk: like_count: "Páči sa mi" topic_count: "Témy" post_count: "Príspevky" + user_count: "Používatelia" active_user_count: "Aktívni používatelia" contact: "Kontaktujte nás" contact_info: "V prípade kritickej chyby alebo naliehavej záležitosti nás prosím konaktujte na %{contact_info}." @@ -340,15 +341,46 @@ sk: one: "1 používateľ" few: "%{count} používatelia" other: "%{count} používateľov" + group_histories: + actions: + change_group_setting: "Zmeniť nastavenia skupiny" + add_user_to_group: "Pridať používateľa" + remove_user_from_group: "Odstrániť používateľa" + make_user_group_owner: "Nastaviť ako vlastníka" + remove_user_as_group_owner: "Odobrať vlastníka" groups: + logs: + title: "Záznamy" + when: "Kedy" + action: "Akcia" + target_user: "Cieľový používateľ" + subject: "Predmet" + details: "Detaily" + from: "Od" + to: "Komu" + edit: + title: 'Upraviť skupinu' + full_name: 'Celé meno' + add_members: "Pridať používateľov" + request_membership_pm: + title: "Žiadosť o pridanie" + body: "Chcel by som sa stať členom skupiny @%{groupName}." add: "Pridať" + closed_group: Uzavretá skupina + membership: "Členstvo" + user_count: "Počet členov" + bio: "O skupine" selector_placeholder: "Pridať členov" owner: "vlastník" visible: "Skupina je viditeľná všetkým používateľom" + index: + title: "Skupiny" + empty: "Nenašli sa viditeľné skupiny." title: one: "skupina" few: "skupiny" other: "skupiny" + activity: "Aktivita" members: "Členovia" topics: "Témy" posts: "Príspevky" @@ -366,10 +398,10 @@ sk: none: "Žiadny" notifications: watching: - title: "Pozerať" + title: "Pozorovať" description: "Budete upozornený na každý nový príspevok vo všetkých správach a zobrazí sa počet nových odpovedí." watching_first_post: - title: "Pozerať prvý príspevok" + title: "Pozorovať prvý príspevok" description: "Budete upozornený iba na prvý príspevok v každej téme v tejto skupine." tracking: title: "Sledovať" @@ -378,7 +410,7 @@ sk: title: "Bežný" description: "Budete upozornený ak niekto zmieni Vaše @meno alebo Vám odpovie." muted: - title: "Ignorovaný" + title: "Ignorované" description: "Nikdy nebudete upozornení na nič ohľadom nových tém v tejto skupine." user_action_groups: '1': "Rozdaných 'páči sa mi'" @@ -443,6 +475,11 @@ sk: profile: "Profil" mute: "Ignorovať" edit: "Upraviť nastavenia" + download_archive: + button_text: "Uložiť moje príspevky" + confirm: "Si si istý, že si chceš uložiť svoje príspevky na disk?" + success: "Sťahovanie bolo spustené, o jeho ukončení budeš informovaný správou." + rate_limit_error: "Príspevky možu byť stiahnuté len raz za deň. Skús opäť zajtra prosím." new_private_message: "Nová správa" private_message: "Správa" private_messages: "Správy" @@ -483,24 +520,30 @@ sk: mailing_list_mode: label: "Režim mailing listu" enabled: "Zapnúť režim mailing listu" + instructions: | + Toto nastavenie nahradí Zhrnutie aktivíť.
    + Stíšené témy a kategórie nie sú v týchto emailoch zahrnuté. daily: "Posielať denné aktualizácie" individual: "Pošli email pri každom novom príspevku" many_per_day: "Pošli mi email pri každom novom príspevku (cca {{dailyEmailEstimate}} denne)" few_per_day: "Pošli mi email pri každom novom príspevku (cca 2 denne)" tag_settings: "Štítky" - watched_tags: "Pozerané" + watched_tags: "Sledované" watched_tags_instructions: "Budete automaticky pozerať všetky témy s týmito štítkami. Budete upozornený na všetky nové príspevky a témy, a zároveň bude vedľa témy zobrazený počet nových príspevkov." tracked_tags: "Sledované" tracked_tags_instructions: "Budete automaticky sledovať všetky témy s týmito štítkami. Počet nových príspevkov sa bude zobrazovať vedľa témy." muted_tags: "Stíšené" - watched_categories: "Pozerané" + muted_tags_instructions: "Nebudete informovaný o nových témach s týmito štítkami a nezobrazia sa ani medzi najnovšími." + watched_categories: "Pozorované" watched_categories_instructions: "Budete automaticky pozerať všetky témy v týchto kategóriách. Budete upozornený na všetky nové príspevky a témy, a zároveň bude vedľa témy zobrazený počet nových príspevkov." tracked_categories: "Sledované" tracked_categories_instructions: "Budete automaticky sledovať všetky témy v tejto kategórii. Počet nových príspevkov sa bude zobrazovať vedľa témy." - watched_first_post_categories: "Pozerať prvý príspevok" - watched_first_post_tags: "Pozerať prvý príspevok" - muted_categories: "Ignorovaný" - muted_categories_instructions: "Nebudete informovaní o udalostiach v nových témach týchto kategórií. Tieto témy sa zároveň nebudú zobrazovať v zozname posledných udalostí." + watched_first_post_categories: "Pozorovať prvý príspevok" + watched_first_post_categories_instructions: "Budete upozornený na prvý príspevok v každej novej téme v týchto kategóriách." + watched_first_post_tags: "Pozorovať prvý príspevok" + watched_first_post_tags_instructions: "Budete upozornený na prvý príspevok v každej novej téme s týmito štítkami." + muted_categories: "Ignorované" + muted_categories_instructions: "Nebudete informovaný o udalostiach v nových témach týchto kategórií. Tieto témy sa zároveň nebudú zobrazovať v zozname posledných udalostí." delete_account: "Vymazať môj účet" delete_account_confirm: "Ste si istý, že chcete permanentne vymazať váš účet? Táto akcia je nenávratná." deleted_yourself: "Váš účet bol úspešne vymazaný." @@ -508,10 +551,10 @@ sk: unread_message_count: "Správy" admin_delete: "Vymazať" users: "Používatelia" - muted_users: "Ignorovaný" + muted_users: "Ignorovaní" muted_users_instructions: "Pozastaviť všetky notifikácie od týchto používateľov." - muted_topics_link: "Zobraziť umlčané témy" - watched_topics_link: "Zobraziť pozerané témy" + muted_topics_link: "Zobraziť stíšené témy" + watched_topics_link: "Zobraziť pozorované témy" apps: "Appky" revoke_access: "Odvolať prístup" undo_revoke_access: "Zrušiť odvolanie prístupu" @@ -537,7 +580,7 @@ sk: success: "(email odoslaný)" in_progress: "(email sa odosiela)" error: "(chyba)" - action: "Odoslať email na reset hesla" + action: "Odoslať email na obnovenie hesla" set_password: "Nastaviť heslo" change_about: title: "Upraviť O mne" @@ -573,6 +616,7 @@ sk: instructions: "Obrázky pozadia budú vystredené a s predvolenou šírkou 590px." email: title: "Email" + instructions: "nikdy sa nezobrazuje verejne" ok: "Pošleme vám email pre potvrdenie" invalid: "Zadajte prosím platný email" authenticated: "Váš email bude autentifikovaný pomocou {{provider}}" @@ -583,6 +627,7 @@ sk: other: "Odošleme vám email iba ak sme vás nevideli posledných {{count}} minút" name: title: "Meno" + instructions: "vaše celé meno (nepovinné)" instructions_required: "Vaše celé meno" too_short: "Vaše meno je prikrátke" ok: "Vaše meno je v poriadku" @@ -604,7 +649,7 @@ sk: last_posted: "Posledný príspevok" last_emailed: "Posledný odemailovaný" last_seen: "Videný" - created: "Spojený" + created: "Vytvorený" log_out: "Odhlásiť sa" location: "Poloha" card_badge: @@ -614,17 +659,22 @@ sk: like_notification_frequency: title: "Oznámiť pri lajknutí" always: "Vždy" + first_time_and_daily: "Prvý lajk príspevku v ten deň" + first_time: "Prvý lajk príspevku" never: "Nikdy" email_previous_replies: + title: "Zahrnúť predošlé odpovede na spodku emailov" always: "vždy" never: "nikdy" email_digests: + title: "Keď nenavštevujem toto fórum, chcem dostať zhrnutie o populárnych témach a odpovediach emailom" every_30_minutes: "každých 30 mintút" every_hour: "každú hodinu" daily: "denne" every_three_days: "každé tri dni" weekly: "týždenne" every_two_weeks: "každé dva týždne" + email_in_reply_to: "Zahrnúť úryvok príspevku, na ktorý používateľ reagoval, v emailoch" email_direct: "Pošlite mi email ak ma niekto cituje, odpovie na môj príspevok, zmieni moje @meno alebo ma pozve do témy." email_private_messages: "Pošlite mi email keď mi niekto pošle správu" email_always: "Pošlite mi emailovú notifikáciu aj keď som aktívny na stránke" @@ -649,6 +699,7 @@ sk: after_4_minutes: "po 4 minútach" after_5_minutes: "po 5 minútach" after_10_minutes: "po 10 minútach" + notification_level_when_replying: "Keď prispejem do témy, nastav spôsob sledovania na" invited: search: "začni písať pre hľadanie pozvánok" title: "Pozvánky" @@ -659,12 +710,12 @@ sk: one: "Zobrazuje sa prvá pozvánka." few: "Zobrazujú sa prvé {{count}} pozvánky." other: "Zobrazuje sa prvých {{count}} pozvánok." - redeemed: "Použité pozvánky" - redeemed_tab: "Použitá" - redeemed_tab_with_count: "Použité ({{count}})" - redeemed_at: "Použitá" + redeemed: "Využité pozvánky" + redeemed_tab: "Využité" + redeemed_tab_with_count: "Využité ({{count}})" + redeemed_at: "Využitá" pending: "Čakajúce pozvánky" - pending_tab: "Čakajúca" + pending_tab: "Čakajúce" pending_tab_with_count: "Čakajúce ({{count}})" topics_entered: "Zobrazených tém" posts_read_count: "Prečítaných príspevkov" @@ -678,7 +729,7 @@ sk: time_read: "Doba čítania" days_visited: "Dní na stránke" account_age_days: "Vek účtu v dňoch" - create: "Poslať Pozvánku" + create: "Poslať pozvánku" generate_link: "Kopírovať Odkaz Pozvánky" bulk_invite: text: "Hromadná pozvánka zo súboru" @@ -722,16 +773,16 @@ sk: one: "záložka" few: "záložky" other: "záložiek" - top_replies: "Najvýznamnejšie odpovede" + top_replies: "Top odpovede" no_replies: "Zatiaľ žiadne odpovede." more_replies: "Viac odpovedí" - top_topics: "Najvýznamnejšie témy" + top_topics: "Top témy" no_topics: "Zatiaľ žiadne témy." more_topics: "Viac tém" - top_badges: "Najvýznamnejšie odznaky" + top_badges: "Top odznaky" no_badges: "Zatiaľ žiadne odznaky." more_badges: "Viac odznakov" - top_links: "Najvýznamnejšie odkazy" + top_links: "Top odkazy" no_links: "Zatiaľ žiadne odkazy." most_liked_by: "Najviac lajkov od" most_liked_users: "Najviac lajkované" @@ -1073,6 +1124,29 @@ sk: category: "Vyhľadať kategóriu #{{category}}" topic: "Hľadaj v tejto téme" private_messages: "Hľadaj správy" + advanced: + title: Rozširené vyhľadávanie + posted_by: + label: Autor príspevku + in_category: + label: V kategórii + with_tags: + label: Má štítky + filters: + label: Hľadaj iba v témach/prispevkoch, ktoré... + likes: sa mi páčia + posted: obsahujú môj príspevok + private: sú v mojich správach + seen: som čítal + unseen: som nečítal + statuses: + label: Kde témy + closed: uzavreté + post: + count: + label: Minimálny počet príspevkov + time: + label: Odoslané hamburger_menu: "prejsť na iné témy, alebo kategórie" new_item: "nový" go_back: 'späť' @@ -1110,12 +1184,12 @@ sk: posted: "Nanapísali ste ešte žiadnu tému." latest: "Nie sú žiadne nové témy. To je smutné." hot: "Nie sú žiadne horúce témy." - bookmarks: "Nemáte žiadne témy v záložke" + bookmarks: "Nemáte zatiaľ žiadne témy v záložkách." category: "V kategórii {{category}} nie je žiadna téma" top: "Nie sú žiadne populárne témy." search: "Nenašli sa žiadne výsledky" educate: - new: '

    Tu sa zobrazia Vaše nové témy.

    V predvolenom nastavení sú témy považované za nové a zobrazí indikátor nové ak boli vytvorené za posledné 2 dni.

    Môžete to zmeniť vo Vašichnastaveniach.

    ' + new: '

    Tu sa zobrazia Vaše nové témy.

    V predvolenom nastavení sú témy považované za nové a zobrazí indikátor nové ak boli vytvorené za posledné 2 dni.

    Môžete to zmeniť vo Vašich nastaveniach.

    ' unread: '

    Tu sa zobrazia Vaše neprečítané témy.

    V predvolenom nastavení sú témy považované za neprečítané a zobrazí sa počet neprečítaných 1 ak ste:

    Alebo ste explicitne nastavili sledovanie alebo pozeranie témy prostredníctvom ovládania upozornení na konci každej témy.

    Môžte to zmeniť vo Vašich nastaveniach.

    ' bottom: latest: "Nie je už viac najnovšich tém." @@ -1217,6 +1291,7 @@ sk: total: Všetkých príspevkov current: tento príspevok notifications: + title: zmeň ako často dostávaš upozornenia o tejto téme reasons: '3_10': 'Budete dostávať upozornenia, pretože pozeráte štítok na tejto téme.' '3_6': 'Budete dostávať upozornenia, pretože pozeráte túto kategóriu.' @@ -1234,10 +1309,10 @@ sk: '0_2': 'Ignorujete všetky upozornenia k tejto téme.' '0': 'Ignorujete všetky upozornenia k tejto téme.' watching_pm: - title: "Pozerať" + title: "Pozorovať" description: "Budete upozornený na každú novú odpoveď na túto správu a zobrazí sa počet nových odpovedí." watching: - title: "Pozerať" + title: "Pozorovať" description: "Budete upozornený na každú novu odpoveď na túto tému a zobrazí sa počet nových odpovedí." tracking_pm: title: "Sledovať" @@ -1279,11 +1354,14 @@ sk: pin_globally: "Pripni tému globálne" make_banner: "Banerová téma" remove_banner: "Odstrániť banerovú tému" + reply: + title: 'Odpovedať' + help: 'vytvor odpoveď k tejto téme' clear_pin: title: "Zruš pripnutie" help: "Zruší pripnutie tejto témy takže sa už viac nebude objavovať na vrchu Vášho zoznamu tém" share: - title: 'Zdielaj' + title: 'Zdieľaj' help: 'zdieľaj odkaz na túto tému' flag_topic: title: 'Označ' @@ -1318,6 +1396,7 @@ sk: no_banner_exists: "Neexistuje žiadna banerová téma." banner_exists: "Banerová téma je aktuálne nastavená." inviting: "Pozývam..." + automatically_add_to_groups: "Táto pozvánka obsahuje tiež prístup do týchto skupín:" invite_private: title: 'Pozvať do konverzácie' email_or_username: "Email, alebo používateľské meno pozvaného" @@ -1496,7 +1575,7 @@ sk: like: "Zruš \"Páči sa\"" vote: "Zruš hlasovanie" people: - vote: "hlasovať za toto" + vote: "hlasoval za tento príspevok" by_you: off_topic: "Označíli ste to ako mimo tému" spam: "Označíli ste to ako spam" @@ -1505,7 +1584,7 @@ sk: notify_user: "Poslali ste správu používateľovi " bookmark: "Vytvorili ste si záložku na tento príspevok" like: "Páči sa Vám to" - vote: "Hlasoval ste za tento príspevok" + vote: "Hlasoval si za tento príspevok" by_you_and_others: off_topic: one: "Vy a 1 ďalšia osoba to označílo ako mimo tému" @@ -1654,7 +1733,7 @@ sk: parent: "Nadradená kategória" notifications: watching: - title: "Pozerať" + title: "Pozorovať" description: "Budete automaticky pozerať všetky témy v týchto kategóriách. Budete upozornený na každý nový príspevok v každej téme. Zároveň bude zobrazený počet nových odpovedí." watching_first_post: title: "Pozerať prvý príspevok" @@ -1830,7 +1909,7 @@ sk: other: "{{categoryName}} ({{count}})" help: "najnovšie témy v kategórii {{categoryName}}" top: - title: "Najvýznamnejšie" + title: "Top" help: "najaktívnejšie témy za posledný rok, mesiac, týždeň, alebo deň" all: title: "Za celú dobu" @@ -1867,7 +1946,7 @@ sk: new: 'g, n Nové' unread: 'g, u Neprečítané' categories: 'g, c Kategórie' - top: 'g, t Najvýznamnejšie' + top: 'g, t Top' bookmarks: 'g, b Záložky' profile: 'g, p Profil' messages: 'g, m Správy' @@ -1952,10 +2031,10 @@ sk: manage_groups_description: "Zadefinujte skupiny pre usporiadanie štítkov" notifications: watching: - title: "Pozerať" + title: "Pozorovať" description: "Budete automaticky pozerať všetky témy s týmto štítkom. Budete upozornený na všetky nové príspevky a témy, navyše počet neprečítaných a nových príspevok bude zobrazený pri téme." watching_first_post: - title: "Pozerať prvý príspevok" + title: "Pozorovať prvý príspevok" description: "Budete upozornený iba na prvý príspevok v každej téme s týmto štítkom." tracking: title: "Sledovať" @@ -1987,8 +2066,8 @@ sk: posted: "Neprispeli ste ešte do žiadnej témy." latest: "Nie sú žiadne najnovšie témy." hot: "Nie sú žiadne horúce témy." - bookmarks: "Nemáte ešte žiadne zazáložkované témy." - top: "Nie sú žiadne najvýznamnejšie témy." + bookmarks: "Nemáte ešte žiadne témy v záložkách." + top: "Nie sú žiadne top témy." search: "Nenašli sa žiadne výsledky" bottom: latest: "Žiadne ďalšie najnovšie témy." @@ -1997,7 +2076,7 @@ sk: read: "Žiadne ďalšie prečítané témy." new: "Žiadne ďalšie nové témy." unread: "Žiadne ďalšie neprečítané témy." - top: "Žiadne ďalšie navýznamnejšie témy." + top: "Žiadne ďalšie top témy." bookmarks: "Žiadne ďalšie zazáložkované témy." search: "Žiadne ďalšie výsledky vyhľadávania." invite: @@ -2495,7 +2574,7 @@ sk: nav: new: "Nový" active: "Aktívny" - pending: "Čakajúca" + pending: "Čakajúci" staff: 'Zamestnanci' suspended: 'Odobrate práva' blocked: 'Zablokovaný' @@ -2736,6 +2815,7 @@ sk: plugins: "Pluginy" user_preferences: "Používateľské Nastavenia" tags: "Štítky" + groups: "Skupiny" badges: title: Odznaky new_badge: Nový odznak @@ -2830,6 +2910,7 @@ sk: embed_truncate: "Skrátiť vložené príspevky" embed_whitelist_selector: "CSS selector pre elementy ktoré je možné vkladať" embed_blacklist_selector: "CSS selector pre elementy ktoré nie je možné vkladať" + embed_classname_whitelist: "Dovolené názvy CSS tried" feed_polling_enabled: "importovať príspevky cez RSS/ATOM" feed_polling_url: "URL adresa RSS/ATOM kanála na preskúmanie" save: "Uložiť Nastavenia vkladania" @@ -2848,3 +2929,23 @@ sk: label: "Nový:" add: "Pridať" filter: "Hľadať (URL alebo externá URL)" + wizard_js: + wizard: + done: "Hotovo" + back: "Späť" + next: "Ďalej" + step: "%{current} z %{total}" + upload: "Načítať" + uploading: "Načítavam..." + quit: "Možno neskôr" + staff_count: + one: "Vaša komunita má 1 člena. " + few: "Vaša komunita má %{count} členov. " + other: "Vaša komunita má %{count} členov. " + invites: + add_user: "pridať" + none_added: "Neprizvali ste žiadnych členov. Určite chcete pokračovať?" + roles: + admin: "Administrátor" + moderator: "Moderátor" + regular: "Bežný používateľ" diff --git a/config/locales/client.ur.yml b/config/locales/client.ur.yml index 7655b9266b..1cef98ba23 100644 --- a/config/locales/client.ur.yml +++ b/config/locales/client.ur.yml @@ -9,7 +9,7 @@ ur: js: number: format: - separator: "." + separator: "کوئی نہیں" delimiter: "،" human: storage_units: @@ -458,21 +458,816 @@ ur: notifications: "اطلاعات" statistics: "اعدادوشمار" desktop_notifications: + label: "ڈیسک ٹاپ اطلاعات" + not_supported: "نوٹیفیکیشن اس براؤزر کے لیئے غیر معاون ہیں۔ معذرت۔" + perm_default: "اطلاعات چالو کریں" + perm_denied_btn: "اِجازت نہیں دی گئی" + perm_denied_expl: "آپ نے اطلاعات کے لئے اجازت دینے سے انکار کر دیا۔ اپنے براؤزر کی ترتیبات سے اطلاعات کی اجازت دیں۔" + disable: "اطلاعات غیر فعال کریں" + enable: "اطلاعات فعال کریں" each_browser_note: "نوٹ: آپ کو ہر براؤزر پر اس سیٹنگ کو تبدیل کرنا ہوگا." + dismiss_notifications: "سب بر خاست کریں" + dismiss_notifications_tooltip: "تمام بغیر پڑھی اطلاعات کو پڑھی جا چکی اطلاعات کے طور پر مارک کریں" + first_notification: "آپ کی پہلی نوٹیفکیشن! شروع کرنے کے لئے اسے منتخب کریں۔" + disable_jump_reply: "میرے جواب دینے کے بعد میری پوسٹ پر نہ جائیں" + dynamic_favicon: "براؤزر آئکن پر نئے / اَپ ڈیٹ ہوئے ٹاپکس کی گنتی دکھائیں" + external_links_in_new_tab: "تمام بیرونی ویب سائٹ کے لنکس ایک نئے ٹیب میں کھولیں" + enable_quoting: "روشنی ڈالے گئے متن کے لئے اقتباسی جواب فعال کریں" + change: "بدلیں" + moderator: "{{صارف}} ایک ماڈریٹر ہے" + admin: "{{صارف}} ایک ایڈمِن ہے" moderator_tooltip: "یہ صارف ایک ماڈریٹر ہے" admin_tooltip: "یہ صارف ایک ایڈمِن ہے" blocked_tooltip: "یہ صارف بلاک کیا ہوا ہے" + suspended_notice: "ہ صارف {{تاریخ}} تک معطل ہے۔" suspended_reason: "وجہ:" github_profile: "گِٹ حَب" + email_activity_summary: "سرگرمی کا خلاصہ" + mailing_list_mode: + label: "میلنگ لسٹ کے موڈ" + enabled: "میلنگ لسٹ کے موڈ فعال کریں" + daily: "روزانہ اپ ڈیٹس بھیجیں" + individual: "ہر نئی پوسٹ پر ایک ای میل بھیجیں" + individual_no_echo: "میری اپنی کے سوا، ہر نئی پوسٹ پر ایک ای میل بھیجیں" + many_per_day: "ہر نئی پوسٹ پر ایک ای میل بھیجیں (تقریبا {{یومیہ ای میل تخمینہ}} فی دن)" + few_per_day: "ہر نئی پوسٹ پر ایک ای میل بھیجیں (تقریبا 2 فی دن)" + tag_settings: "ٹیگز" + watched_tags: "دیکھا گیا" + watched_tags_instructions: "آپ خود کار طریقے سے اِن ٹیگ والے ٹاپکس کو دیکھیں گے۔ تمام نئی پوسٹ اور ٹاپکس کے بارے میں مطلع کیا جائے گا، اور نئی پوسٹس کی گنتی بھی ٹاپک کے ساتھ دکھائی جائے گی۔" + tracked_tags: "ٹریک کیا ہوا" + tracked_tags_instructions: "آپ خود کار طریقے سے اِن ٹیگ والے ٹاپکس کو ٹریک کریں گے۔ نئی پوسٹس کی گنتی ٹاپک کے ساتھ دکھائی جائے گی۔" + muted_tags: "خاموش کِیا ہوا" + muted_tags_instructions: "آپ کو اِن ٹیگ والے نئے ٹاپکس کی کسی بھی چیز کے بارے میں مطلع نہیں کیا جائے گا، اور یہ تازہ ترین میں بھی نظر نہیں آئیں گے۔" + watched_categories: "دیکھا گیا" + watched_categories_instructions: "آپ خود کار طریقے سے اِن زمرہ جات میں موجود تمام ٹاپکس کو دیکھیں گے۔ تمام نئی پوسٹ اور ٹاپکس کے بارے میں مطلع کیا جائے گا، اور نئی پوسٹس کی گنتی بھی ٹاپک کے ساتھ دکھائی جائے گی۔" + tracked_categories: "ٹریک کیا ہوا" + tracked_categories_instructions: "آپ خود کار طریقے سے اِن زمرہ جات میں موجود تمام ٹاپکس کو ٹریک کریں گے۔ نئی پوسٹس کی گنتی ٹاپک کے ساتھ دکھائی جائے گی۔" + watched_first_post_categories: "پہلی پوسٹ پر نظر رکھی ہوئی ہے" + watched_first_post_categories_instructions: "آپ کو اِن زمرہ جات میں ہر نئے ٹاپک کی پہلی پوسٹ کے بارے میں مطلع کیا جائے گا۔" + watched_first_post_tags: "پہلی پوسٹ پر نظر رکھی ہوئی ہے" + watched_first_post_tags_instructions: "آپ کو اِن ٹیگ والے ہر نئے ٹاپک کی پہلی پوسٹ کے بارے میں مطلع کیا جائے گا۔" + muted_categories: "خاموش کِیا ہوا" + muted_categories_instructions: "آپ کو اِن زمرہ جات میں موجود نئے ٹاپکس کی کسی بھی چیز کے بارے میں مطلع نہیں کیا جائے گا، اور یہ تازہ ترین میں بھی نظر نہیں آئیں گے۔" + delete_account: "میرا اکاؤنٹ حذف کریں" + delete_account_confirm: "کیا آپ واقعی مستقل طور پر اپنا اکاؤنٹ حذف کرنا چاہتے ہیں؟ اس عمل کو کالعدم نہیں کیا جا سکتا!" + deleted_yourself: "آپ کے اکاؤنٹ کو کامیابی سے حزف کر دیا گیا ہے۔" + delete_yourself_not_allowed: "آپ ابھی اپنے اکاؤنٹ کو حذف نہیں کرسکتے۔ آپ کے لئے اکاؤنٹ حزف کرنے کے لئے ایک ایڈمن سے رابطہ کریں۔" + unread_message_count: "پیغامات" + admin_delete: "حذف کریں" + users: "صارفین" + muted_users: "خاموش کِیا ہوا" + muted_users_instructions: "اِن صارفین کی طرف سے تمام اطلاعات کو روکیں۔" + muted_topics_link: "خاموش کردیے گئے ٹاپکس دکھائیں" + watched_topics_link: "دیکھے گئے ٹاپک ظاہر کریں" + automatically_unpin_topics: "جب میں سب سے نیچے تک پہنچوں تو خود کار طریقے سے ٹاپک سے پن ہٹایں۔" + apps: "ایپس" + revoke_access: "رسائی کالعدم کریں" + undo_revoke_access: "رسائی کالعدم کو منسوخ کریں" + api_approved: "منظورشدہ" + staff_counters: + flags_given: "مدد گار نشان" + flagged_posts: "نشان زدہ پوسٹ" + deleted_posts: "حذف کی گئی پوسٹس" + suspensions: "معطلیاں" + warnings_received: "تنبیہات" + messages: + all: "تمام" + inbox: "اِن باکس" + sent: "بھیجا جا چکا" + archive: "آر کائیو" + groups: "میرے گروپ" + bulk_select: "پیغامات منتخب کریں" + move_to_inbox: "اِنباکس میں منتقل کریں" + move_to_archive: "آر کائیو" + failed_to_move: "منتخب شدہ پیغامات کو منتقل کرنے میں ناکامی (شاید آپ کے نیٹ ورک بند ہے)" + select_all: "تمام منتخب کریں" + change_password: + success: "(اِی میل بھیج دی گئ)" + in_progress: "(اِی میل بھیجی جا رہی ہے)" + error: "(خرابی)" + action: " پاس ورڈ دوبارہ سیٹ کرنے کی اِی میل بھیجیں" + set_password: "پاس ورڈ رکھیں" + choose_new: "نیا پاس ورڈ منتخب کریں" + choose: "پاس ورڈ منتخب کریں" + change_about: + title: "\"میرے بارے میں\" تبدیل کریں" + error: "اِس چیز کو تبدیل کرنے میں ایک خرابی کا سامنا کرنا پڑا۔" + change_username: + title: "صارف کا نام تبدیل کریں" + confirm: "اگر آپ اپنا صارف نام تبدیل کرتے ہیں تو آپ کی پوسٹوں کی پچھلی تمام اقتباسات اور @نام زکر ٹوٹ جائیں گے۔ کیا آپ واقعی یہ کرنا چاہتے ہیں؟" + taken: "معذرت، یِہ صارف نام پہلے سے لیا جاچکا ہے۔" + error: "آپ کا صارف نام تبدیل کرنے میں ایک خرابی کا سامنا کرنا پڑا۔" + invalid: "یہ صارف نام غلط ہے۔ اِس میں صرف ہندسوں اور حروف کو شامل کیا جا سکتا ہے" + change_email: + title: "اِی میل تبدیل کریں" + taken: "معذرت، یہ اِی میل دستیاب نہیں ہے۔" + error: "آپ کا اِی میل تبدیل کرنے میں ایک خرابی کا سامنا کرنا پڑا۔ شاید یہ ایڈریس پہلے سے استعمال میں ہے؟" + success: "ہم نے اِس ایڈریس پر ایک اِی میل بھیج دی ہے۔ براہ کرم، تصدیق کی ہدایات پر عمل کریں۔" + change_avatar: + title: "اپنے پروفائل کی تصویر تبدیل کریں" + gravatar: "گَرِیوَّٹار، کی بنیاد پر" + gravatar_title: "گَرِیوَّٹار کی ویب سائٹ پر اپنے اوتار کو تبدیل کریں" + refresh_gravatar_title: "اپنے گَرِیوَّٹار کو رِیفریش کریں" + letter_based: "سسٹم تفویض کردہ پروفائل تصویر" + uploaded_avatar: "اپنی مرضی کی تصویر" + uploaded_avatar_empty: "اپنی مرضی کی تصویر شامل کریں" + upload_title: "آپنی تصویر اَپ لوڈ کریں" + upload_picture: "تصویر اَپ لوڈ کریں" + image_is_not_a_square: "انتباہ: ہم نے آپ کی تصویر کو کراپ کیا ہے؛ چوڑائی اور اونچائی برابر نہیں تھے۔" + cache_notice: "آپ نے کامیابی سے اپنی پروفائل تصویر تبدیل کرلی ہے لیکن براؤزر کیشنگ کی وجہ سے اِسے نمودار ہونے میں کچھ وقت لگ سکتا ہے۔" + change_profile_background: + title: "پروفائل کا پسِ منظر" + instructions: "پروفائل کا پسِ منظر مرکوز ہو گا اور اُس کی 850 پِکسل کی پہلے سے طے شدہ چوڑائی ہو گی۔" + change_card_background: + title: "صارف کارڈ کا پسِ منظر" + instructions: "پسِ منظر کی تصاویر مرکوز ہوں گی اور اُن کی 590 پِکسل کی پہلے سے طے شدہ چوڑائی ہو گی۔" + email: + title: "اِی میل" + instructions: "کبھی بھی عوام کو نہیں دکھایا گیا" + ok: "ہم تصدیق کے لئے آپ کو اِی میل کریں گے" + invalid: "براہ کرم، ایک قابلِ قبول ایِ میل ایڈریس درج کریں" + authenticated: "آپ کے اِی میل کی توثیق کر دی گئی ہے {{فراہم کنندہ}}" + frequency_immediately: "جس بارے میں ہم آپ کو اِی میل کر رہے ہیں، اگر آپ نے نہیں پڑھی ہوئی تو ہم فوری طور پر آپ کو اِی میل کریں گے۔" + frequency: + one: "ہم آپ کو اِی میل کریں گے صرف اُس صور میں کہ ہم نے آپ کو گزشتہ ایک منٹ میں نہ دیکھا ہو۔" + other: "ہم آپ کو اِی میل کریں گے صرف اُس صور میں کہ ہم نے آپ کو گزشتہ {{شمار}} منٹ میں نہ دیکھا ہو۔" name: + title: "نام" + instructions: "آپ کا پورا نام (اختیاری)" instructions_required: "آپ کا پورا نام" too_short: "آپ کا نام بہت چھوٹا ہے" ok: "آپ کا نام صحیح لگ رہا ہے" username: title: "صارف کا نام" + instructions: "منفرد، کوئی خالی جگہ نہیں، مختصر" + short_instructions: "لوگ آپ کا زکر @{{صارف نام}} کے طور پر کر سکتے ہیں" + available: "آپ کا صارف نام دستیاب ہے" + not_available: "دستیاب نہیں۔ اِستعمال کریں {{تجویز}}؟" + not_available_no_suggestion: "دستیاب نہیں" + too_short: "آپ کا صارف نام بہت چھوٹا ہے" + too_long: "آپ کا صارف نام بہت طویل ہے" + checking: "صارف نام کی دستیابی کی جانچ ہو رہی..." + prefilled: "اِی میل اِس رجسٹرڈ صارف نام کے ساتھ میچ کرتا ہے" + locale: + title: "انٹرفیس کی زبان" + instructions: "صارف کیلئے انٹرفیس کی زبان۔ یہ اُس وقت تبدیل ہو گی جب آپ وِیب سائٹ رِیفریش کریں ۔" + default: "(ڈِیفالٹ)" + any: "کوئی بھی" + password_confirmation: + title: "پاس ورڈ دوبارہ" + last_posted: "آخری پوسٹ" + last_emailed: "جِسے آخری دفع اِی میل کی گئی" + last_seen: "دیکھا ہوا" + created: "شمولیت اختیار کی" + log_out: "لاگ آُوٹ" + location: "محل وقوع" + card_badge: + title: "صارف کارڈ بیج" + website: "وِیب سائٹ" + email_settings: "اِی میل" + like_notification_frequency: + title: "جب لائک کیا جائے تو مطلع کریں" + always: "ہمیشہ" + first_time_and_daily: "پہلی بار پوسٹ کو لائک کیا جائے اور روزانہ" + first_time: "پہلی بار پوسٹ کو لائک کیا جائے" + never: "کبھی نہیں " + email_previous_replies: + title: "اِی میل کے نچلے حصے میں پچھلے جوابات شامل کریں" + unless_emailed: "اگر ماضی میں بھیجا گیا ہو، تو نہیں" + always: "ہمیشہ" + never: "کبھی نہیں " + email_digests: + title: "جب میں یہاں کا دورا نہ کروں، مجھے مقبول ٹاپک اور جوابات کا ایک اِی میل خلاصہ بھیجیں" + every_30_minutes: "ہر 30 منٹ" + every_hour: "گھنٹہ وار" + daily: "روزانہ " + every_three_days: "ہر تین دن" + weekly: "ہفتہ وار" + every_two_weeks: "ہر دو ہفتے" + include_tl0_in_digests: "اِی میل خلاصہ میں نئے صارفین سے مواد شامل کریں" + email_in_reply_to: "ای میل میں پوسٹ کے جواب کا اقتباس شامل کریں" + email_direct: "مجھے ایک اِی میل بھیجیں اگر کوئی میرے پوسٹ کا اقتباس کرے، میری پوسٹ کا جواب دے، میرے @صارفنام کا تذکرا کرے، یا پجھے کسی ٹاپک میں مدعو کرے" + email_private_messages: "اگر کوئی مجھے پیغام بھیجیے تو مجھے ایک اِی میل بھیجیں" + email_always: "اگر میں ویب سائٹ پر فعال ہوں تو پھر بھی مجھے اِی میل اطلاعات بھیجیں" + other_settings: "دیگر" + categories_settings: "زُمرَہ جات" + new_topic_duration: + label: "ٹاپک کو نیا سمجھا جائے، جب" + not_viewed: "میں نے اُنہیں ابھی تک نہیں دیکھا" + last_here: "میرے آخری دفع یہاں آنے کے بعد بنائے گئے" + after_1_day: "پچھلے ایک دن میں بنائے گئے" + after_2_days: "پچھلے 2 دنوں میں بنائے گئے" + after_1_week: "پچھلے ایک ہفتے میں بنائے گئے" + after_2_weeks: "پچھلے 2 ہفتوں میں بنائے گئے" + auto_track_topics: "جس ٹاپک میں مَیں داخل ہوں اُسے خود کار طریقے سے ٹریک کریں" + auto_track_options: + never: "کبھی نہیں " + immediately: "ابھی اِسی وقت" + after_30_seconds: "30 سیکنڈ کے بعد" + after_1_minute: "1 منٹ کے بعد" + after_2_minutes: "2 منٹ کے بعد" + after_3_minutes: "3 منٹ کے بعد" + after_4_minutes: "4 منٹ کے بعد" + after_5_minutes: "5 منٹ کے بعد" + after_10_minutes: "10 منٹ کے بعد" + notification_level_when_replying: "جب میں ایک ٹاپک میں پوسٹ کروں، اُس ٹاپک کو مقرر کریں" + invited: + search: "دعوتیں تلاش کرنے کے لئے ٹائپ کریں..." + title: "دعوتیں" + user: "مدعو کیا گیا صارف" + sent: "بھیج دیا گیا" + none: "ظاہر کرنے کے لئے کوئی زیر التواء دعوتیں نہیں ہیں۔" + truncated: + one: "پہلی دعوت دکھائی جا رہی ہیں۔" + other: "پہلی {{شمار}} دعوتیں دکھائی جا رہی ہیں۔" + redeemed: "دعوتیں جِن سے فائدہ اٹھا لیا گیا ہے" + redeemed_tab: "فائدہ اٹھا لیا گیا" + redeemed_tab_with_count: "فائدہ اٹھا لیا گیا ({{شمار}})" + redeemed_at: "فائدہ اٹھا لیا گیا" + pending: "زیرِالتواء دعوتیں" + pending_tab: "زیرِالتواء" + pending_tab_with_count: "زیرِالتواء ({{شمار}})" + topics_entered: " دیکھ لیے گئے ٹاپک" + posts_read_count: " پڑھ لی گئیں پوسٹ" + expired: "اِس دعوت کی میعاد ختم ہو چکی ہے۔" + rescind: "خارج کریں" + rescinded: "دعوت خارج کر دی گئی" + reinvite: "دعوت دوبارہ بھیجیں" + reinvite_all: "تمام دعوتیں دوبارہ بھیجیں" + reinvited: "دعوت دوبارہ بھیج دی گئی" + reinvited_all: "تمام دعوتیں دوبارہ بھیج دی گئیں!" + time_read: "وقت جو پڑھنے کیلیئے صرف ہوا" + days_visited: "دورہ کیے گئے دن" + account_age_days: "دنوں میں اکاؤنٹ کی عمر" + create: "ایک دعوت بھیجیں" + generate_link: "دعوت لنک کاپی کریں" + link_generated: "دعوت لنک کامیابی سے بن گیا!" + valid_for: "دعوت لنک صرف اِس اِی میل اِیڈریس کے لئے درست ہے:٪{اِیمیل}" + bulk_invite: + none: "آپ نے یہاں ابھی تک کسی کو بھی مدعو نہیں کیا۔ انفرادی طار پر دعوت نامے ارسال کریں، یا ایک CSV فائل اَپ لوڈ کرکے ایک وقت میں ہی بہت سے لوگوں کو دعوت دیں۔" + text: "فائل کی مدد سے ایک وقت میں بہت سے لوگوں کو دعوت دیں" + success: "فائل کامیابی سے اَپ لوڈ کر دی گئی، عمل مکمل ہونے پر آپ کو پیغام کے ذریعے مطلع کر دیا جائے گا۔" + error: "معذرت، فائل CSV فارمیٹ میں ہونا ضروری ہے۔" + password: + title: "پاسورڈ" + too_short: "آپ کا پاسورڈ بہت چھوٹا ہے" + common: "وہ پاسورڈ کافی عام ہے" + same_as_username: "آپ کا پاسورڈ وہی ہے جو آپ کا صارف نام ہے۔" + same_as_email: "آپ کا پاسورڈ وہی ہے جو آپ کا اِی میل ہے۔" + ok: "آپ کا پاسورڈ صحیح لگ رہا ہے" + instructions: "کم از کم {شمار} حروف" + summary: + title: "خلاصہ" + stats: "اعدادوشمار" + time_read: "وقت جو پڑھنے کیلیئے صرف ہوا" + topic_count: + one: "بنایا گیا ٹاپک" + other: "بنائے گئے ٹاپک" + post_count: + one: "بنائی گئی پوسٹ" + other: "بنائی گئیں پوسٹ" + likes_given: + one: " دیا گیا" + other: " دیا گیا" + likes_received: + one: " موصول ہوئے" + other: " موصول ہوئے" + days_visited: + one: "دن جس میں دورہ کیا گیا" + other: "دن جن میں دورہ کیا گیا" + posts_read: + one: "پوسٹ جو پڑھی گئی" + other: "پوسٹ جو پڑھی گئیں" + bookmark_count: + one: "بُک مارک" + other: "بُکمارکس" + top_replies: "ٹاپ جوابات" + no_replies: "ابھی تک کوئی جوابات نہیں۔" + more_replies: "مزید جوابات" + top_topics: "ٹاپ ٹاپک" + no_topics: "ابھی تک کوئی ٹاپک نہیں۔" + more_topics: "مزید ٹاپک" + top_badges: "ٹاپ بَیج" + no_badges: "ابھی تک کوئی بَیج نہیں۔" + more_badges: "مزید بَیج" + top_links: "ٹاپ لنکس" + no_links: "ابھی تک کوئی لنکس نہیں۔" + most_liked_by: "جس کی طرف سے سب سے زیادہ لائک کیا گیا" + most_liked_users: "سب سے زیادہ لائک کیا گیا" + most_replied_to_users: "جس کو سب سے زیادہ جواب دیا گیا" + no_likes: "ابھی تک کوئی لائکس نہیں۔" + associated_accounts: "لاگ ان" + ip_address: + title: "آخری IP ایڈریس" + registration_ip_address: + title: "رجسٹریشن IP ایڈریس" + avatar: + title: "پروفائل تصویر" + header_title: "پروفائل، پیغامات، بک مارکس اور ترجیحات" + title: + title: "عنوان" + filters: + all: "تمام" + stream: + posted_by: "کی طرف سے پوسٹ کیا گیا" + sent_by: "کی طرف سے بھیجا گیا" + private_message: "پیغام" + the_topic: "ٹاپک" + loading: "لوڈ ہو رہا ہے..." + errors: + prev_page: "لوڈ کرتے ہوئے" + reasons: + network: "نیٹ ورک کی خرابی" + server: "سرور کی خرابی" + forbidden: "رسائی سے اِنکار کر دیا گیا" + unknown: "خرابی" + not_found: "صفحہ نہیں ملا" + desc: + network: " براہِ مہربانی اپنا کنکشن چیک کریں" + network_fixed: "لگتا ہے یہ وآپس آ گیا" + server: "خرابی کوڈ: {{اسٹیٹس}}" + forbidden: "آپ کو یہ دیکھنے کی اجازت نہیں ہے۔" + not_found: "افوہ، ایپلیکیشن نے ایک ایسے URL کو لوڈ کرنے کی کوشش جو غیر موجود ہے۔" + unknown: "کچھ غلط ہو گیا۔" + buttons: + back: "واپس جائیں" + again: "دوبارہ کوشش کریں" + fixed: "پیج لوڈ کریں" + close: "بند کریں" + assets_changed_confirm: "یہ ویب سائٹ ابھی ابھی اَپ ڈیٹ کی گئی ہے۔ تازہ ترین ورژن کے لئے ابھی رِیفریش کریں؟" + logout: "آپ لاگ آؤٹ ہو گئے تھے۔" + refresh: "رِیفریش" + read_only_mode: + enabled: "یہ سائٹ صرف پڑھنے کے مَوڈ میں ہے۔ براہِ مہربانی براؤز کرتے رہئیے، لیکن جواب دینا، لائکس دینا، اور دیگر اعمال ابھی کے لئے غیر فعال ہیں۔" + login_disabled: "جب تک سائٹ صرف پڑھنے کے مَوڈ میں ہے لاگ اِن غیر فعال رہے گا۔" + logout_disabled: "جب تک سائٹ صرف پڑھنے کے مَوڈ میں ہے لاگ آؤٹ غیر فعال رہے گا۔" + too_few_topics_and_posts_notice: "چلیں اِس بحث کو شروع کریں! اِس وقت اَبھی ٪{موجودہ ٹاپک}/٪{درکار ٹاپک} ٹاپک اور ٪{موجودہ پوسٹ}/٪{درکار پوسٹ} پوسٹ ہیں۔ نئے زائرین کو پڑھنے اور اُن کا جواب دینے کیلئے کچھ مکالمات کی ضرورت ہے۔" + too_few_topics_notice: "چلیں اِس بحث کو شروع کریں! اِس وقت اَبھی ٪{موجودہ ٹاپک}/٪{درکار ٹاپک} ٹاپک ہیں۔ نئے زائرین کو پڑھنے اور اُن کا جواب دینے کیلئے کچھ مکالمات کی ضرورت ہے۔" + too_few_posts_notice: "چلیں اِس بحث کو شروع کریں! اِس وقت اَبھی ٪{موجودہ پوسٹ}/٪{درکار پوسٹ} پوسٹ ہیں۔ نئے زائرین کو پڑھنے اور اُن کا جواب دینے کیلئے کچھ مکالمات کی ضرورت ہے۔" + logs_error_rate_notice: + rate: + one: "1 خرابی/٪{مدت}" + other: "٪{شمار} خرابیاں/٪{مدت}" + learn_more: "اورجانیے..." + all_time: 'کُل' + all_time_desc: 'کُل ٹاپک بنائے گئے' + year: 'سال' + year_desc: 'پچھلے 365 دنوں میں بنائے گئے ٹاپک' + month: 'مہینہ' + month_desc: 'پچھلے 30 دنوں میں بنائے گئے ٹاپک' + week: 'ہفتہ' + week_desc: 'پچھلے 7 دنوں میں بنائے گئے ٹاپک' + day: 'دن' + first_post: پہلی پوسٹ + mute: خاموش کریں + unmute: آواز چالو کریں + last_post: آخری پوسٹ + last_reply_lowercase: آخری جواب + replies_lowercase: + one: جواب + other: جوابات + signup_cta: + sign_up: "سائن اپ" + hide_session: "مجھے کل یاد دلائیں" + hide_forever: "نہیں شکریہ" + hidden_for_session: "ٹھیک ہے، میں تم سے کَل پوچھوں گا۔ آپ جب چاہیں، اکاؤنٹ بنانے کے لئے 'لاگ اِن' بھی استعمال کر سکتے ہیں." + intro: "خوش آمدید! :heart_eyes: ایسا لگتا ہے آپ بحث سے لطف اندوز ہو رہے ہیں، لیکن آپ نے اکاؤنٹ کے لئے سائن اَپ نہیں کیا ہوا۔" + value_prop: "جب آپ ایک اکاؤنٹ بناتے ہیں، ہم بالکل یاد رکھتے ہیں کہ آپ نے کیا پڑھا ہے، تاکہ جہاں سے آپ نے پڑھنا چھوڑا ہو بلکل وہاں ہی پر آپ کو ہمیشہ واپس پہنچایا جا سکے۔ جب بھی کوئی نئی پوسٹ ہوتی ہے آپ کو یہاں اور اِی میل پر اطلاع بھی دے دی جاتی ہے۔ اور آپ محبت کا بانٹںے کے لئے پوسٹ لائک کر سکتے ہیں۔ :heartbeat:" + summary: + enabled_description: "آپ اس ٹاپک کا خلاصہ ملاحظہ کررہے ہیں: سب سے دلچسپ پوسٹ کمیونٹی کی طرف سے متعین کی جاتی ہیں۔" + description: "{{replyCount}} جوابات موجود ہیں۔" + description_time: "{{replyCount}} جوابات موجود ہیں جن کو پڑھنے کے وقت کا تخمینہ < {{readingTime}} ہے۔" + enable: 'اس ڑاپک کا خلاصہ کریں' + disable: 'تمام پوسٹیں دکھائیں' + deleted_filter: + enabled_description: "اِس ٹاپک میں حذف شدہ پوسٹ شامل ہیں، جو چھپا دی گئی ہیں۔" + disabled_description: "ٹاپک کی حذف شدہ پوسٹ دکھائی گئی ہیں۔" + enable: "حذف شدہ پوسٹس کو چھپائیں" + disable: "حذف شدہ پوسٹس کو ظاہر کریں" + private_message_info: + title: "پیغام" + invite: "دوسروں کو مدعو کریں..." + remove_allowed_user: "کیا آپ واقعی اِس پیغام سے {{نام}} ہٹانا چاہتے ہیں؟" + remove_allowed_group: "کیا آپ واقعی اِس پیغام سے {{نام}} ہٹانا چاہتے ہیں؟" + email: 'اِی میل' + username: 'صارف نام' + last_seen: 'دیکھا گیا' + created: 'بنایا گیا' + created_lowercase: 'بنایا گیا' + trust_level: 'ٹرسٹ لیول' + search_hint: 'صارف نام، ای میل یا IP ایڈریس' + create_account: + disclaimer: "رجسٹر کرنے پر آپ <{{a href='{{privacy link>زاتی معلومات کی حفاظتی پالیسی اور سروس کی شرائط۔" + title: "نیا اکاؤنٹ بنائیں" + failed: "کچھ غلط ہو گیا، شاید یہ ای میل پہلے ہی سے رجسٹرڈ ہے، پاسورڈ بھول جانے والا لنک اِستعمال کر کے دیکھیں" + forgot_password: + title: "پاسورڈ رِی سَیٹ" + action: "میں اپنا پاسورڈ بھول گیا" + invite: "اپنا صارف نام یا اِی میل ایڈریس درج کریں، اور ہم آپ کو ایک پاسورڈ رِی سیٹ ای میل بھیج دیں گے۔" + reset: "پاسورڈ رِی سَیٹ کریں" + complete_username: "اگر کوئی اکاؤنٹ صارف نام ٪{صارف نام} سے ملتا ہو گا، تو آپ کو پاسورڈ ری سیٹ کرنے کے لئے ہدایات کی ایک اِی میل جلد ہی موصول ہو جائے گی۔" + complete_email: "اگر کوئی اکاؤنٹ ٪{اِیمیل} سے ملتا ہو گا، تو آپ کو پاسورڈ ری سیٹ کرنے کے لئے ہدایات کی ایک اِی میل جلد ہی موصول ہو جائے گی۔" + complete_username_found: "ہمیں ایک اکاؤنٹ ملا ہے جو صارف نام ٪{صارف نام} سے میچ کرتا ہے، آپ کو پاسورڈ ری سیٹ کرنے کے لئے ہدایات کی ایک اِی میل جلد ہی موصول ہو جائے گی۔" + complete_email_found: "ہمیں ایک اکاؤنٹ ملا ہے جو ٪{اِیمیل} سے میچ کرتا ہے، آپ کو پاسورڈ ری سیٹ کرنے کے لئے ہدایات کی ایک اِی میل جلد ہی موصول ہو جائے گی۔" + complete_username_not_found: "کوئی اکاؤنٹ صارف نام ٪{صارف نام} سے میچ نہیں کرتا" + complete_email_not_found: "کوئی اکاؤنٹ ٪{اِیمیل} سے میچ نہیں کرتا" + login: + title: "لاگ اِن" + username: "صارف" + password: "پاسورڈ" + email_placeholder: "اِی میل یا صارف نام" + caps_lock_warning: "کیپس لاک آن ہے" + error: "نامعلوم خرابی" + rate_limit: "دوبارہ لاگ اِن کرنے کی کوشش کرنے سے پہلے براہ کرم تھوڑا انتظار کریں۔" + reset_password: 'پاسورڈ رِی سَیٹ کریں' + logging_in: "لاگ اِن ہو رہا ہے..." + or: "یا" + authenticating: "تصدیق کی جا رہی ہے..." + awaiting_activation: "آپ کا اکاؤنٹ ایکٹیویشن کا انتظار کر رہا ہے، \"پاسورڈ بھول جانے\" والا لنک استعمال کر کہ ایک اور ایکٹیویشن اِی میل جاری کریں۔" + awaiting_approval: "آپ کا اکاؤنٹ ابھی تک عملے کے کسی رکن کی طرف سے منظور نہیں کیا گیا۔ جب یہ منظوری مل جائے گی تو آپ کو ایک ای میل بھیج دی جائے گی۔" + requires_invite: "معذرت، اس فورم تک رسائی صرف دعوت کے زریعے ممکن ہے۔" + not_activated: "ابھی آپ لاگ ان نہیں کر سکتے۔ ہم پہلے آپ کو ایک ایکٹیویشن اِی میل {{sentTo}} پر بھیج چکے ہیں۔ براہ مہربانی، اپنے اکاؤنٹ کو چالو کرنے کے لئے اُس اِی میل میں دی گئی ہدایات پر عمل کریں۔" + not_allowed_from_ip_address: "آپ اِس آئی پی ایڈریس سے لاگ اِن نہیں ہو سکتے۔" + admin_not_allowed_from_ip_address: "آپ ایڈمن کے طور پر اِس آئی پی ایڈریس سے لاگ اِن نہیں ہو سکتے۔" + resend_activation_email: "دوبارہ ایکٹیویشن ای میل بھیجنے کے لئے یہاں کلک کریں۔" + sent_activation_email_again: "ہم نے آپ کو {{currentEmail}} پر ایک اور ایکٹیویشن اِی میل بھیجی ہے۔ اسے پہنچنے میں چند منٹ لگ سکتے ہیں؛ اپنے سپیم فولڈر کو چیک کرنا نہ بھولیے گا۔" + to_continue: "برائے مہربانی لاگ اِن کریں" + preferences: "آپ کا اپنی صارف ترجیحات کو تبدیل کرنے کے لیے لاگ اِن ہونا ضروری ہے۔" + forgot: "مجھے اپنے اکاؤنٹ کی تفصیلات یاد نہیں ہیں" + not_approved: "آپ کا اکاؤنٹ ابھی تک منظور نہیں کیا گیا ہے۔ جب آپ لاگ اِن کر سکیں گو اِی میل کے ذریعے آپ کو مطلع کر دیا جائے گا۔" + google: + title: "گوگل سے" + message: "گُوگَل کے زریعے تصدیق کی جا رہی ہے (یقینی بنائیں کہ پاپ اَپ بلاکرز فعال نہیں ہیں)" + google_oauth2: + title: "گوگل سے" + message: "گُوگَل کے زریعے تصدیق کی جا رہی ہے (یقینی بنائیں کہ پاپ اَپ بلاکرز فعال نہیں ہیں)" + twitter: + title: "ٹویٹر سے" + message: "ٹویٹر کے زریعے تصدیق کی جا رہی ہے (یقینی بنائیں کہ پاپ اَپ بلاکرز فعال نہیں ہیں)" + instagram: + title: "اِنسٹاگرام سے" + message: "اِنسٹاگرام کے زریعے تصدیق کی جا رہی ہے (یقینی بنائیں کہ پاپ اَپ بلاکرز فعال نہیں ہیں)" + facebook: + title: "فیس بک سے" + message: "گُوگَلفیس بک کے زریعے تصدیق کی جا رہی ہے (یقینی بنائیں کہ پاپ اَپ بلاکرز فعال نہیں ہیں)" + yahoo: + title: "یاہُو سے" + message: "یاہُو کے زریعے تصدیق کی جا رہی ہے (یقینی بنائیں کہ پاپ اَپ بلاکرز فعال نہیں ہیں)" + github: + title: "گِٹ ہَب سے" + message: "گِٹ ہَب کے زریعے تصدیق کی جا رہی ہے (یقینی بنائیں کہ پاپ اَپ بلاکرز فعال نہیں ہیں)" + invites: + accept_title: "دعوت نامہ" + welcome_to: "{SITE_NAME}٪ پر خوش آمدید!" + invited_by: "آپ کو جن کی طرف سے مدعو کیا گیا تھا:" + your_email: "آپ کے اکاؤنٹ کا اِیمیل ایڈریس ٪{اِیمیل} ہے۔" + accept_invite: "دعوت قبول کریں" + success: "آپ کا اکاؤنٹ بنا دیا گیا ہے اور اب آپ لاگ اِن کر سکتے ہیں۔" + password_label: "پاسورڈ مقرر کریں (اختیاری)" + password_reset: + continue: "{SITE_NAME}٪ پر جاری رکھیں" + emoji_set: + apple_international: "Apple/International" + google: "Google" + twitter: "Twitter" + emoji_one: "Emoji One" + win10: "Win10" + category_page_style: + categories_only: "صرف زمرہ جات" + categories_with_featured_topics: "نمایاں ٹاپکس کے ساتھ زمرہ جات" + categories_and_latest_topics: "تازہ ترین ٹاپکس کے ساتھ زمرہ جات" + shortcut_modifier_key: + shift: 'شفٹ' + composer: + more_emoji: "مزید..." + options: "اختیارات" + whisper: "سرگوشی" + unlist: "غیر مندرج" + add_warning: "یہ ایک آفیشل انتباہ ہے۔" + toggle_whisper: "سرگوشی ٹَوگل کریں" + toggle_unlisted: "غیر مندرج ٹَوگل کریں" + posting_not_on_topic: "کون سے ٹاپک کا آپ جواب دینا چاہتے ہیں؟" + saving_draft_tip: "محفوظ کیا جا رہا ہے..." + saved_draft_tip: "محفوظ کر لیا گیا" + saved_local_draft_tip: "مقامی طور پر محفوظ کر لیا گیا" + similar_topics: "آپ کا ٹاپک ملتا ہے..." + drafts_offline: "ڈرافٹس آف لائن" + group_mentioned: + one: "{{گروپ}} کا ذکر کر کہ، آپ 1 شخص کو مطلع کرنے لگے ہیں - کیا آپ واقعی یہ کرنا چاہتے ہیں؟" + other: "{{گروپ}} کا ذکر کر کہ، آپ {{شمار}} لوگوں کو مطلع کرنے لگے ہیں - کیا آپ واقعی یہ کرنا چاہتے ہیں؟" + cannot_see_mention: + category: "آپ نے {{صارف نام}} کا زکر کیا ہے لیکن چونکہ اُن کو اِس زمرے تک رسائی حاصل نہیں، اُن کو مطلع نہیں کیا جائے گا۔ آپ کو انہیں ایک ایسے گروپ میں شامل کرنے کی ضرورت ہے جسے اِس زمرے تک رسائی حاصل ہے۔" + private: "آپ نے {{صارف نام}} کا زکر کیا ہے لیکن چونکہ وہ یہ ذاتی پیغام نہیں دیکھ سکتے اُن کو مطلع نہیں کیا جائے گا۔ آپ کو اُنہیں اِس ذاتی پیغام میں مدعو کرنے کی ضرورت ہے۔" + duplicate_link: "آپ کی طرد سے {{ڈومین}} کا لنک، @{{صارف نام}} کی طرف سے {{قبل}} اِس ٹاپک کے ایک جواب میں پہلے ہی پوسٹ ہو چکا ہے - کیا آپ واقعی یہ دوبارہ پوسٹ کرنا چاہتے ہیں؟" + error: + title_missing: "عنوان درکار ہے" + title_too_short: "عنوان میں کم از کم {{min}} حروف ہونا ضروری ہے" + title_too_long: "عنوان {{میکس}} حروف سے زیادہ نہیں ہو سکتا" + post_missing: "پوسٹ خالی نہیں ہو سکتی" + post_length: "پوسٹ میں کم از کم {{min}} حروف ہونا ضروری ہے" + try_like: 'کیا آپ نے بٹن اِستعمال کیا ہے؟' + category_missing: "ایک زمرہ کا انتخاب کرنا ضروری ہے" + save_edit: "ترمیم محفوظ کریں" + reply_original: "حقیقی ٹاپک پر جواب دیں" + reply_here: "یہاں جواب دیں" + reply: "جواب" + cancel: "منسوخ" + create_topic: "ٹاپک بنائیں" + create_pm: "پیغام" + title: "یا Ctrl+Enter دبائیں" + users_placeholder: "ایک صارف شامل کریں" + title_placeholder: "ایک مختصر جملہ میں بتائیے کہ یہ بحث کس چیز کے بارے میں ہے؟" + title_or_link_placeholder: "عنوان ٹائپ کریں، یا ایک لنک یہاں پیسٹ کریں" + edit_reason_placeholder: "آپ ترمیم کیوں کر رہے ہیں؟" + show_edit_reason: "(ترمیم کی وجہ شامل کریں)" + topic_featured_link_placeholder: "عنوان کے ساتھ دکھایا گیا لنک درج کریں۔" + reply_placeholder: "یہاں ٹائپ کریں۔ فارمیٹ کیلئے مارکڈائون، BBCode، یا HTML اِستعمال کریں۔ تصاویر ڈریگ یا پیسٹ کریں۔" + view_new_post: "اپنے نئی پوسٹ دیکھئیے۔" + saving: "محفوظ کیا جا رہا ہے" + saved: "محفوظ کر لیا گیا!" + saved_draft: "پوسٹ کا ڈرافت پیش رفت ہے۔ دوبارہ شروع کرنے کے لئے منتخب کریں۔" + uploading: "اَپ لوڈ کیا جا رہا ہے..." + show_preview: 'پیش نظارہ دکھائیں »' + hide_preview: '« پیش نظارہ چھپائیں' + quote_post_title: "پوری پوسٹ کا اقتباس کریں" + bold_label: "B" + bold_text: "گہرا متن" + italic_label: "I" + italic_text: "زور دیا گیا متن" + link_title: "ہائپرلِنک" + link_description: "یہاں لِنک کی تفصیل درج کریں" + link_dialog_title: "ہائپرلِنک ڈالیں" + link_optional_text: "اختیاری عنوان" + link_url_placeholder: "http://example.com" + quote_title: "بلاک کوٹ" + quote_text: "بلاک کوٹ" + code_title: "پہلے سے فارمیٹ کیا گیا متن" + code_text: "حاشیہ نے متن کو پہلے سے 4 خالی جگہوں سے فارمیٹ کر دیا" + paste_code_text: "کوڈ یہاں ٹائپ یا پیسٹ کریں" + upload_title: "اَپ لوڈ" + upload_description: "یہاں اَپ لوڈ کی تفصیل درج کریں" + olist_title: "نمبروار فہرست" + ulist_title: "بلٹ والی لسٹ" + list_item: "فہرست آئٹم" + heading_label: "H" + heading_title: "سرخی" + heading_text: "سرخی" + hr_title: "افقی لکیر" + help: "مارکڈائون ترمیم میں مدد" + toggler: "کمپوزر پینل چھپائیں یا دکھائیں" + modal_ok: "ٹھیک" + modal_cancel: "منسوخ" + cant_send_pm: "معذرت، آپ ٪{صارف نام} کو پیغام نہیں بھیج سکتے۔" + yourself_confirm: + title: "کیا آپ وصول کنندگان کو شامل کرنا بھول گئے؟" + body: "اِس وقت یہ پیغام صرف اپنے آپ کو بھیجا جا رہا ہے!" + admin_options_title: "اس ٹاپک کیلئے عملے کی اختیاری ترتیبات" + auto_close: + label: "خود کار طریقے سے ٹاپک بند کرنے کا وقت:" + error: "براہ کرم، ایک قابلِ قبول قدر درج کریں" + based_on_last_post: "بند نہ کریں جب تک ٹاپک کی آخری پوسٹ کم از کم اتنی پرانی نہ ہو۔" + all: + examples: 'گھنٹوں کی تعداد درج کریں (24)، مطلق وقت (17:30) یا ٹائمسٹیمپ (2013-11-22 14:00)۔' + limited: + units: "(گھنٹوں کے #)" + examples: 'گھنٹوں کی تعداد درج کریں (24)۔' + notifications: + title: "@نام کے ذکر، آپ کی پوسٹ اور ٹاپک پر جوابات، پیغامات، وغیرہ کی اطلاعات" + none: "اِس وقت ویب سائٹ اطلاعات لوڈ کرنے سے قاصر ہے۔" + empty: "کوئی اطلاعات نہیں ملیں۔" + more: "پرانی اطلاعات دیکھیے" + total_flagged: "کل نشان زدہ پوسٹس" + mentioned: "

    {{صارف نام}} {{وضاحت}}

    " + group_mentioned: "

    {{صارف نام}} {{وضاحت}}

    " + quoted: "

    {{صارف نام}} {{وضاحت}}

    " + replied: "

    {{صارف نام}} {{وضاحت}}

    " + posted: "

    {{صارف نام}} {{وضاحت}}

    " + edited: "

    {{صارف نام}} {{وضاحت}}

    " + liked: "

    {{صارف نام}} {{وضاحت}}

    " + liked_2: "

    {{صارف نام}}، {{صارف نام2}} {{وضاحت}}

    " + liked_many: + one: "

    {{صارف نام}}، {{صارف نام2}} اور 1 دوسرا {{وضاحت}}

    " + other: "

    {{صارف نام}}، {{صارف نام2}} اور {{شمار}} دوسرے {{وضاحت}}

    " + private_message: "

    {{صارف نام}} {{وضاحت}}

    " + invited_to_private_message: "

    {{صارف نام}} {{وضاحت}}

    " + invited_to_topic: "

    {{صارف نام}} {{وضاحت}}

    " + invitee_accepted: "

    {{صارف نام}} نے آپ کی دعوت قبول کرلی

    " + moved_post: "

    {{صارف نام}} {{وضاحت}} منتقل کر دیا

    " + linked: "

    {{صارف نام}} {{وضاحت}}

    " + granted_badge: "

    '{{وضاحت}}' حاصل کیا

    " + watching_first_post: "

    نیا ٹاپک {{وضاحت}}

    " + group_message_summary: + one: "i title='messages in group inbox' class='fa fa-group'>

    آپ کے {{گروپ_نام}} اِن باکس میں {{شمار}} پیغام

    " + other: "i title='messages in group inbox' class='fa fa-group'>

    آپ کے {{گروپ_نام}} اِن باکس میں {{شمار}} پیغامات

    " + alt: + mentioned: "کی طرف سے ذکر کیا گیا" + quoted: "کی طرف سے اقتباس کیا گیا" + replied: "جواب دیا" + posted: "کی طرف سے پوسٹ" + edited: "اِس وقت تک اپنی پوسٹ میں ترمیم کر لیں" + liked: "آپ کی پوسٹ کو لائیک کیا" + private_message: "کی طرف سے ذاتی پیغام" + invited_to_private_message: "کی طرف سے ذاتی پیغام کیلئے دعوت دی گئی" + invited_to_topic: "کی طرف سے ٹاپک کیلئے دعوت دی گئی" + invitee_accepted: "کی طرف سے دعوت قبول کر لی گئی" + moved_post: "کی طرف سے آپ کی پوسٹ منتقل کر دی گئی تھی" + linked: "آپ کی پوسٹ سے لنک کیا" + granted_badge: "بَیج عطا کیا" + group_message_summary: "گروپ اِن باکس میں پیغامات" + popup: + mentioned: '{{صارف نام}} نے آپ کا تذکرہ "{{ٹاپک}}" میں کیا - {{site_title}}' + group_mentioned: '{{صارف نام}} نے آپ کا تذکرہ "{{ٹاپک}}" میں کیا - {{site_title}}' + quoted: '{{صارف نام}} نے "{{ٹاپک}}" میں آپ کا حوالا دیا - {{site_title}}' + replied: '{{صارف نام}} نے "{{ٹاپک}}" میں آپ کو جواب دیا - {{site_title}}' + posted: '{{صارف نام}} نے "{{ٹاپک}}" میں پوسٹ کیا - {{site_title}}' + private_message: '{{صارف نام}} نے "{{ٹاپک}}" میں آپ کو زاتی پیغام بھیجا - {{site_title}}' + linked: '{{صارف نام}} نے "{{ٹاپک}}" سے آپ کی پوسٹ کو لنک کیا - {{site_title}}' + upload_selector: + title: "ایک تصویر شامل کریں" + title_with_attachments: "ایک تصویر یا ایک فائل شامل کریں" + from_my_computer: "میری ڈیوائس سے" + from_the_web: "انٹرنیٹ سے" + remote_tip: "تصویر کا لنک" + remote_tip_with_attachments: "تصویر یا فائل کا لنک {{authorized_extensions}}" + local_tip: "اپنے ڈیوائس سے تصاویر منتخب کریں" + local_tip_with_attachments: "اپنے ڈیوائس سے تصاویر یا فائلیں منتخب کریں {{authorized_extensions}}" + hint: "(آپ اِن کو اَپ لوڈ کرنے کیلئیے ایڈیٹر میں ڈرَیگ & ڈراپ بھی کر سکتے ہیں)" + hint_for_supported_browsers: "آپ تصاویر کو ایڈیٹر میں ڈرَیگ & ڈراپ یا پَیسٹ بھی کر سکتے ہیں" + uploading: "اَپ لوڈ کیا جا رہا ہے" + select_file: "فائل منتخب کریں" + image_link: "لنک جس سے آپ کی تصویر منسلک ہو گی" + search: + sort_by: "ترتیب بہ" + relevance: "مطابقت" + latest_post: "تازہ ترین پوسٹ" + most_viewed: "سب سے زیادہ دیکھا گیا" + most_liked: "سب سے زیادہ لائک کیا گیا" + select_all: "تمام منتخب کریں" + clear_all: "تمام کو صاف کریں" + too_short: "آپ کا سَرچ ٹَرم بہت مختصر ہے۔" + result_count: + one: "\"{{term}}\" کیلئیے 1 نتیجہ" + other: "\"{{term}}\" کیلئیے {{شمار}} نتائج" + title: "ٹاپک، پوسٹس، صارفین، یا زمرہ جات کو سَرچ کریں" + no_results: "کوئی نتائج نہیں پائے گئے۔" + no_more_results: "کوئی اور نتائج نہیں پائے گئے۔" + searching: "تلاش کیا جا رہا ہے ..." + post_format: "{{صارف نام}} کی طرف سے #{{post_number}}" + context: + user: "@{{صارف نام}} کے حساب سے پوسٹس تلاش کریں" + category: "#{{زمرہ}} زمرہ میں تلاش کریں" + topic: "اِس ٹاپک میں تلاش کریں" + private_messages: "پیغامات میں تلاش کریں" + advanced: + title: اعلی درجے کی تلاشی + posted_by: + label: کی طرف سے پوسٹ کیا گیا + in_category: + label: زمرہ میں + in_group: + label: گروپ میں + with_badge: + label: بَیج کے ساتھ + with_tags: + label: ٹیگز کے ساتھ + filters: + label: صرف وہ ٹاپک/پوسٹس دکھائیں جو + likes: جو میں نے لائیک کیے + posted: جن میں میں نے پوسٹ کیا + watching: جو میں دیکھ رہا ہوں + tracking: جو میں ٹریک کر رہا ہوں + private: جو میرے پیغامات میں ہے + bookmarks: جو میں نے بُک مارک کیے ہیں + first: جو سب سے پہلی پوسٹ ہو + pinned: جو پِن ہوا ہو + unpinned: جو پِن نہ ہوا ہو + seen: جو میں نے پڑھ لیا ہو + unseen: جو میں نے نہ پڑھا ہو + wiki: جو وِیکی ہو + statuses: + label: جہاں ٹاپک + open: کھلے ہوں + closed: بند ہوں + archived: آر کائیو کیے ہوں + noreplies: کے صفر جوابات ہوں + single_user: صرف ایک صارف پر مشتمل ہوں + post: + count: + label: کم از کم پوسٹ شمار + time: + label: پوسٹ کیا + before: سے پہلے + after: کے بعد + hamburger_menu: "ایک اور ٹاپک فہرست یا زمرہ پر جائیں" + new_item: "نیا" + go_back: 'واپس جائیں' + not_logged_in_user: 'موجودہ سرگرمی کے خلاصہ اور ترجیحات کے ساتھ صفحہِ صارف' + current_user: 'اپنے صفحہِ صارف پر جائیں' + topics: + new_messages_marker: "آخری وزٹ" + bulk: + select_all: "تمام منتخب کریں" + clear_all: "تمام کو صاف کریں" + unlist_topics: "ٹاپکس کو فہرست سے ہٹائیں" + reset_read: "\"پڑھ لیا گیا\" کو رِیسیٹ کریں" + delete: "ٹاپکس حذف کریں" + dismiss: "بر خاست کریں" + dismiss_read: "تمام نہ پڑھے گئے کو بر خاست کریں" + dismiss_button: "بر خاست کریں..." + dismiss_tooltip: "صرف نئی پوسٹس برخاست کریں یا ٹاپکس کو ٹریک کرنے سے رک جائیں" + also_dismiss_topics: "ان ٹاپکس کو ٹریک کرنے سے رک جائیں تاکہ وہ کبھی دوبارہ میرے لیے \"نہ پڑھے گئے\"میں نظر نہ آئیں" + dismiss_new: "نیا برخاست کریں" + toggle: "ٹاپکس کے بَلک انتخاب کو ٹَوگل کریں" + actions: "بَلک عمل" + change_category: "زمرہ تبدیل کریں" + close_topics: "ٹاپکس بند کریں" + archive_topics: "ٹاپکس آر کائیو کریں" + notification_level: "اطلاعات کا لیول تبدیل کریں" + choose_new_category: "ٹاپکس کیلئے نئے زمرہ کا انتخاب کریں:" + selected: + one: "آپ نے 1 ٹاپک منتخب کیا ہے۔" + other: "آپ نے {{شمار}} ٹاپک منتخب کیے ہیں۔" + change_tags: "ٹیگز بدلیں" + append_tags: "ٹیگز میں اضافہ کریں" + choose_new_tags: "ان ٹاپکس کیلئے نئے ٹیگز کا انتخاب کریں:" + choose_append_tags: "ان ٹاپکس پر اضافہ کرنے کیلئے نئے ٹیگز کا انتخاب کریں:" + changed_tags: "ان ٹاپکس کے ٹیگز تبدیل کر دیے گئے تھے۔" + none: + unread: "آپ کے پاس کوئی بغیر پڑھے ٹاپک موجود نہیں۔" + new: "آپ کے پاس کوئی نئے ٹاپک موجود نہیں۔" + read: "ابھی تک آپ نے کوئی ٹاپکس نہیں پڑھے۔" + posted: "ابھی تک آپ نے کسی ٹاپک میں پوسٹ نہیں کیا۔" + latest: "کوئی تازہ ٹاپک موجود نہیں ہیں۔ یہ اداس کر دینے والی بات ہے۔" + hot: "کوئی مشہور ٹاپک موجود نہیں ہیں۔" + bookmarks: "ابھی تک آپ کے بُک مارک کیے ہوے ٹاپک نہیں ہیں۔" + category: "کوئی {{زمرے}} کے ٹاپک موجود نہیں ہیں۔" + top: "کوئی ٹاپ ٹاپک موجود نہیں ہیں۔" + search: "سرچ کے کوئی نتائج نہیں ہیں۔" + educate: + new: '

    آپ کے نئے ٹاپم یہاں ظاہر ہوتے ہیں۔

    ڈیفالٹ کے طور پر، ٹاپک نئے سمجھے جاتے ہیں اور اگر وہ پچھلے 2 دن میں بنائے گئے تھے تو نئے کی علامت دکھائی جائے گی۔

    اِس کو تبدیل کرنے کیلئے اپنی ترجیحات پر جائیں۔

    ' + unread: '

    آپ کے بغیر پڑھے ٹاپک یہاں ظاہر ہوتے ہیں۔

    ڈیفالٹ کے طور پر، ٹاپک بغیر پڑھے سمجھے جاتے ہیں اور بغیر پڑھے کا شمار 1 دکھائیں گے، اگر آپ نے:

    • ٹاپک بنایا ہوا ہو
    • ٹاپک پر جواب دیا ہو
    • ٹاپک کو 4 منٹ سے زیادہ پڑھا ہو

    یا آپ نے واضح طور پرٹاپک کے نچلے حصے میں موجود نوٹیفکیشن کنٹرول کے ذریعے ٹاپک کو ٹریک یا دیکھا ہوا مقرر کیا ہو۔<

    اِس کو تبدیل کرنے کیلئے اپنی ترجیحات پر جائیں۔

    ' + bottom: + latest: "کوئی مزید تازہ ترین ٹاپک موجود نہیں ہیں۔" + hot: "کوئی مزید مشہور ٹاپک موجود نہیں ہیں۔" + posted: "کوئی مزید پوسٹ کیے گئے ٹاپک موجود نہیں ہیں۔" + read: "کوئی مزید پڑھ لیے گئے ٹاپک موجود نہیں ہیں۔" + new: "کوئی مزید نئے ٹاپک موجود نہیں ہیں۔" + unread: "کوئی مزید بغیر پڑھے ٹاپک موجود نہیں ہیں۔" admin_js: admin: export_json: button_text: "برآمد" + user: + tl3_requirements: + flagged_posts: "نشان زدہ پوسٹ" + flagged_by_users: "نشان زدہ کرنے والے صارفین" + likes_given: "لائیکس دیے گئے" + likes_received: "لائیکس موصول ہوے" + likes_received_days: "لائیکس موصول ہوے: منفرد دنوں میں" + likes_received_users: "لائیکس موصول ہوے: منفرد صارفین سے" + qualifies: "ٹرسٹ سطح 3 کے لئے اِہل ہے۔" + does_not_qualify: "ٹرسٹ سطح 3 کے لئے اِہل نہیں ہے۔" + will_be_promoted: "جلد ہی ترقی دے دی جائے گا۔" + will_be_demoted: "جلد ہی تنزلی کر دی جائے گی۔" + on_grace_period: "فی الحال ترقی کے رعایتی مدت میں، تنزلی نہیں کی جائے گی۔" + locked_will_not_be_promoted: "ٹرسٹ کی سطح مقفل۔ کبھی بھی ترقی نہیں دی جائے گی۔" + locked_will_not_be_demoted: "ٹرسٹ کی سطح مقفل۔ کبھی بھی تنزلی نہیں کی جائے گی۔" + sso: + title: "انفرادی سائن آن" + external_id: "بیرونی آئی ڈی" + external_username: "صارف کا نام" + external_name: "نام" + external_email: "اِی میل" + external_avatar_url: "پروفائل کی تصویر کا یوآرایل" + user_fields: + title: "صارف کے لیے دیئے گئے خانے" + help: "خانے شامل کریں جو آپ کے صارفین پُر کر سکیں۔" + create: "صارفین سے پُر ہونے والے خانے بنائیں۔" + untitled: "بلاعنوان" + name: "فیلڈ کا نام" + type: "فیلڈ کی قسم" + description: "فیلڈ کی وضاحت" + save: "محفوظ کریں" + edit: "ترمیم کریں" + delete: "حذف کریں" + cancel: "منسوخ" + delete_confirm: "کیا آپ واقعی یہ صارف سے بھرے جانے والا خانا حذف کرنا چاہتے ہیں؟" + options: "اختیارات" + required: + title: "سائن اَپ کے وقت درکار ہے؟" + enabled: "درکار ہے" + disabled: "درکار نہیں ہے" + editable: + title: "سائن اَپ کے بعد قابل ترمیم؟" + enabled: "قابلِ ترمیم" + disabled: "ناقابلِ ترمیم" + show_on_profile: + title: "پبلک پروفائل پر دکھائیں؟" + enabled: "پروفائل پر دکھائیں؟" + disabled: "پروفائل پر نہیں دکھایا؟" + show_on_user_card: + title: "صارف کارڈ پر دکھائیں؟" + enabled: "صارف کارڈ پر دکھایا گیا" + disabled: "صارف کارڈ پر نہیں دکھایا گیا" badges: name: نام diff --git a/config/locales/client.zh_CN.yml b/config/locales/client.zh_CN.yml index 1067ae28cd..72b7d02723 100644 --- a/config/locales/client.zh_CN.yml +++ b/config/locales/client.zh_CN.yml @@ -919,7 +919,7 @@ zh_CN: title: "使用 Yahoo 帐号登录" message: "正在通过 Yahoo 帐号验证登录(请确保浏览器没有禁止弹出窗口)" github: - title: "使用 GitHub 帐号登录" + title: "用 GitHub 帐号登录" message: "正在通过 GitHub 帐号验证登录(请确保浏览器没有禁止弹出窗口)" invites: accept_title: "邀请" @@ -1828,7 +1828,6 @@ zh_CN: history: "历史" changed_by: "由 {{author}}" raw_email: - title: "原始邮件" not_available: "不可用!" categories_list: "分类列表" filters: diff --git a/config/locales/client.zh_TW.yml b/config/locales/client.zh_TW.yml index 8e532fe295..5af19db1da 100644 --- a/config/locales/client.zh_TW.yml +++ b/config/locales/client.zh_TW.yml @@ -805,9 +805,9 @@ zh_TW: enabled: "站點正處於只讀模式。你可以繼續瀏覽,但是回覆、讚和其他操作暫時被禁用。" login_disabled: "在唯讀模式下不能登入" logout_disabled: "站點在只讀模式下無法登出。" - too_few_topics_and_posts_notice: "讓我們開始討論!目前有 %{currentTopics} / %{requiredTopics} 個主題和 %{currentPosts} / %{requiredPosts} 個帖子。新訪客需要能夠閲讀和回覆一些討論。" - too_few_topics_notice: "讓我們開始討論!目前有 %{currentTopics} / %{requiredTopics} 個主題。新訪客需要能夠閲讀和回覆一些討論。" - too_few_posts_notice: "讓我們開始討論!目前有 %{currentPosts} / %{requiredPosts} 個帖子。新訪客需要能夠閲讀和回覆一些討論。" + too_few_topics_and_posts_notice: "讓我們開始討論!目前有 %{currentTopics} / %{requiredTopics} 個主題和 %{currentPosts} / %{requiredPosts} 個帖子。新訪客需要一些討論串來閲讀和回覆。" + too_few_topics_notice: "讓我們開始討論!目前有 %{currentPosts} / %{requiredPosts} 個主題。新訪客需要一些討論串來閲讀和回覆。" + too_few_posts_notice: "讓我們開始討論!目前有 %{currentPosts} / %{requiredPosts} 個帖子。新訪客需要一些討論串來閲讀和回覆。" logs_error_rate_notice: reached: "%{relativeAge}%{rate} 達到了站點設置中的 %{siteSettingRate}。" exceeded: "[%{relativeAge}] 目前的錯誤率 %{rate} 已超出了站點設置中的 %{siteSettingRate}。" @@ -925,6 +925,7 @@ zh_TW: accept_title: "邀請函" welcome_to: "歡迎來到 %{site_name}!" invited_by: "您被邀請,來自:" + social_login_available: "你也可以透過其他相同 email 的社交帳號登入。" your_email: "您帳號的電郵地址是 %{email}" accept_invite: "接受邀請" success: "你的帳號已被建立,且您已經登入了。" @@ -1486,6 +1487,7 @@ zh_TW: wiki_last_edited_on: "共筆最後編輯時間" last_edited_on: "文章最近編輯的時間" reply_as_new_topic: "回覆為關連的討論話題" + reply_as_new_private_message: "回覆作為新訊息給同一收件人" continue_discussion: "繼續 {{postLink}} 的討論:" follow_quote: "跳到引用的文章" show_full: "顯示所有文章" diff --git a/config/locales/server.ar.yml b/config/locales/server.ar.yml index 85e1056063..e555565d68 100644 --- a/config/locales/server.ar.yml +++ b/config/locales/server.ar.yml @@ -72,7 +72,7 @@ ar: inclusion: غير متضمن في القائمة invalid: غير صالح is_invalid: "تبدو غير واضحة، هل هذه الجملة كاملة؟" - contains_censored_words: "الرسالة تحتوي على كلمات غير مسموح بها" + contains_censored_words: "تحتوي الكلمات الآتية الخاضعة للرّقابة: %{censored_words}" less_than: يجب أن يكون أقل من %{count} less_than_or_equal_to: يجب أن تكون أقل من أو تساوي %{count} not_a_number: ليس عدد @@ -152,7 +152,7 @@ ar: few: "%{count} ردود أخرى" many: "%{count} ردا آخر" other: "%{count} رد آخر" - loading: "يحمّل النقاش..." + loading: "يحمّل النّقاش..." permalink: "الرابط الثابت" imported_from: "هذا موضوع نقاش مصاحب للمدخل الأصلي على %{link}" in_reply_to: "◀ %{username}" @@ -163,15 +163,15 @@ ar: few: "%{count} ردود" many: "%{count} ردا" other: "%{count} رد" - no_mentions_allowed: "عذراً، لا يمكنك تنبيه أعضاء آخرين." + no_mentions_allowed: "نأسف، لا يمكنك الإشارة إلى الغير." too_many_mentions: - zero: "عذرا, لا يمكنك تنبيه أي عضو آخر في مشاركة." - one: "عذراً، يمكنك تنبيه عضو آخر واحد فقط في مشاركة." - two: "عذراً، يمكنك تنبيه عضوان آخران فقط في مشاركة." - few: "عذرا, يمكنك تنبيه %{count} أعضاء آخرين فقط في مشاركة." - many: "عذرا, يمكنك تنبيه %{count} عضواً آخراً فقط في مشاركة." - other: "عذرا, يمكنك تنبيه %{count} عضو فقط في مشاركة." - no_mentions_allowed_newuser: "عذرا, الأعضاء الجدد لا يمكنهم تنبيه الأعضاء الآخرين." + zero: "نأسف، لا يمكنك الإشارة إلى أحد في كلّ مشاركة." + one: "نأسف، يمكنك الإشارة إلى مستخدم واحد فقط في كلّ مشاركة." + two: "نأسف، يمكنك الإشارة إلى مستخدمين فقط في كلّ مشاركة." + few: "نأسف، يمكنك الإشارة إلى %{count} مستخدمين فقط في كلّ مشاركة." + many: "نأسف، يمكنك الإشارة إلى %{count} مستخدمًا فقط في كلّ مشاركة." + other: "نأسف، يمكنك الإشارة إلى %{count} مستخدم فقط في كلّ مشاركة." + no_mentions_allowed_newuser: "نأسف، لا يمكن للمستخدمين الجدد الإشارة إلى الغير." too_many_mentions_newuser: zero: "عذرا ، المستخدمون الجدد بامكانهم فقط تنبيه %{count} عضو في المشاركة ." one: "عذرا ، المستخدمون الجدد بامكانهم فقط تنبيه عضو واحد فقط في المشاركة ." @@ -179,7 +179,7 @@ ar: few: "عذرا ، المستخدمون الجدد بامكانهم فقط تنبيه %{count} أعضاء في المشاركة ." many: "عذرا ، المستخدمون الجدد بامكانهم فقط تنبيه %{count} عضو في المشاركة ." other: "عذرا ، المستخدمون الجدد بامكانهم فقط تنبيه %{count} عضو في المشاركة ." - no_images_allowed: "آسفون، لا يمكن للمستخدمين الجدد وضع صور في المنشورات." + no_images_allowed: "نأسف، لا يمكن للمستخدمين الجدد وضع صور في المشاركات." too_many_images: zero: "يمكن للمستخدمين الجدد وضع أيّ عدد من الصور في أي منشور." one: "آسفون، يمكن للمستخدمين الجدد وضع صورة واحدة فقط في كل منشور." @@ -187,7 +187,7 @@ ar: few: "آسفون، يمكن للمستخدمين الجدد وضع %{count} صور فقط في كل منشور." many: "آسفون، يمكن للمستخدمين الجدد وضع %{count} صورة فقط في كل منشور." other: "آسفون، يمكن للمستخدمين الجدد وضع %{count} صورة فقط في كل منشور." - no_attachments_allowed: "آسفون، لا يمكن للمستخدمين الجدد إرفاق ملفات إلى المنشورات." + no_attachments_allowed: "نأسف، لا يمكن للمستخدمين الجدد إرفاق ملفّات إلى المشاركات." too_many_attachments: zero: "يمكن للمستخدمين الجدد إرفاق أيّ عدد من الملفات إلى أي منشور." one: "آسفون، يمكن للمستخدمين الجدد إرفاق ملف واحد فقط إلى كل منشور." @@ -195,7 +195,7 @@ ar: few: "آسفون، يمكن للمستخدمين الجدد إرفاق %{count} ملفات فقط إلى كل منشور." many: "آسفون، يمكن للمستخدمين الجدد إرفاق %{count} ملفا فقط إلى كل منشور." other: "آسفون، يمكن للمستخدمين الجدد إرفاق %{count} ملف فقط إلى كل منشور." - no_links_allowed: "آسفون، لا يمكن للمستخدمين الجدد وضع روابط في المنشورات." + no_links_allowed: "نأسف، لا يمكن للمستخدمين الجدد وضع روابط في المشاركات." too_many_links: zero: "يمكن للمستخدمين الجدد وضع أيّ عدد من الروابط في أي منشور." one: "آسفون، يمكن للمستخدمين الجدد وضع رابطا واحدا فقط في كل منشور." @@ -203,9 +203,10 @@ ar: few: "آسفون، يمكن للمستخدمين الجدد وضع %{count} روابط فقط في كل منشور." many: "آسفون، يمكن للمستخدمين الجدد وضع %{count} رابطا فقط في كل منشور." other: "آسفون، يمكن للمستخدمين الجدد وضع %{count} رابط فقط في كل منشور." - spamming_host: "عذرا لا يمكنك مشاركة رابط لهذا المضيف." + spamming_host: "نأسف، لا يمكنك وضع رابط لهذا المضيف." user_is_suspended: "ليس مسموحا للمستخدمين المعلّقة عضويتهم النشر." topic_not_found: "حدث خطب ما. قد يكون الموضوع أُغلق أو حُذف وأنت تشاهده؟" + not_accepting_pms: "نأسف، لا يقبل %{username} الرّسائل حاليًّا." just_posted_that: "هذا مماثل لما شاركته مؤخرا" invalid_characters: "يحتوي احرف غير صالحة " is_invalid: "تبدو غير واضحة، هل هذه عبارة كاملة؟" @@ -232,7 +233,7 @@ ar: user_posts: "احدث المشاركات من %{group_name} " user_topics: " آخر المواضيع بواسطة @%{username}" tag: "مواضيع معلمة " - too_late_to_edit: "تم انشاء هذا التعليق منذ فترة وليس بالامكان تعديله او حذفه" + too_late_to_edit: "أُنشئت المشاركة هذه منذ فترة طويلة جدًّا، لذا تعديلها أو حذفها لم يعد ممكنًا." revert_version_same: "ألاصدار الحالي يتطابق مع نفس ألاصدار الذي تحاول استرجاعه ." excerpt_image: "صورة" queue: @@ -300,7 +301,7 @@ ar: base: warning_requires_pm: "يمكنك إرفاق التحذيرات إلى الرسائل الخاصة فقط." too_many_users: "يمكنك إرسال التحذيرات إلى مستخدم واحد كل مرة." - cant_send_pm: "آسفون، لا يمكنك إرسال رسالة خاصة إلى هذا المستخدم." + cant_send_pm: "نأسف، لا يمكنك إرسال رسالة خاصّة إلى هذا المستخدم." no_user_selected: "عليك تحديد مستخدم صالح." user: attributes: @@ -589,7 +590,7 @@ ar: many: "قبل حوالي %{count} سنة" other: "قبل حوالي %{count} سنة" password_reset: - no_token: "آسفون، رابط تغيير كلمة المرور قديم جدا. انقر زر \"تسجيل الدخول\" واختر \"نسيت كلمة مروري\" لنرسل لك رابطا آخر." + no_token: "نأسف، رابط تغيير كلمة السّرّ قديم جدًّا. انقر زرّ \"لِج\" واختر \"نسيت كلمة السّرّ\" لنرسل لك رابطًا آخر." update: 'حدّث كلمة المرور' save: 'تعين كلمة المرور' title: 'إعادة تعين كلمة المرور' @@ -1048,7 +1049,7 @@ ar: max_invites_per_day: "أقصى عدد للدعوات التي يمكن للعضو إرسالها باليوم." max_topic_invitations_per_day: "أقصى عدد لدعوات الموضوع التي يمكن للعضو إرسالها باليوم." alert_admins_if_errors_per_minute: "عدد الأخطاء في الدقيقة الواحدة لكى يرسل تنبيه للمدير. قيمة 0 تعطل هذه الميزة. ملاحظة: تتطلب إعادة تشغيل." - categories_topics: "عدد المواضيع المعروضة في الأقسام" + categories_topics: "عدد المواضيع لتظهر في صفحة ‎/categories." suggested_topics: "عدد المواضيع المواضيع المقترحة يظهر في أسفل الموضوع." limit_suggested_to_category: "أظهر فقط المواضيع من الفئات الحالية في المواضيع المقترحة." clean_up_uploads: " يتيم أزالة تحديث غير مرجعية لمنع استضافة غير المشروعة. تحذير: قد تحتاج لعمل نسخة احتياطية من الدليل / تحميل قبل تمكين هذا الإعداد." @@ -1487,7 +1488,7 @@ ar: subject_template: "اكتمل تصدير البيانات" csv_export_failed: subject_template: "فشل تصدير البيانات" - text_body_template: "نحن آسفون، لكنه فشل تصدير البيانات الخاصة بك. يرجى التحقق من السجلات أو اتصل بأحد المشرفين." + text_body_template: "نأسف، فشل تصدير البيانات. رجاء افحص السّجلّات أو راسل أحد أعضاء الطّاقم." email_reject_no_account: subject_template: "[%{site_name}] بريد الكتروني -- حساب غير معروف" email_reject_empty: @@ -1538,14 +1539,13 @@ ar: subject_template: "الغاء تفعيل تحميل الصور عن بعد " text_body_template: "تم تعطيل الإعداد 'download_remote_images_to_local' لأنه تم الوصول إلى حد مساحة القرص في 'download_remote_images_threshold'." subject_re: "اعادة " - subject_pm: "[مسائًا]" user_notifications: previous_discussion: "الردود السابقة " in_reply_to: "في رد لـ " unsubscribe: title: "غير مشترك " description: "لست مهتما في تلقي هذه الرسائل الالكترونيه؟ لا مشكله! اضغط تحت ليتم الغاء اشتركك فورا:" - visit_link_to_respond_pm: "[Visit Message](%{base_url}%{url}) للرد." + visit_link_to_respond_pm: "[زُر الرّسالة](%{base_url}%{url}) للرّدّ." posted_by: "مشاركة بواسطة %{username} على %{post_date}" user_invited_to_private_message_pm: subject_template: "[%{site_name}] %{username} دعاك لرسالة '%{topic_title}'" @@ -1655,9 +1655,9 @@ ar: store_failure: "فشل حفظ التحميل #%{upload_id} للعضو #%{user_id}." file_missing: "عذرا، يجب عليك توفير ملف للرفع." attachments: - too_large: "نعتذر، الملف الذي تريد رفعه كبير جداً ( الحد الاقصى {max_size_kb} كيلوبايت )" + too_large: "نأسف، الملفّ الذي تحاول رفعه كبير جدًّا (أقصى حجم هو %{max_size_kb} ك.بايت)." images: - too_large: "نعتذر، الصورة الذي تريد رفعها كبيرة جداً ( الحد الاقصى هو %{max_size_kb} كيلوبايت )،يرجى اعادة تغيير حجمها ثم حاول مرة اخرى." + too_large: "نأسف، الصّورة التي تحاول رفعها كبير جدًّا (أقصى حجم هو %{max_size_kb} ك.بايت)، رجاء غيّر حجمها وحاول مرّة أخرى." size_not_found: "نعتذر، لكننا لا يمكن تحديد حجم الصورة. ربما صورتك تالفة؟" email_log: no_user: "لا يمكنك إيجاد عضو بواسطة id %{user_id}" @@ -1881,6 +1881,8 @@ ar: performance_report: initial_post_raw: 'هذا الموضوع يحتوي على معلومات الاداء اليومي للموقع ' initial_topic_title: التبليغ عن اداء الموقع + finish_installation: + congratulations: "تهانينا على تثبيت دسكورس!" wizard: step: homepage: @@ -1892,6 +1894,8 @@ ar: label: "أحدث المواضيع" categories: label: "الأقسام" + finished: + title: "نسخة دسكورس جاهزة!" activemodel: errors: <<: *errors diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml index 1fba838171..1fca70e068 100644 --- a/config/locales/server.de.yml +++ b/config/locales/server.de.yml @@ -190,6 +190,12 @@ de: latest: "Aktuelle Themen" hot: "Beliebte Themen" top: "Die besten Themen" + top_all: "Top-Themen aller Zeiten" + top_yearly: "Top-Themen der letzten 12 Monate" + top_quarterly: "Top-Themen der letzten drei Monate" + top_monthly: "Top-Themen der letzten 30 Tage" + top_weekly: "Top-Themen der letzten Woche" + top_daily: "Top-Themen der letzten 24 Stunden" posts: "Letzte Beiträge" private_posts: "Neueste private Nachricht" group_posts: "Letzte Beiträge von %(Gruppen_name)" @@ -426,7 +432,7 @@ de: pms_per_day: "Du hast die maximale Anzahl an Nachrichten für heute erreicht. Bitte warte %{time_left}, bis Du es wieder versuchst." create_like: "Du hast die maximale Anzahl an Likes für heute erreicht. Bitte warte %{time_left}, bevor du es wieder versuchst." create_bookmark: "Du hast die maximale Anzahl an Lesezeichen für heute erreicht. Bitte warte %{time_left}, bis Du es wieder versuchst." - edit_post: "Du hast die maximale Anzahl an Änderungen für heute erreicht. Bitte warte %{time_left}, bis Du es wieder versuchst." + edit_post: "Du hast für heute die maximale Anzahl an Bearbeitungen erreicht. Bitte warte %{time_left}, bevor du es erneut versuchst." live_post_counts: "Du forderst die Live-Anzahl der Antworten zu schnell neu an. Bitte warte %{time_left}, bis du es wieder versuchst." unsubscribe_via_email: "Du hast die maximale Anzahl an Abbestell-E-Mails für heute erreicht. Bitte warte %{time_left}, vor einem neuen Versuch." topic_invitations_per_day: "Du hast die maximale Zahl an neuen Thema-Einladungen für heute erreicht. Bitte warte %{time_left}, bis Du es wieder versuchst." @@ -536,6 +542,7 @@ de: welcome_to: "Willkommen bei %{site_name}!" approval_required: "Bevor du auf das Forum zugreifen kannst, muss dein neues Konto noch von einem Moderator genehmigt werden. Du erhältst eine E-Mail, sobald dies geschehen ist!" missing_session: "We können nicht feststellen, ob dein Konto erstellt wurde, bitte stelle sichere, dass du Cookies aktiviert hast." + activated: "Bitte entschuldige, dieses Konto wurde bereits aktiviert." post_action_types: off_topic: title: 'Am Thema vorbei' @@ -789,6 +796,8 @@ de: facebook_config_warning: 'Der Server erlaubt die Anmeldung mit Facebook (enable_facebook_logins), aber die App ID und der Geheimcode sind nicht gesetzt. Besuche die Einstellungen um die fehlenden Einträge hinzuzufügen. Besuche den Leitfaden um mehr zu erfahren.' twitter_config_warning: 'Der Server erlaubt die Anmeldung mit Twitter (enable_twitter_logins), aber der Schlüssel und der Geheimcode sind nicht gesetzt. Besuche die Einstellungen um die fehlenden Einträge hinzuzufügen. Besuche den Leitfaden um mehr zu erfahren.' github_config_warning: 'Der Server erlaubt die Anmeldung mit Facebook GitHub (enable_github_logins), aber die Kunden-ID und der Geheimcode sind nicht gesetzt. Besuche die Einstellungen um die fehlenden Einträge hinzuzufügen. Besuche den Leitfaden um mehr zu erfahren.' + s3_config_warning: 'Der Server ist so eingestellt, dass Dateien auf S3 hochgeladen werden, aber mindestens eine der folgenden Einstellungen ist nicht gesetzt: s3_access_key_id, s3_secret_access_key, s3_use_iam_profile, or s3_upload_bucket. Gehe zu den Seiten-Einstellungen und aktualisiere die Einstellungen. Siehe „How to set up image uploads to S3?“ um mehr zu erfahren.' + s3_backup_config_warning: 'Der Server ist so eingestellt, dass Backups auf S3 hochgeladen werden, aber mindestens eine der folgenden Einstellungen ist nicht gesetzt: s3_access_key_id, s3_secret_access_key, s3_use_iam_profile, or s3_backup_bucket. Gehe zu den Seiten-Einstellungen und aktulisiere die Einstellungen. Siehe „How to set up image uploads to S3?“ um mehr zu erfahren.' image_magick_warning: 'Der Server wurde konfiguriert um Vorschaubilder von grossen Bildern zu erstellen, aber ImageMagick ist nicht installiertd. Installiere ImageMagick mit deinem bevorzugten Packetmanager oder besuche um das aktuelle Paket herunterzuladen.' failing_emails_warning: "%{num_failed_jobs} E-Mails konnten nicht versendet werden. Überprüfe deine app.yml und stelle sicher, dass die E-Mail Servereinstellungen korrekt gesetzt sind. \nSieh dir hier die nicht versendeten E-Mails an." subfolder_ends_in_slash: "Deine Installation in einem Pfad ist nicht korrekt, DISCOURSE_RELATIVE_URL_ROOT endet mit einem Schrägstrich." @@ -860,6 +869,7 @@ de: email_custom_headers: "Eine durch senkrechte Striche getrennte Liste von eigenen E-Mail Headerzeilen" email_subject: "Format der Betreffzeile in Standard-E-Mails. Siehe https://meta.discourse.org/t/customize-subject-format-for-standard-emails/20801" force_https: "Erzwinge HTTPS für deine Site. ACHTUNG: Aktiviere dies nicht, bevor HTTPS nicht vollständig eingerichtet ist und auf jeden Fall überall funktioniert! Hast du alle CDN-Netzwerke, alle Logins über Soziale Netzwerke, alle externe Logos / Abhängigkeiten geprüft, um sicherzustellen, dass sie auch alle HTTPS-kompatibel sind?" + same_site_cookies: "Verwende Same-Site-Cookies, die alle Angriffsszenarien für Cross-Site-Request-Forgery in unterstützten Browsern (lax oder strict). Warnung: Strict wird nur auf Seiten funktionieren, die Login erzwingen und SSO verwenden." summary_score_threshold: "Mindestpunktzahl, die ein Beitrag benötigt, um in der \"Thema zusammenfassen\"-Ansicht zu erscheinen." summary_posts_required: "Mindestanzahl an Beiträgen in einem Thema, bevor die \"Thema zusammenfassen\"-Funktion aktiviert wird." summary_likes_required: "Mindestanzahl an Likes in einem Thema, bevor die \"Thema zusammenfassen\" Funktion aktiviert wird." @@ -936,7 +946,7 @@ de: login_required: "Nur angemeldete Benutzer dürfen Inhalte der Site lesen, anonyme Zugriffe sind verboten." min_username_length: "Minimale Zeichenlänge für Benutzernamen. WARNUNG: Wenn bestehende Benutzer oder Gruppen kürzere Namen haben, wird deine Seite nicht mehr funktionieren!" max_username_length: "Maximale Zeichenlänge für Benutzernamen. WARNUNG: Wenn bestehende Benutzer oder Gruppen längere Namen haben, wird deine Seite nicht mehr funktionieren!" - reserved_usernames: "Benutzernamen, welche für die Registrierung gesperrt werden sollen." + reserved_usernames: "Benutzernamen, die nicht registriert werden dürfen. Das Wildcard-Symbol * kann verwendet werden, um ein beliebige Zeichenfolge zu erlauben." min_password_length: "Minimale Länge des Passworts." min_admin_password_length: "Minimale Passwortlänge für Administratoren." password_unique_characters: "Minimale Anzahl unterschiedlicher Zeichen, die ein Passwort enthalten muss." @@ -1002,6 +1012,8 @@ de: max_private_messages_per_day: "Maximale Zahl Direktnachrichten, die ein Benutzer pro Tag erstellen kann." max_invites_per_day: "Maximale Zahl an Einladungen, die ein Benutzer pro Tag verschicken kann." max_topic_invitations_per_day: "Maximale Zahl an Thema-Einladungen, die ein Benutzer pro Tag verschicken kann." + max_logins_per_ip_per_hour: "Maximale Anzahl der erlaubten Anmeldungen pro IP-Adresse und Stunde" + max_logins_per_ip_per_minute: "Maximale Anzahl der erlaubten Anmeldungen pro IP-Adresse und Stunde" alert_admins_if_errors_per_minute: "Anzahl der Fehler pro Minute, bei der ein Administrator benachrichtigt werden soll. Ein Wert von 0 deaktiviert diese Funktion. Achtung: Benötigt einen Neustart." alert_admins_if_errors_per_hour: "Anzahl der Fehler pro Stunde, bei der ein Administrator benachrichtigt werden soll. Ein Wert von 0 deaktiviert diese Funktion. Achtung: Benötigt einen Neustart." categories_topics: "Anzahl der Themen auf der /categories Seite" @@ -1207,6 +1219,7 @@ de: read_time_word_count: "Wörter pro Minute für die Berechnung der geschätzten Lesezeit." topic_page_title_includes_category: "Name des Themas enthält den Namen der Kategorie." native_app_install_banner: "Wiederkehrende Benutzer dazu einladen, die native Discourse-App herunterzuladen." + share_anonymized_statistics: "Anonymisierte Nutzungsdaten teilen." max_prints_per_hour_per_user: "Maximale Anzahl von Aufrufen der Druckansicht pro Nutzer pro Stunde (0 zum deaktivieren)" full_name_required: "Der voller Name wird für das Benutzerprofil benötigt." enable_names: "Zeigt den vollen Namen eines Benutzers auf dem Profil, der Benutzerkarte und in E-Mails an. Wenn deaktiviert wird der volle Name überall ausgeblendet." @@ -1420,6 +1433,8 @@ de: deactivated: "Deaktiviert wegen zu vielen unzustellbaren E-Mails an '%{email}'." deactivated_by_staff: "Deaktiviert vom Team" activated_by_staff: "Aktiviert vom Team" + new_user_typed_too_fast: "Neuer Benutzer hat zu schnell getippt" + content_matches_auto_block_regex: "Inhalt stimmt mit regulärem Auto-Block-Ausdruck überein" username: short: "muss mindestens %{min} Zeichen lang sein" long: "darf nicht länger als %{max} Zeichen sein" @@ -1479,6 +1494,11 @@ de: %{base_url}/users/password-reset/%{email_token} (Wenn der Link abgelaufen ist, wähle "Passwort vergessen" aus, wenn du dich mit deiner E-Mail-Adresse einloggen möchtest.) + download_backup_mailer: + title: "Backup-Download Mailer" + subject_template: "Backup-Download für [%{site_name}]" + no_token: | + Entschuldige, der Backup-Download-Link wurde schon verwendet oder ist abgelaufen. test_mailer: title: "Test-E-Mail" subject_template: "[%{site_name}] Test der E-Mail-Zustellbarkeit" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 7a1b55ed1b..dd8df3b108 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -229,6 +229,12 @@ en: latest: "Latest topics" hot: "Hot topics" top: "Top topics" + top_all: "All time top topics" + top_yearly: "Yearly top topics" + top_quarterly: "Quarterly top topics" + top_monthly: "Monthly top topics" + top_weekly: "Weekly top topics" + top_daily: "Daily top topics" posts: "Latest posts" private_posts: "Latest private messages" group_posts: "Latest posts from %{group_name}" @@ -385,6 +391,10 @@ en: attributes: payload_url: invalid: "URL is invalid. URL should includes http:// or https://. And no blank is allowed." + custom_emoji: + attributes: + name: + taken: is already in use by another emoji user_profile: no_info_me: "
    the About Me field of your profile is currently blank, would you like to fill it out?
    " @@ -1396,6 +1406,8 @@ en: native_app_install_banner: "Asks recurring visitors to install Discourse native app." + share_anonymized_statistics: "Share anonymized usage statistics." + max_prints_per_hour_per_user: "Maximum number of /print page impressions (set to 0 to disable)" full_name_required: "Full name is a required field of a user's profile." @@ -1566,11 +1578,6 @@ en: post_revision_text: "Ownership transferred from %{old_user} to %{new_user}" deleted_user: "a deleted user" - emoji: - errors: - name_already_exists: "Sorry, the name '%{name}' is already used by another emoji." - error_while_storing_emoji: "Sorry, there has been an error while storing the emoji." - topic_statuses: archived_enabled: "This topic is now archived. It is frozen and cannot be changed in any way." archived_disabled: "This topic is now unarchived. It is no longer frozen, and can be changed." @@ -1639,6 +1646,8 @@ en: deactivated: "Was deactivated due to too many bounced emails to '%{email}'." deactivated_by_staff: "Deactivated by staff" activated_by_staff: "Activated by staff" + new_user_typed_too_fast: "New user typed too fast" + content_matches_auto_block_regex: "Content matches auto block regex" username: short: "must be at least %{min} characters" long: "must be no more than %{max} characters" @@ -2721,7 +2730,7 @@ en: Please treat this discussion forum with the same respect you would a public park. We, too, are a shared community resource — a place to share skills, knowledge and interests through ongoing conversation. - These are not hard and fast rules, merely aids to the human judgment of our community. Use these guidelines to keep this a clean, well-lighted place for civilized public discourse. + These are not hard and fast rules, merely guidelines to aid the human judgment of our community and keep this a clean and well-lighted place for civilized public discourse. @@ -2731,18 +2740,18 @@ en: The topics discussed here matter to us, and we want you to act as if they matter to you, too. Be respectful of the topics and the people discussing them, even if you disagree with some of what is being said. - One way to improve the discussion is by discovering ones that are already happening. Please spend some time browsing the topics here before replying or starting your own, and you’ll have a better chance of meeting others who share your interests. + One way to improve the discussion is by discovering ones that are already happening. Spend time browsing the topics here before replying or starting your own, and you’ll have a better chance of meeting others who share your interests. ## [Be Agreeable, Even When You Disagree](#agreeable) - You may wish to respond to something by disagreeing with it. That’s fine. But, remember to _criticize ideas, not people_. Please avoid: + You may wish to respond to something by disagreeing with it. That’s fine. But remember to _criticize ideas, not people_. Please avoid: - * Name-calling. - * Ad hominem attacks. - * Responding to a post’s tone instead of its actual content. - * Knee-jerk contradiction. + * Name-calling + * Ad hominem attacks + * Responding to a post’s tone instead of its actual content + * Knee-jerk contradiction Instead, provide reasoned counter-arguments that improve the conversation. @@ -2750,11 +2759,11 @@ en: ## [Your Participation Counts](#participate) - The conversations we have here set the tone for everyone. Help us influence the future of this community by choosing to engage in discussions that make this forum an interesting place to be — and avoiding those that do not. + The conversations we have here set the tone for every new arrival. Help us influence the future of this community by choosing to engage in discussions that make this forum an interesting place to be — and avoiding those that do not. - Discourse provides tools that enable the community to collectively identify the best (and worst) contributions: favorites, bookmarks, likes, flags, replies, edits, and so forth. Use these tools to improve your own experience, and everyone else’s, too. + Discourse provides tools that enable the community to collectively identify the best (and worst) contributions: bookmarks, likes, flags, replies, edits, and so forth. Use these tools to improve your own experience, and everyone else’s, too. - Let’s try to leave our park better than we found it. + Let’s leave our community better than we found it. @@ -2764,7 +2773,7 @@ en: When you see bad behavior, don’t reply. It encourages the bad behavior by acknowledging it, consumes your energy, and wastes everyone’s time. _Just flag it_. If enough flags accrue, action will be taken, either automatically or by moderator intervention. - In order to maintain our community, moderators reserve the right to remove any content and any user account for any reason at any time. Moderators do not preview new posts in any way; the moderators and site operators take no responsibility for any content posted by the community. + In order to maintain our community, moderators reserve the right to remove any content and any user account for any reason at any time. Moderators do not preview new posts; the moderators and site operators take no responsibility for any content posted by the community. diff --git a/config/locales/server.et.yml b/config/locales/server.et.yml index 6324bacc68..79cc6f9790 100644 --- a/config/locales/server.et.yml +++ b/config/locales/server.et.yml @@ -32,8 +32,10 @@ et: purge_reason: "Kustutatud automaatselt kui mahajäetud, deaktiveeritud konto" disable_remote_images_download_reason: "Väliste piltide allalaadimine keelati, kuna polnud polnud piisavalt vaba ruumi." anonymous: "Anonüümne" + remove_posts_deleted_by_author: "Autori poolt kustutatud" emails: incoming: + default_subject: "See teema vajab pealkirja" show_trimmed_content: "Näita lühendatud sisu" maximum_staged_user_per_email_reached: "Meili teel loodud ettevalmistamisel olevate kasutajate maksimaalne arv on täis." errors: @@ -71,6 +73,7 @@ et: inclusion: puudub nimekirjas invalid: pole korrektne is_invalid: "tundub segane. kas see on terve lause?" + contains_censored_words: "sisaldab järgmisi tsenseeritud sõnu: %{censored_words}" less_than: peab olema väiksem kui %{count} less_than_or_equal_to: peab olema väiksem või võrdne kui %{count} not_a_number: ei ole number @@ -266,6 +269,7 @@ et: same_as_username: "on sama mis su kasutajanimi. Palun kasuta turvalisemat parooli." same_as_email: "on sama mis su meiliaadress. Palun kasuta turvalisemat parooli." same_as_current: "ühtib sinu hetkel kehtiva parooliga." + unique_characters: "sisaldab liiga palju korduvaid tähemärke. Palun kasuta turvalisemat parooli." ip_address: signup_not_allowed: "Sellelt kontolt pole liitumine lubatud." color_scheme_color: @@ -461,6 +465,8 @@ et: other: "peaaegu %{count} aastat tagasi" password_reset: no_token: "Vabandust, see parooli uuendamise link on liiga vana. Vajuta sisselogimise nuppu ja kasuta värske lingi saamiseks 'Unustasin parooli'." + choose_new: "Vali uus parool" + choose: "Vali parool" update: 'Uuenda parooli' save: 'Määra Parool' title: 'Uuenda Parool' @@ -556,18 +562,23 @@ et: mailing_list_mode: "Lülita postiloendi režiim välja" log_out: "Logi välja" user_api_key: + title: "Autoriseeri rakenduse ligipääs" + authorize: "Autoriseeri" read: "lugemine" read_write: "lugemine ja kirjutamine" reports: visits: + title: "Kasutajakülastused" xaxis: "Päev" yaxis: "Külastajate arv" signups: title: "Uued kasutajad" xaxis: "Päev" + yaxis: "Uute kasutajate arv" profile_views: title: "Kasutaja profiili vaatamisi" xaxis: "Päev" + yaxis: "Kasutajaprofiilide vaatamiste arv" topics: title: "Teemad" xaxis: "Päev" @@ -583,6 +594,7 @@ et: flags: title: "Tähised" xaxis: "Päev" + yaxis: "Lippude arv" bookmarks: title: "Järjehoidjad" xaxis: "Päev" @@ -707,6 +719,8 @@ et: min_trust_level_to_tag_topics: "Teemade sildistamiseks on nõutav minimaalne usaldustase" suppress_overlapping_tags_in_list: "Ära näita silti, kui see ühtib täpselt sõnaga teema päses" remove_muted_tags_from_latest: "Ära näita värskete teemade nimistus teemasid, millel on vaigistatud silt." + errors: + invalid_integer: "Väärtuseks peab olema täisarv." search: types: category: 'Liigid' @@ -718,6 +732,8 @@ et: login: admin_not_allowed_from_ip_address: "Sellelt IP-aadressilt ei saa adminnina sisse logida." already_logged_in: "Oih, näib, et üritad vastu võtta võõra kasutaja kutset. Kui Sa ei ole kasutaja %{current_user}, logi palun välja ja proovi uuesti." + flags_dispositions: + agreed: "Täname, et teada andsite. Tegeleme sellega." system_messages: backup_failed: subject_template: "Varundamine ebaõnnestus" diff --git a/config/locales/server.fi.yml b/config/locales/server.fi.yml index 3157fda146..25e22c2493 100644 --- a/config/locales/server.fi.yml +++ b/config/locales/server.fi.yml @@ -190,6 +190,12 @@ fi: latest: "Tuoreimmat viestiketjut" hot: "Kuumat ketjut" top: "Huippuketjut" + top_all: "Kaikkien aikojen parhaat ketjut" + top_yearly: "Vuoden parhaat ketjut" + top_quarterly: "Vuosineljänneksen parhaat ketjut" + top_monthly: "Kuukauden parhaat ketjut" + top_weekly: "Viikon parhaat ketjut" + top_daily: "Päivän parhaat ketjut" posts: "Uusimmat viestit" private_posts: "Uusimmat yksityisviestit" group_posts: "Uusimmat viestit ryhmässä %{group_name}" @@ -387,8 +393,8 @@ fi: replace_paragraph: "(Korvaa tämä kappale lyhyellä kuvauksella uudesta alueesta. Tämä kuvaus näytetään alueen valinnan yhteydessä, joten yritä pitää se alle 200 merkin pituisena. **Aluetta ei näytetä Keskustelualueet-sivulla ennen kuin olet muokannut tätä tekstiä tai luonut viestiketjuja.**)" post_template: "%{replace_paragraph}\n\nKäytä seuraavat kappaleet pidempään kuvaukseen tai selvittääksesi alueen säännöt ja ohjeet:\n\n- Miksi käyttäjät valitsisivat tämän alueen? Mitä varten se on?\n\n- Kuinka se tarkkaan ottaen eroaa muista olemassa olevista alueista?\n\n- Minkälaista sisältöä alueen ketjuissa tulisi yleensä olla?\n\n- Tarvitaanko tätä aluetta? Voisiko sen yhdistää toiseen alueeseen tai siirtää toisen alueen alle?\n" errors: - uncategorized_parent: "Alueettomia ei voi asettaa toisen alueen alle" - self_parent: "Alue ei voi olla itsensä ylempi alue." + uncategorized_parent: "Alueettomilla ei voi olla emoaluetta" + self_parent: "Alue ei voi olla itsensä emoalue" depth: "Alue ei voi olla tytäralueen tytäralue" invalid_email_in: "'%{email}' ei ole käypä sähköpostiosoite" email_already_used_in_group: "'%{email}' on jo käytössä ryhmällä '%{group_name}'." @@ -537,6 +543,7 @@ fi: welcome_to: "Tervetuloa sivustolle %{site_name}!" approval_required: "Valvojan täytyy hyväksyä uusi tilisi, jotta pääset palstalle. Saat sähköpostin, kun tilisi on hyväksytty." missing_session: "Emme voineet havaita, onnistuiko tilisi luonti. Varmista, että selaimesi sallii evästeiden käytön." + activated: "Pahoittelut, tämä tili on jo aktivoitu." post_action_types: off_topic: title: 'Se eksyy aiheesta' @@ -939,7 +946,7 @@ fi: login_required: "Vaadi kirjautumista sivuston lukemiseen, epää anonyymi pääsy." min_username_length: "Käyttäjänimen vähimmäispituus merkeissä. VAROITUS: Jos olemassa olevalla käyttäjällä tai ryhmällä on tätä lyhyempi nimi, sivustosi hajoaa!" max_username_length: "Käyttäjänimen vähimmäispituus merkeissä. VAROITUS: Jos olemassa olevalla käyttäjällä tai ryhmällä on tätä pidempi nimi, sivustosi hajoaa!" - reserved_usernames: "Käyttäjänimet, joiden rekisteröintiä ei sallita." + reserved_usernames: "Käyttäjänimet, joita ei voi rekisteröidä. Jokerimerkkiä * voi käyttää korvaamaan merkin nolla kertaa tai useammin." min_password_length: "Salasanan vähimmäispituus." min_admin_password_length: "Ylläpitäjän salasanan vähimmäispituus." password_unique_characters: "Vähimmäismäärä eri merkkejä salasanassa." @@ -1124,7 +1131,8 @@ fi: auto_block_fast_typers_max_trust_level: "Suurin luottamustaso, jolla automaattisesti estetään nopeat kirjoittajat" auto_block_first_post_regex: "Merkkikokoriippumaton regex joka aiheuttaa käyttäjän ensimmäisen viestin estämisen ja lisäämisen hyväksymisjonoon. Esimerkiksi raivoaminen|a[bc]a aiheuttaa kaikkien viestien, joissa on sanat raivoava, aba tai aca estämisen. Vaikuttaa vain ensimmäiseen viestiin." reply_by_email_enabled: "Ota käyttöön vastaukset sähköpostin avulla." - reply_by_email_address: "Saapuvan sähköpostin sapluuna sähköpostivastauksiin, esimerkiksi: %{reply_key}@reply.example.com tai replies+%{reply_key}@example.com" + reply_by_email_address: "Saapuvien sähköpostivastausten sähköpostiosoitekaava, esimerkiksi: %{reply_key}@reply.example.com tai replies+%{reply_key}@example.com" + alternative_reply_by_email_addresses: "Lista vaihtoehtoisista saapuvien sähköpostivastausten sähköpostiosoitekaavoista, esimerkiksi: %{reply_key}@reply.example.com tai replies+%{reply_key}@example.com" incoming_email_prefer_html: "Käytä HTMLää tekstin sijaan saapuville sähköposteille. Voi aiheuttaa odottamattomia ongelmia ulkoasussa!" disable_emails: "Estä Discoursea lähettämästä mitään sähköpostia" strip_images_from_short_emails: "Poista kuvat sähköposteista, joiden koko on alle 2800 tavua" @@ -1209,6 +1217,7 @@ fi: read_time_word_count: "Sanamäärä minuutissa, jota käytetään lukuajan arviointiin." topic_page_title_includes_category: "Ketjusivu sisältää alueen nimen." native_app_install_banner: "Tarjoaa toistuvasti vieraileville Discoursen käyttöjärjestelmäkohtaista sovellusta." + share_anonymized_statistics: "Julkaise yksilöimättömät käyttötilastot." max_prints_per_hour_per_user: "Tulostuspyyntöjen (/print) enimmäismäärä (aseta 0 poistaaksesi käytöstä)" full_name_required: "Koko nimi on käyttäjäprofiilin vaadittu kohta" enable_names: "Näytä käyttäjän koko nimi profiilissa, käyttäjäkortissa ja sähköposteissa. Poista käytöstä piilottaaksesi koko nimen kaikkialla." @@ -1419,6 +1428,8 @@ fi: deactivated: "Käyttäjätili poistettiin käytöstä osoitteesta '%{email}' palautettujen sähköpostien vuoksi." deactivated_by_staff: "Henkilökunta poisti käytöstä" activated_by_staff: "Henkilökunta vahvisti" + new_user_typed_too_fast: "Uusi käyttäjä näppäili liian nopeasti" + content_matches_auto_block_regex: "Sisältö täyttää automaattisesti estettävän säännöllisen lausekkeen" username: short: "täytyy olla vähintään %{min} merkkiä" long: "ei saa olla yli %{max} merkkiä" @@ -1534,6 +1545,17 @@ fi: %{base_url}/users/password-reset/%{email_token} (jos yllä oleva linkki on vanhentunut, valitse "unohdin salasanani" kirjautuessasi sisään sähköpostiosoitteellasi) + download_backup_mailer: + title: "Lataa varmuuskopio" + subject_template: "[%{site_name}] Varmuuskopion lataus sivustosta" + text_body_template: | + Tässä [varmuuskopio sivustosta](%{backup_file_path}), jota pyysit. + + Lähetimme tämän latauslinkin varmennettuun sähköpostiosoitteeseesi turvallisuussyistä. + + (Jos *et* pyytänyt varmuuskopiota, on asia otettava vakavissaan -- jollakulla on ylläpitäjän oikeudet sivustoosi.) + no_token: | + Pahoittelut, tämä varmuuskopion latauslinkki on jo käytetty tai on vanhentunut. test_mailer: title: "Sähköpostipalvelun testaus" subject_template: "[%{site_name}] Sähköpostin toimitettavuustesti" @@ -2722,7 +2744,7 @@ fi: description: "Mikä on yhteisösi oletuskieli?" forum_title: title: "Nimi" - description: "Nimi on merkiitävä asia, sillä se on ensimmäinenasia jonka potentiaalinen vierailija saa tietää yhteisöstäsi. Mitä valitsemasi nimi kertoo yhteisöstä?" + description: "Nimi on merkittävä asia, sillä se on ensimmäinenasia, jonka potentiaalinen vierailija saa tietää yhteisöstäsi. Mitä valitsemasi nimi kertoo yhteisöstä?" fields: title: label: "Yhteisösi nimi" @@ -2762,7 +2784,7 @@ fi: description: "Sinun tai organisaatiosi yleinen yhteydenottosivu. Näytetään Tietoja-sivulla." site_contact: label: "Automaattiset viestit" - description: "Tämän käyttäjän nimissä Discourse lähettää kaikki automaattiset yksityisviestit käyttäjälle. Tärkeimpänä, käyttäjä on uudelle käyttäjälle lähetettävän tervetuloviestin lähettäjä." + description: "Tämän käyttäjän nimissä Discourse lähettää käyttäjille kaikki automaattiset yksityisviestit, kuten uudelle käyttäjälle lähetettävän tervetulotoivotuksen. " corporate: title: "Organisaatio" description: "Nämä nimet näkyvät rekisteriselosteen ja käyttöehtojen yhteydessä, joita voit milloin vain muokata henkilökunta-alueella. Jos taustalla ei ole yritystä, voit hypätä tämän vaiheen yli toistaiseksi." diff --git a/config/locales/server.he.yml b/config/locales/server.he.yml index 19ad430884..f00b0bba8d 100644 --- a/config/locales/server.he.yml +++ b/config/locales/server.he.yml @@ -190,6 +190,12 @@ he: latest: "נושאים אחרונים" hot: "נושאים חמים" top: "נושאים מובילים" + top_all: "הנושאים המובילים בכל הזמנים" + top_yearly: "הנושאים המובילים השנתיים" + top_quarterly: "הנושאים המובילים הרבעוניים" + top_monthly: "הנושאים המובילים החודשיים" + top_weekly: "הנושאים המובילים השבועיים" + top_daily: "הנושאים המובילים היומיים" posts: "פוסטים אחרונים" private_posts: "הודעות פרטיות אחרונות" group_posts: "פוסטים אחרונים מ %{group_name}" @@ -422,7 +428,7 @@ he: pms_per_day: "הגעתם למספר המירבי של הודעות היום. אנא המתינו %{time_left} לפני ניסיון חוזר לבצע פעולה זו." create_like: "הגעתם למספר המירבי של לייקים היום. אנא המתינו %{time_left} לפני ניסיון חוזר לבצע פעולה זו." create_bookmark: "הגעתם למספר המירבי של סימניות להיום. אנא המתינו %{time_left} לפני ניסיון חוזר לבצע פעולה זו." - edit_post: "הגעתם למספר המירבי של עריכות להיום. אנא המתינו %{time_left} לפני ניסיון חוזר לבצע פעולה זו." + edit_post: "הגעתם למספר המרבי של עריכות היום. אנא המתינו %{time_left} לפני שתנסו שוב." live_post_counts: "אתם מבקשים ספירה של פוסטים חיים מהר מידי. אנא המתינו %{time_left} לפני שאתם מנסים שוב." unsubscribe_via_email: "הגעתם למספר המקסימלי של בטולי מנוי באמצעות מייל להיום. אנא המתינו %{time_left} לפני שאתם מנסים שוב." topic_invitations_per_day: "הגעתם למספר המקסימלי של הזמנות לנושאים להיום. אנא המתינו %{time_left} לפני שאתם מנסים שוב." @@ -532,6 +538,7 @@ he: welcome_to: "ברוכים הבאים ל-%{site_name}!" approval_required: "מנהל צריך לאשר את החשבון שלכם ידנית לפני שתוכלו להיכנס לפורום הזה. יישלח אליכם דואר אלקטרוני כשהחשבון שלכם יאושר!" missing_session: "אנחנו לא יכולים לזהות אם חשבונכם נוצר, אנא וודאו שיש לכם עוגיות (cookies) מאופשרות." + activated: "מצטערים, חשבון זה כבר הופעל." post_action_types: off_topic: title: 'אוף-טופיק' @@ -935,7 +942,7 @@ he: login_required: "דרשו הזדהות לקריאת תוכן באתר זה, אל תאפשרו גישה אנונימית." min_username_length: "אורך שמות משתמשים מינימלי בתווים. אזהרה: אם למשתמשים קיימים או קבוצות כבר יש שם קצר יותר, האתר שלכם ישבר!" max_username_length: "אורך שמות משתמשים מקסימלי בתווים. אזהרה: אם למשתמשים קיימים או קבוצות כבר יש שמות ארוכים יותר, האתר שלכם ישבר!" - reserved_usernames: "שמות משתמשים שלא ניתן להירשם איתם." + reserved_usernames: "שמות משתמשים שלא מותרת הרשמה אליהם. סימון ה wildcard - * ניתן לשימוש כדי להתאים כל תו, 0 פעמים או יותר." min_password_length: "אורך סיסמה מינימלי." min_admin_password_length: "אורך סיסמה מינימלית לאדמיניסטרטור." password_unique_characters: "מספר מינימלי של תווים ייחודיים שחייבים להיות בסיסמאות." @@ -1208,6 +1215,7 @@ he: read_time_word_count: "מספר המילים לדקה כדי להעריך את זמן הקריאה." topic_page_title_includes_category: "כותרת דף נושא כוללת את שם הקטגוריה." native_app_install_banner: "בקשו ממבקרים חוזרים להתקין את אפליקציית Discourse." + share_anonymized_statistics: "שתפו סטטיסטיקות שימוש אנונימיות." max_prints_per_hour_per_user: "מספר מקסימלי של צפיות בדף /print (הדפסה) (קיבעו ל 0 כדי לנטרל)" full_name_required: "שם מלא הוא שדה נדרש לפרופיל משתמש/ת." enable_names: "הצגת השם המלא של המשתמש/ת בעמודי הפרופיל שלהם, בכרטיסי המשתמש ובדוא\"ל שלהם. נטרלו להסתרת השם המלא בכל מקום." @@ -1421,6 +1429,8 @@ he: deactivated: "הושבת בעקבות מיילים רבים מידי שהוחזרו ל '%{email}'." deactivated_by_staff: "נוטרל על ידי הצוות" activated_by_staff: "הופעל על ידי הצוות" + new_user_typed_too_fast: "משתמש חדש הקליד מהר מידי" + content_matches_auto_block_regex: "ביטוי רגולרי לחסימת תוכן אטוטמטית" username: short: "חייבים להיות לפחות %{min} תווים" long: "נדרשים לא יותר מ-%{max} תווים" @@ -1533,6 +1543,17 @@ he: תודה שקיבלתם את ההזמנה שלכם ל %{site_name} -- ברוכים הבאים! לחצו על הקישור בשביל לבחור סיסמה: %{base_url}/users/password-reset/%{email_token} (אם הקישור פג תוקף, בחרו ב"שכחתי את הסיסמה שלי" בהתחברות.) + download_backup_mailer: + title: "הורדת גיבוי שולח מיילים" + subject_template: "הורדת גיבוי אתר [%{site_name}]" + text_body_template: | + הנה ה[קישור להורדת גיבוי](%{backup_file_path}) שביקשרתם. + + שלחנו קישור הורדה זה לכתובת המייל המאומתת שלכם מסיבות בטיחותיות. + + (אם *לא* ביקשתם הורדה זו, אתם אמורים להיות מוטרדים למדי -- למישהו יש הרשאות אדמיניסטרציה לאתר שלכם.) + no_token: | + מצטערים, כבר נעשה שימוש בקישור הורדת גיבוי זה או שהוא פקע. test_mailer: title: "שולח-מיילים לבדיקה" subject_template: "[%{site_name}] מייל בדיקת שליחתיות" @@ -2982,7 +3003,7 @@ he: description: "דף יצירת קשר כללי איתכם או עם הארגון שלכם. יוצג בדף האודות שלכם." site_contact: label: "הודעות אוטומטיות" - description: "כל ההודעות הפרטיות והאוטומטיות של Discourse יישלחו ממשתמש זה. הכי חשוב, משתמש זה יהיה השולח הנבחר של כל הודעת ברוכים הבאים שנשלחת אוטומטית למשתמשים חדשים." + description: "כל הודעות דיסקורס האישיות האוטומטיות יישלחו ממשתמש זה, כמו הודעת הברוכים הבאים שנשלחת לכל משתמש חדש." corporate: title: "ארגון" description: "שמות אלו יוכנסו למדיניות הפרטיות שלכם ולתנאי השימוש, שתוכלו לערוך בכל זמן בקטגוריית הצוות. אם אין לכם חברה, הרגישו חופשי לדלג על שלב זה לעת עתה." diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml index eaa954f5b6..9aed538f2e 100644 --- a/config/locales/server.it.yml +++ b/config/locales/server.it.yml @@ -924,24 +924,24 @@ it: enable_facebook_logins: "Abilita l'autenticazione via Facebook, richiede facebook_app_id e facebook_app_secret" facebook_app_id: "App id per autenticazione Facebook, come registrata su https://developers.facebook.com/apps" facebook_app_secret: "App secret per autenticazione Facebook, come registrata su https://developers.facebook.com/apps" - facebook_request_extra_profile_details: "Richiedi i miei dati, posizione e sito web da facebook. (richiede che la tua applicazione di autorizzazione sia approvata da facebook)" + facebook_request_extra_profile_details: "Richiedi i miei dati, posizione e sito web da facebook (richiede che la tua applicazione auth sia approvata da facebook)." enable_github_logins: "Abilita l'autenticazione via Github, richiede github_client_id e github_client_secret" github_client_id: "Client id per autenticazione Github, come registrata su https://github.com/settings/applications" github_client_secret: "Client secret per autenticazione Github, come registrata su https://github.com/settings/applications" - readonly_mode_during_backup: "Abilita la modalità read only mentre esegui un backup" + readonly_mode_during_backup: "Abilita la modalità sola lettura mentre è in esecuzione un backup" allow_restore: "Abilita il ripristino, che sostituisce TUTTI i dati del sito! Lascia a falso a meno che non hai intenzione di ripristinare un backup." maximum_backups: "Il numero massimo di backup da mantenere sul disco. I backup più vecchi vengono automaticamente cancellati." automatic_backups_enabled: "Esegui backup automatici come definito nella frequenza di backup" backup_frequency: "Con che frequenza, in giorni, effettuiamo il backup del sito." enable_s3_backups: "Carica i backup su S3 quando completati. IMPORTANTE: richiede che siano inserite valide credenziali S3 nelle impostazioni File." s3_backup_bucket: "Il bucket remoto che contiene i backup. ATTENZIONE: assicurati che sia un bucket privato." - s3_disable_cleanup: "Disabilita la rimozione dei backup S3 quando rimossi localmente." - backup_time_of_day: "Ora del giorno in UTC quando il backup dovrebbe avvenire." - backup_with_uploads: "Includi gli upload nei backup schedulati. Se disabilitata verrà eseguito il backup del solo database." + s3_disable_cleanup: "Disabilita la rimozione dei backup da S3 quando rimossi localmente." + backup_time_of_day: "Ora del giorno in UTC in cui eseguire il backup." + backup_with_uploads: "Includi i caricamenti nei backup programmati. Se disabilitata verrà eseguito il backup del solo database." active_user_rate_limit_secs: "Ogni quanti secondi viene aggiornato il campo 'last_seen_at'" verbose_localization: "Mostra suggerimenti per la traduzione nell'interfaccia utente" previous_visit_timeout_hours: "Durata di una visita prima che venga considerata la visita 'precedente', in ore" - rebake_old_posts_count: "Numero di vecchi post che devono essere rebaked ogni 15 minuti." + rebake_old_posts_count: "Numero di vecchi messaggi da rigenerare ogni 15 minuti." rate_limit_create_topic: "Dopo aver creato un argomento, gli utenti devono aspettare (n) secondi prima di poterne creare un altro." rate_limit_create_post: "Dopo aver inviato un messaggio, gli utenti devono aspettare (n) secondi prima di creare un altro messaggio. " rate_limit_new_user_create_topic: "Dopo aver creato un argomento, i nuovi utenti devono aspettare (n) secondi prima di poter creare un altro argomento." @@ -954,25 +954,25 @@ it: max_private_messages_per_day: "Numero massimo di messaggi che gli utenti possono creare al giorno." max_invites_per_day: "Numero massimo di inviti che un utente può inviare in un giorno." max_topic_invitations_per_day: "Numero massimo di inviti ad argomenti che un utente può inviare al giorno." - alert_admins_if_errors_per_minute: "Numero di errori per minuto al fine di attivare un admin alert. Un valore pari a 0 disabilita questa feature. NOTA: richiede un riavvio." - alert_admins_if_errors_per_hour: "Numero di errori per ora al fine di attivare un admin alert. Un valore pari a 0 disabilita questa feature. NOTA: richiede un riavvio." - categories_topics: "Numero di topic da mostrare nella pagine /categories." + alert_admins_if_errors_per_minute: "Soglia di errori al minuto che scatena un allarme agli amministratori. Un valore pari a 0 disabilita questa caratteristica. NOTA: richiede un riavvio." + alert_admins_if_errors_per_hour: "Soglia di errori all'ora che scatena un allarme agli amministratori. Un valore pari a 0 disabilita questa caratteristica. NOTA: richiede un riavvio." + categories_topics: "Numero di argomenti da mostrare nella pagina /categorie." suggested_topics: "Numero di argomenti suggeriti mostrati in fondo ad un argomento." limit_suggested_to_category: "Negli argomenti suggeriti, mostra soltanto argomenti della categoria corrente. " - suggested_topics_max_days_old: "I topic suggeriti dovrebbero essere non più vecchi di n giorni." + suggested_topics_max_days_old: "Gli argomenti suggeriti non dovrebbero essere più vecchi di n giorni." clean_up_uploads: "Elimina i caricamenti orfani per evitare l'hosting di materiale illegale. ATTENZIONE: prima di attivare questa impostazione è meglio effettuare un backup della cartella /uploads." clean_orphan_uploads_grace_period_hours: "Dopo quante ore un caricamento orfano (senza riferimenti) viene rimosso." purge_deleted_uploads_grace_period_days: "Dopo quanti giorni un caricamento cancellato viene rimosso." purge_unactivated_users_grace_period_days: "Periodo di grazia (in giorni) prima che un utente che non abbia attivato il proprio account venga cancellato." enable_s3_uploads: "Mette i caricamenti sullo spazio disco Amazon S3. IMPORTANTE: richiede che siano inserite valide credenziali S3 (sia l'access key id sia l'access key secret)." - s3_use_iam_profile: 'Usa il ruolo AWS EC2 IAM per recuperare le key. NOTA: abilitarlo sovrascriverà la "s3 access key id" e la "s3 secret access key". ' + s3_use_iam_profile: 'Usa il ruolo AWS EC2 IAM per recuperare le chiavi. NOTA: abilitarla sovrascriverà le impostazioni "s3 access key id" e "s3 secret access key". ' s3_upload_bucket: "Il nome del bucket Amazon S3 sul quale verranno caricati i file. ATTENZIONE: deve essere tutto minuscolo, senza punti, senza trattini bassi." s3_access_key_id: "La access key id Amazon S3 che verrà usata per caricare le immagini." s3_secret_access_key: "La access key secret Amazon S3 che verrà usata per caricare le immagini." s3_region: "La region name Amazon S3 che verrà usata per caricare le immagini." avatar_sizes: "Elenco delle dimensioni degli avatar, generate automaticamente." external_system_avatars_enabled: "Utilizza un servizio esterno per gli avatar." - external_system_avatars_url: "URL del servizio esterno di avatar. Le sostituzioni consentite sono {username} {first_letter} {color} {size}" + external_system_avatars_url: "URL del servizio esterno di avatar. Le sostituzioni consentite sono {username} {first_letter} {color} {size}" default_opengraph_image_url: "URL dell'immagine di default opengraph." enable_flash_video_onebox: "Attiva l'inserimento di collegamenti swf e flv (Adobe Flash) in onebox. ATTENZIONE: comporta rischi per la sicurezza." default_invitee_trust_level: "Livello di esperienza (0-4) assegnato di default agli utenti invitati." @@ -993,19 +993,19 @@ it: tl3_links_no_follow: "Non rimuovere rel=nofollow dai collegamenti pubblicati da utenti con livello di esperienza 3." min_trust_to_create_topic: "Livello minimo richiesto per creare un nuovo argomento." min_trust_to_edit_wiki_post: "Livello minimo richiesto per modificare un argomento segnato come wiki." - min_trust_to_edit_post: "Il minimo livello di trust richiesto per modificare i post." - min_trust_to_allow_self_wiki: "Il minimo livello di trust richiesto per consentire agli utenti di postare sulla wiki." - min_trust_to_send_messages: "Il minimo livello di trust richiesto per creare nuovi messaggi privati." + min_trust_to_edit_post: "Il livello di esperienza minimo richiesto per modificare i messaggi." + min_trust_to_allow_self_wiki: "Il livello di esperienza minimo richiesto per consentire agli utenti di pubblicare una propria wiki." + min_trust_to_send_messages: "Il livello di esperienza minimo richiesto per creare nuovi messaggi privati." newuser_max_links: "Quanti collegamenti può aggiungere a un messaggio un nuovo utente ." newuser_max_images: "Quante immagini può aggiungere ad un messaggio un nuovo utente." newuser_max_attachments: "Quanti allegati può aggiungere ad un messaggio un nuovo utente." newuser_max_mentions_per_post: "Massimo numero di menzioni ad un @nome che un utente può fare in un messaggio." newuser_max_replies_per_topic: "Numero massimo di risposte che un nuovo utente può inviare in un singolo argomento, prima che qualcuno risponda." max_mentions_per_post: "Numero massimo di menzioni ad un @nome che chiunque può fare in un messaggio." - max_users_notified_per_group_mention: "Massimo numero di utenti che possono ricevere una notifica se un gruppo è menzionato (se la soglia è raggiunta nessuna notifica verrà inviata)" + max_users_notified_per_group_mention: "Massimo numero di utenti che possono ricevere una notifica se un gruppo è menzionato (se la soglia è raggiunta, nessuna notifica verrà inviata)" create_thumbnails: "Crea anteprime e lightbox delle immagini che sono troppo grandi per essere contenute in un messaggio." email_time_window_mins: "Aspetta (n) minuti prima di inviare email di notifica, per dare agli utenti la possibilità di modificare e completare i loro messaggi." - private_email_time_window_seconds: "Attendi (n) secondi prima di inviare una notifica privata, per dare agli utenti la possibilità di modificare e finalizzare i loro messaggi." + private_email_time_window_seconds: "Attendi (n) secondi prima di inviare una notifica privata per email, per dare agli utenti la possibilità di modificare e finalizzare i loro messaggi." email_posts_context: "Quante risposte precedenti inserire come contesto nelle email di notifica." flush_timings_secs: "Frequenza di svuotamento dei dati temporali verso il server, in secondi." title_max_word_length: "La lunghezza massima di una parola, in caratteri, nel titolo di un argomento." @@ -1015,7 +1015,7 @@ it: title_fancy_entities: "Converti caratteri ASCII comuni in HTML nei titoli dell'argomento, tipo SmartyPants http://daringfireball.net/projects/smartypants/" min_title_similar_length: "Lunghezza minima di un titolo che attiva il controllo su argomenti simili." min_body_similar_length: "Lunghezza minima del corpo di un messaggio che attiva il controllo su argomenti simili." - desktop_category_page_style: "Stile visuale per la pagina /categories" + desktop_category_page_style: "Stile visuale per la pagina /categorie." category_colors: "Un elenco di valori esadecimali di colori permessi per le categorie." category_style: "Stile grafico dei distintivi relativi alle categorie." max_image_size_kb: "Dimensione massima in kB per caricare immagini degli utenti. Deve essere configurata anche in nginx (client_max_body_size) / apache o nel proxy." diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml index f4f533154d..33080aa630 100644 --- a/config/locales/server.nl.yml +++ b/config/locales/server.nl.yml @@ -9,13 +9,13 @@ nl: dates: short_date_no_year: "D MMM" short_date: "D MMM YYYY" - long_date: "D MMMM YYYY H:mm" + long_date: "D MMMM YYYY [om] HH:mm" datetime_formats: &datetime_formats formats: short: "%d-%m-%Y" short_no_year: "%-d %B" - date_only: "%B %-d, %Y" - long: "%B %-d, %Y, %l:%M%P" + date_only: "%-d %B %Y" + long: "%-d %B %Y om %H:%M" date: month_names: [null, januari, februari, maart, april, mei, juni, juli, augustus, september, oktober, november, december] <<: *datetime_formats @@ -27,43 +27,43 @@ nl: topics: "Topics" posts: "berichten" loading: "Laden" - powered_by_html: 'Powered by Discourse, werkt het beste met JavaScript ingeschakeld' - log_in: "Inloggen" - purge_reason: "Automatisch verwijderd, account gedeactiveerd." - disable_remote_images_download_reason: "Het downloaden van plaatjes is uitgeschakeld omdat er niet genoeg schijfruimte beschikbaar is." + powered_by_html: 'Mogelijk gemaakt door Discourse, best bekeken met JavaScript ingeschakeld' + log_in: "Aanmelden" + purge_reason: "Automatisch verwijderd als verlaten, gedeactiveerde account." + disable_remote_images_download_reason: "Het downloaden van externe afbeeldingen is uitgeschakeld, omdat er niet genoeg schijfruimte beschikbaar was." anonymous: "Anoniem" remove_posts_deleted_by_author: "Verwijderd door gebruiker" emails: incoming: default_subject: "Dit topic heeft een titel nodig" - show_trimmed_content: "Toon getrimde inhoud" - maximum_staged_user_per_email_reached: "Het maximum aantal staged gebruikers dat per e-mail kan worden aangemaakt is bereikt." + show_trimmed_content: "Afgekapte inhoud tonen" + maximum_staged_user_per_email_reached: "Het maximale aantal staged gebruikers dat per e-mail kan worden aangemaakt is bereikt." errors: - empty_email_error: "Gebeurt wanneer de e-mail die wij ontvangen hebben leeg is." - no_message_id_error: "Gebeurt wanneer de e-mail geen 'Message-Id' header heeft." - auto_generated_email_error: "Gebeurt wanneer de 'voorrang' header is ingesteld op: lijst, ongewenst, bulk of auto_reply, of wanneer een andere header het volgende bevat: auto-submitted, auto-replied of auto-generated." - no_body_detected_error: "Gebeurt wanneer er geen body uit de mail gehaald kan worden, en er geen bijlagen gevonden worden." + empty_email_error: "Gebeurt wanneer de e-mail die we hebben ontvangen leeg was." + no_message_id_error: "Gebeurt wanneer de e-mail geen 'Message-Id'-header heeft." + auto_generated_email_error: "Gebeurt wanneer de 'precedence'-header is ingesteld op list, junk, bulk of auto_reply, of wanneer een andere header het volgende bevat: auto-submitted, auto-replied of auto-generated." + no_body_detected_error: "Gebeurt wanneer er geen hoofdtekst uit de mail kon worden gehaald en er geen bijlagen waren." inactive_user_error: "Gebeurt wanneer de afzender niet actief is." blocked_user_error: "Gebeurt wanneer de afzender is geblokkeerd." - bad_destination_address: "Gebeurt wanneer geen van de e-mailadressen in de Aan, CC-, of BCC-velden gelijk zijn aan de geconfigureerde inkomende e-mailadressen." - strangers_not_allowed_error: "Gebeurt wanneer een gebruiker heeft geprobeerd om een nieuw topic aan te maken in een categorie waar hij/zij geen lid van is." - insufficient_trust_level_error: "Gebeurt wanneer een gebruiker heeft geprobeerd om een nieuw topic aan te maken in een categorie waarvoor hij/zij niet het benodigde trustlevel heeft." - reply_user_not_matching_error: "Gebeurt wanneer een reactie kwam van een ander e-mailadres dan waar de notificatie was heen gestuurd. " - topic_not_found_error: "Gebeurt wanneer een reactie binnen kwam, maar het topic al is verwijdert." - topic_closed_error: "Gebeurt wanneer een reactie binnen kwam, maar het verwante topic is gesloten." - bounced_email_error: "E-mail is een gebounced e-mailrapport." - screened_email_error: "Gebeurt wanneer het e-mailadres van de verzender al gescreend was." + bad_destination_address: "Gebeurt wanneer geen van de e-mailadressen in de Aan/Cc/Bcc-velden met een geconfigureerd inkomend e-mailadres overeenkwam." + strangers_not_allowed_error: "Gebeurt wanneer een gebruiker een nieuw topic probeerde aan te maken in een categorie waar hij/zij geen lid van is." + insufficient_trust_level_error: "Gebeurt wanneer een gebruiker een nieuw topic probeerde aan te maken in een categorie waarvoor hij/zij niet het vereiste vertrouwensniveau heeft." + reply_user_not_matching_error: "Gebeurt wanneer een antwoord van een ander e-mailadres kwam dan waar de melding naartoe is gestuurd." + topic_not_found_error: "Gebeurt wanneer een antwoord is ontvangen, maar het verwante topic is verwijderd." + topic_closed_error: "Gebeurt wanneer een antwoord is ontvangen, maar het verwante topic is gesloten." + bounced_email_error: "E-mail is een gebouncet e-mailrapport." + screened_email_error: "Gebeurt wanneer het e-mailadres van de afzender al was gecontroleerd." errors: &errors format: '%{attribute} %{message}' messages: - too_long_validation: "is beperkt tot %{max} tekens; je gebruikt %{length}." + too_long_validation: "is beperkt tot %{max} tekens; u hebt er %{length} ingevoerd." invalid_boolean: "Ongeldige boolean." taken: "is al in gebruik" - accepted: moet geaccepteerd worden - blank: mag niet leeg zijn + accepted: moet zijn geaccepteerd + blank: kan niet leeg zijn present: moet leeg zijn confirmation: "komt niet overeen met %{attribute}" - empty: mag niet leeg zijn + empty: kan niet leeg zijn equal_to: moet gelijk zijn aan %{count} even: moet even zijn exclusion: is gereserveerd @@ -77,97 +77,101 @@ nl: matches_censored_pattern: "bevat de volgende woorden die met de gecensureerde regexp van de website overeenkomen: %{censored_words}" less_than: moet minder zijn dan %{count} less_than_or_equal_to: moet minder zijn dan of gelijk zijn aan %{count} - not_a_number: is niet een getal + not_a_number: is geen getal not_an_integer: moet een integer zijn odd: moet oneven zijn record_invalid: 'Validatie mislukt: %{errors}' restrict_dependent_destroy: - one: "Kan record niet verwijderen omdat %{record} hiervan afhankelijk is" - many: "Kan record niet verwijderen omdat %{record} hiervan afhankelijk is" + one: "Kan record niet verwijderen, omdat %{record} hiervan afhankelijk is" + many: "Kan record niet verwijderen, omdat %{record} hiervan afhankelijk zijn" too_long: - one: is te lang (maximum is één teken) + one: is te lang (maximum is 1 teken) other: is te lang (maximum is %{count} tekens) too_short: - one: is te kort (minimum is één teken) + one: is te kort (minimum is 1 teken) other: is te kort (minimum is %{count} tekens) wrong_length: - one: is de verkeerde lengte (moet één teken zijn) - other: is de verkeerde lengte (moet %{count} tekens zijn) + one: heeft de verkeerde lengte (moet 1 teken zijn) + other: heeft de verkeerde lengte (moet %{count} tekens zijn) other_than: "moet anders zijn dan %{count}" template: - body: 'De volgende velden bevatten fouten:' + body: 'Er waren problemen met de volgende velden:' header: - one: 1 fout voorkomt dat deze %{model} opgeslagen kan worden - other: '%{count} fouten voorkomen dat deze %{model} opgeslagen kan worden' + one: 1 fout heeft voorkomen %{model} kon worden opgeslagen + other: '%{count} fouten hebben voorkomen dat %{model} kon worden opgeslagen' embed: - load_from_remote: "Er ging iets mis bij het laden van dat bericht." + load_from_remote: "Er is een fout opgetreden bij het laden van dat bericht." site_settings: - min_username_length_exists: "Je kan de minimale gebruikersnaam lengte niet hoger instellen dan de kortste gebruikersnaam." - min_username_length_range: "Je kan het minimum niet hoger instellen dan het maximum." - max_username_length_exists: "Je kan de maximale gebruikersnaam lengte niet lager instellen dan de langste gebruikersnaam." - max_username_length_range: "Je kan het maximum niet lager instellen dan het minimun." - default_categories_already_selected: "Je kan geen categorie selecteren die wordt gebruikt in een andere lijst." - s3_upload_bucket_is_required: "U kunt niet de uploads van de S3 toestaan totdat u de 's3_upload_bucket' hebt verleend." + min_username_length_exists: "U kunt de minimale gebruikersnaamlengte niet hoger instellen dan de kortste gebruikersnaam." + min_username_length_range: "U kunt het minimum niet hoger instellen dan het maximum." + max_username_length_exists: "U kunt de maximale gebruikersnaamlengte niet lager instellen dan de langste gebruikersnaam." + max_username_length_range: "U kunt het maximum niet lager instellen dan het minimum." + default_categories_already_selected: "U kunt geen categorie selecteren die in een andere lijst wordt gebruikt." + s3_upload_bucket_is_required: "U kunt geen uploads naar S3 toestaan voordat u de 's3_upload_bucket' hebt opgegeven." invite: not_found: "Uw uitnodigingstoken is ongeldig. Neem contact op met de beheerder van de website." bulk_invite: - file_should_be_csv: "Het geüploade bestand moet in csv-formaat zijn." - error: "Er trad een fout op tijdens het uploaden van dat bestand. Probeer het later nog eens." + file_should_be_csv: "Het geüploade bestand dient de CSV-indeling te hebben." + error: "Er is een fout opgetreden tijdens het uploaden van dat bestand. Probeer het later opnieuw." topic_invite: - user_exists: "Sorry, die gebruiker is al uitgenodigd. Je kan een gebruiker maar een keer voor een topic uitnodigen." + user_exists: "Sorry, die gebruiker is al uitgenodigd. U kunt een gebruiker maar één keer voor een topic uitnodigen." backup: - operation_already_running: "Er wordt al een opdracht uitgevoerd. Kan nu niet een nieuwe opdracht starten." - backup_file_should_be_tar_gz: "Het backupbestand moet een .tar.gz archief zijn." - not_enough_space_on_disk: "Er is niet voldoende ruimte op de schijf vrij om deze backup te uploaden." - invalid_filename: "De naam van het backup-bestand bevat ongeldige tekens. Geldige tekens zijn a-z 0-9 . - _." - not_logged_in: "Om dat te kunnen doen moet je ingelogd zijn." - not_found: "De opgevraagde URL of resource kan niet gevonden worden." - invalid_access: "Je hebt geen permissie om de opgevraagde resource te bekijken." - read_only_mode_enabled: "De site is in read only modus. Interactie is niet mogelijk." + operation_already_running: "Er wordt al een bewerking uitgevoerd. Er kan nu geen nieuwe taak worden gestart." + backup_file_should_be_tar_gz: "Het back-upbestand dient een .tar.gz-archief te zijn." + not_enough_space_on_disk: "Er is niet voldoende ruimte op de schijf om deze back-up te uploaden." + invalid_filename: "De naam van het back-upbestand bevat ongeldige tekens. Geldige tekens zijn a-z 0-9 . - _." + not_logged_in: "U dient aangemeld te zijn om dat te doen." + not_found: "De opgevraagde URL of bron kon niet worden gevonden." + invalid_access: "U mag de opgevraagde bron niet bekijken." + read_only_mode_enabled: "De website bevindt zich in alleen-lezenmodus. Interacties zijn uitgeschakeld." reading_time: "Leestijd" likes: "Likes" too_many_replies: - one: "Sorry, nieuwe gebruikers mogen één reactie plaatsen in hetzelfde topic." - other: "Sorry, nieuwe gebruikers mogen %{count} reacties plaatsen in hetzelfde topic." + one: "Sorry, maar nieuwe gebruikers mogen tijdelijk maar 1 antwoord in hetzelfde topic plaatsen." + other: "Sorry, maar nieuwe gebruikers mogen tijdelijk maar %{count} antwoorden in hetzelfde topic plaatsen." embed: - start_discussion: "Reageer" - continue: "Ga verder met de discussie" + start_discussion: "Discussie starten" + continue: "Discussie voortzetten" error: "Fout bij embedden" - configure: "Configureer Embedden" + referer: "Verwijzing:" + mismatch: "De verwijzing kwam met geen van de volgende hosts overeen:" + no_hosts: "Er zijn geen hosts ingesteld voor embedding." + configure: "Embedden configureren" more_replies: - one: "Nog 1 reactie" - other: "Nog %{count} reacties" + one: "Nog 1 antwoord" + other: "Nog %{count} antwoorden" loading: "Discussie laden..." permalink: "Permalink" - imported_from: "Deze topic is een voortzetting van de oorspronkelijke topic: %{link}" + imported_from: "Dit discussietopic is een voortzetting van het oorspronkelijke topic op %{link}" in_reply_to: "▶ %{username}" replies: - one: "1 reactie" - other: "%{count} reacties" - no_mentions_allowed: "Sorry, je mag geen andere gebruikers noemen." + one: "1 antwoord" + other: "%{count} antwoorden" + no_mentions_allowed: "Sorry, u kunt geen andere gebruikers noemen." too_many_mentions: - one: "Sorry, je mag slechts één andere gebruiker noemen in een post." - other: "Sorry, je mag slechts %{count} andere gebruikers noemen in een bericht." - no_mentions_allowed_newuser: "Sorry, nieuwe gebruikers mogen geen andere gebruikers noemen." + one: "Sorry, u kunt maar één andere gebruiker in een bericht noemen." + other: "Sorry, u kunt maar %{count} gebruikers in een bericht noemen." + no_mentions_allowed_newuser: "Sorry, nieuwe gebruikers kunnen geen andere gebruikers noemen." too_many_mentions_newuser: - one: "Sorry, nieuwe gebruikers mogen slechts één andere gebruiker noemen in een post." - other: "Sorry, nieuwe gebruikers mogen slechts %{count} andere gebruikers noemen in een bericht." - no_images_allowed: "Sorry, nieuwe gebruikers mogen geen afbeeldingen plaatsen in een bericht." + one: "Sorry, nieuwe gebruikers kunnen maar één andere gebruiker in een bericht noemen." + other: "Sorry, nieuwe gebruikers kunnen maar %{count} gebruikers in een bericht noemen." + no_images_allowed: "Sorry, nieuwe gebruikers kunnen geen afbeeldingen in berichten plaatsen." too_many_images: - one: "Sorry, nieuwe gebruikers mogen slechts één afbeelding plaatsen in een post." - other: "Sorry, nieuwe gebruikers mogen slechts %{count} afbeeldingen plaatsen in een bericht." - no_attachments_allowed: "Sorry, nieuwe gebruikers mogen geen bijlages invoegen in een bericht." + one: "Sorry, nieuwe gebruikers kunnen maar één afbeelding in een bericht plaatsen." + other: "Sorry, nieuwe gebruikers kunnen maar %{count} afbeeldingen in een bericht plaatsen." + no_attachments_allowed: "Sorry, nieuwe gebruikers kunnen geen bijlagen in berichten plaatsen." too_many_attachments: - one: "Sorry, nieuwe gebruikers mogen slechts één bijlages invoegen in een post." - other: "Sorry, nieuwe gebruikers mogen slechts %{count} bijlages invoegen in een bericht." - no_links_allowed: "Sorry, nieuwe gebruikers mogen geen links plaatsen in een bericht." + one: "Sorry, nieuwe gebruikers kunnen maar één bijlage in een bericht plaatsen." + other: "Sorry, nieuwe gebruikers kunnen maar %{count} bijlagen in een bericht plaatsen." + no_links_allowed: "Sorry, nieuwe gebruikers kunnen geen koppelingen in berichten plaatsen." too_many_links: - one: "Sorry, nieuwe gebruikers mogen slechts één link plaatsen in een post." - other: "Sorry, nieuwe gebruikers mogen slechts %{count} links plaatsen in een bericht." - spamming_host: "Sorry, je kan niet linken naar die host." - user_is_suspended: "Geschorste gebruikers mogen geen berichten meer plaatsen." - topic_not_found: "Er is iets fout gegaan. Wellicht is het topic gesloten of verwijderd terwijl je er naar keek?" - just_posted_that: "lijkt teveel op het bericht dat je net geschreven hebt" + one: "Sorry, nieuwe gebruikers kunnen maar één koppeling in een bericht plaatsen." + other: "Sorry, nieuwe gebruikers kunnen maar %{count} koppelingen in een bericht plaatsen." + spamming_host: "Sorry, u kunt geen koppeling naar die host plaatsen." + user_is_suspended: "Geschorste gebruikers mogen geen berichten plaatsen." + topic_not_found: "Er is iets fout gegaan. Misschien is het topic gesloten of verwijderd terwijl u het bekeek?" + not_accepting_pms: "Sorry, %{username} accepteert momenteel geen berichten." + just_posted_that: "lijkt te veel op wat u onlangs hebt geplaatst" invalid_characters: "bevat ongeldige tekens" is_invalid: "lijkt onduidelijk, is het een volledige zin?" next_page: "volgende pagina →" @@ -175,32 +179,38 @@ nl: page_num: "Pagina %{num}" home_title: "Hoofdpagina" topics_in_category: "Topics in de categorie '%{category}'" - rss_posts_in_topic: "RSS feed van '%{topic}'" - rss_topics_in_category: "RSS fees van topics in de categorie '%{category}'" + rss_posts_in_topic: "RSS-feed van '%{topic}'" + rss_topics_in_category: "RSS-feed van topics in de categorie '%{category}'" author_wrote: "%{author} schreef:" num_posts: "Berichten:" num_participants: "Deelnemers:" - read_full_topic: "Lees volledige topic" + read_full_topic: "Volledige topic lezen" private_message_abbrev: "PB" rss_description: latest: "Nieuwste topics" - hot: "Hot topics" - top: "Populaire topics" + hot: "Populaire topics" + top: "Toptopics" + top_all: "Toptopics vanaf begin" + top_yearly: "Jaarlijkse toptopics" + top_quarterly: "Driemaandelijkse toptopics" + top_monthly: "Maandelijkse toptopics" + top_weekly: "Wekelijkse toptopics" + top_daily: "Dagelijkse toptopics" posts: "Nieuwste berichten" - private_posts: "Recente privé-berichten" - group_posts: "Meest recente berichten van %{group_name}" - group_mentions: "Laatste vermeldingen van %{group_name}" - user_posts: "Laatste berichten van @%{username}" - user_topics: "Laatste topics van @%{username}" + private_posts: "Nieuwste privéberichten" + group_posts: "Nieuwste berichten van %{group_name}" + group_mentions: "Nieuwste vermeldingen van %{group_name}" + user_posts: "Nieuwste berichten van @%{username}" + user_topics: "Nieuwste topics van @%{username}" tag: "Gemarkeerde onderwerpen" - too_late_to_edit: "Dat bericht is lang geleden geschreven. Het kan niet meer gewijzigd of verwijderd worden." - revert_version_same: "De huidige versie is dezelfde als de versie waar je naar probeert terug te draaien." + too_late_to_edit: "Dat bericht is te lang geleden geschreven. Het kan niet meer worden gewijzigd of verwijderd." + revert_version_same: "De huidige versie is dezelfde als de versie die u probeert terug te zetten." excerpt_image: "afbeelding" queue: - delete_reason: "Verwijderd via de bericht moderatie wachtrij" + delete_reason: "Verwijderd via wachtrij voor berichtmoderatie" groups: errors: - can_not_modify_automatic: "Je kunt automatische groepen niet wijzigen" + can_not_modify_automatic: "U kunt een automatische groep niet wijzigen" member_already_exist: "'%{username}' is al lid van deze groep." invalid_domain: "%{domain}' is geen geldig domein." invalid_incoming_email: "%{email}' is geen geldig e-mailadres." @@ -208,42 +218,42 @@ nl: email_already_used_in_category: "'%{email}' wordt al gebruikt door de categorie '%{category_name}'." default_names: everyone: "iedereen" - admins: "admins" + admins: "beheerders" moderators: "moderators" staff: "staf" - trust_level_0: "trust_level_0" - trust_level_1: "trust_level_1" - trust_level_2: "trust_level_2" - trust_level_3: "trust_level_3" - trust_level_4: "trust_level_4" + trust_level_0: "vertrouwensniveau_0" + trust_level_1: "vertrouwensniveau_1" + trust_level_2: "vertrouwensniveau_2" + trust_level_3: "vertrouwensniveau_3" + trust_level_4: "vertrouwensniveau_4" education: until_posts: - one: "één bericht" + one: "1 bericht" other: "%{count} berichten" new-topic: | - Welkom op %{site_name} — **bedankt voor het starten van een nieuwe conversatie!** + Welkom op %{site_name} – **bedankt voor het starten van een nieuwe conversatie!** - - Klink de titel interessant als je deze hardop leest? Is het een goede samenvatting? + - Klinkt de titel interessant als u deze hardop leest? Is het een goede samenvatting? - - Wie zou hier in geïnteresseerd zijn? Waarom is het van belang? Wat voor reacties verwacht je te krijgen? + - Wie zou hierin geïnteresseerd zijn? Waarom is het van belang? Wat voor reacties verwacht u te krijgen? - - Gebruik algemeen gebruikte steekwoorden zodat anderen je topic kunnen *vinden*. Selecteer een categorie om je topic te groeperen met gerelateerde topics. + - Gebruik algemeen gebruikte woorden, zodat anderen uw topic kunnen *vinden*. Selecteer een categorie om uw topic met verwante topics te groeperen. - Voor meer informatie, [bekijk onze gemeenschaps-regels](/guidelines). Dit paneel verschijnt alleen bij je eerste %{education_posts_text}. + [Bekijk onze gemeenschapsrichtlijnen](/guidelines) voor meer informatie. Dit paneel verschijnt alleen bij uw eerste %{education_posts_text}. new-reply: | - Welkom op %{site_name} — **bedankt voor het deelnemen aan de conversatie!** + Welkom op %{site_name} – **bedankt voor uw bijdrage!** - - Geeft je reactie een nuttige bijdrage aan de conversatie, hoe klein dan ook? + - Levert uw antwoord een nuttige bijdrage aan de conversatie, hoe klein dan ook? - - Wees aardig voor de andere leden. + - Wees aardig voor de andere gemeenschapsleden. - - Je mag best kritisch zijn, maar onthoud dat je kritiek moet geven op *ideeën*, niet op mensen. + - Opbouwende kritiek is welkom, maar geef kritiek op *ideeën*, niet op mensen. - Voor meer informatie, [bekijk onze regels](/guidelines). Deze tekst zal alleen verschijnen bij je eerste %{education_posts_text}. + [Bekijk onze gemeenschapsrichtlijnen](/guidelines) voor meer informatie. Dit paneel verschijnt alleen bij uw eerste %{education_posts_text}. activerecord: attributes: category: - name: "Naam categorie" + name: "Categorienaam" topic: title: 'Titel' featured_link: 'Uitgelichte link' @@ -258,7 +268,7 @@ nl: base: warning_requires_pm: "Je kunt alleen waarschuwingen aan privéberichten toevoegen." too_many_users: "Je kunt een waarschuwing per keer slechts naar één ander lid sturen." - cant_send_pm: "Sorry, je kan geen privébericht sturen naar deze persoon." + cant_send_pm: "Sorry, u kunt geen privébericht naar die gebruiker sturen." no_user_selected: "Je moet een geldige gebruiker selecteren." featured_link: invalid: "is ongeldig. URL moet http:// of https:// bevatten." @@ -321,7 +331,7 @@ nl: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Over de categorie %{category}" - replace_paragraph: "(Vervang deze eerste paragraaf met een korte beschrijving van je nieuwe categorie. Deze leidraad zal worden getoond in het categorie selectie scherm, dus probeer minder dan 200 karakters te gebruiken. **Totdat je deze beschrijving bewerkt of topics aanmaakt, zal deze categorie niet weergegeven worden op de pagina Categorieën.**)" + replace_paragraph: "(Vervang deze eerste alinea door een korte beschrijving van uw nieuwe categorie. Deze leidraad verschijnt in het categorieselectiegebied, dus probeer deze onder de 200 tekens te houden. **Voordat u deze beschrijving bewerkt of topics aanmaakt, verschijnt deze categorie niet op de categoriepagina.**)" post_template: "%{replace_paragraph}\n\nGebruik de volgende paragrafen voor een langere beschrijving, of om categorierichtlijnen of regels vast te stellen:\n\n- Waarom zouden mensen deze categorie gebruiken? Waar dient het voor?\n\n- Op welke punten onderscheid het zich van andere categorieën die we al hebben?\n\n- Wat moet topics in deze categorie over het algemeen bevatten?\n\n- Hebben we deze categorie nodig? Kunnen we het samenvoegen met een andere categorie of subcategorie?\n" errors: uncategorized_parent: "Ongecategoriseerd kan geen bovenliggende categorie hebben" @@ -351,24 +361,24 @@ nl: title: "leider" change_failed_explanation: "Je probeerde %{user_name} te degraderen naar '%{new_trust_level}'. Echter, het trustlevel is al '%{current_trust_level}'. %{user_name} blijft op trust level '%{current_trust_level}'. Als je de gebruiker wil degraderen, zet het trustlevel dan eerst vast." rate_limiter: - slow_down: "je hebt deze actie te vaak uitgevoerd, probeer het later nog eens." + slow_down: "U hebt deze actie te vaak uitgevoerd; probeer het later opnieuw." too_many_requests: "Er is een dagelijks limiet voor hoe vaak je dat kan doen. Wacht %{time_left} voordat je dit opnieuw probeert." by_type: - first_day_replies_per_day: "Je hebt het maximum aantal reacties dat een nieuwe gebruiker op hun eerste dag kan creëren bereikt. Wacht %{time_left} voor je het opnieuw probeert ." - first_day_topics_per_day: "Je hebt het maximum aantal topics dat een nieuwe gebruiker op hun eerste dag kan creëren bereikt. Wacht %{time_left} voordat je het opnieuw probeert." + first_day_replies_per_day: "U hebt het maximale aantal antwoorden dat een nieuwe gebruiker op de eerste dag kan plaatsen bereikt. Wacht %{time_left} voordat u het opnieuw probeert." + first_day_topics_per_day: "U hebt het maximale aantal topics dat een nieuwe gebruiker op de eerste dag kan plaatsen bereikt. Wacht %{time_left} voordat u het opnieuw probeert." create_topic: "Je maakt te snel topics aan. Wacht %{time_left} voordat je het opnieuw probeert. " create_post: "Je reageert te snel. Wacht %{time_left} voordat je het opnieuw probeert. " delete_post: "Je verwijdert berichten te snel. Wacht %{time_left} voor je het opnieuw probeert." - topics_per_day: "Je hebt het maximum aantal nieuwe topics bereikt voor vandaag. Wacht %{time_left} voordat je het opnieuw probeert. " - pms_per_day: "Je hebt het maximum aantal berichten bereikt voor vandaag. Wacht a.u.b. %{time_left} voordat je het opnieuw probeert." - create_like: "Je hebt het maximum aantal likes voor vandaag bereikt. Wacht aub %{time_left} voordat je het opnieuw probeert." - create_bookmark: "Je hebt het maximum aantal bladwijzers voor vandaag bereikt. Wacht aub %{time_left} voordat je het opnieuw probeert." - edit_post: "Je hebt het maximum aantal bewerkingen voor vandaag bereikt. Wacht aub %{time_left} voordat je het opnieuw probeert." - unsubscribe_via_email: "Je hebt het maximum aantal uitschrijvingen voor vandaag bereikt. Wacht aub %{time_left} voordat je het opnieuw probeert." - topic_invitations_per_day: "Je hebt het maximum aantal topic uitnodigingen bereikt voor vandaag. Wacht aub %{time_left} voordat je het opnieuw probeert." + topics_per_day: "U hebt het maximale aantal nieuwe topics voor vandaag bereikt. Wacht %{time_left} voordat u het opnieuw probeert." + pms_per_day: "U hebt het maximale aantal berichten voor vandaag bereikt. Wacht %{time_left} voordat u het opnieuw probeert." + create_like: "U hebt het maximale aantal likes voor vandaag bereikt. Wacht %{time_left} voordat u het opnieuw probeert." + create_bookmark: "U hebt het maximale aantal bladwijzers voor vandaag bereikt. Wacht %{time_left} voordat u het opnieuw probeert." + edit_post: "U hebt het maximale aantal bewerkingen voor vandaag bereikt. Wacht %{time_left} voordat u het opnieuw probeert." + unsubscribe_via_email: "U hebt het maximale aantal uitschrijvingen via e-mail voor vandaag bereikt. Wacht %{time_left} voordat u het opnieuw probeert." + topic_invitations_per_day: "U hebt het maximale aantal topicuitnodigingen voor vandaag bereikt. Wacht %{time_left} voordat u het opnieuw probeert." hours: one: "1 uur" - other: "%{count} uren" + other: "%{count} uur" minutes: one: "1 minuut" other: "%{count} minuten" @@ -427,7 +437,7 @@ nl: other: "%{count} minuten geleden" about_x_hours: one: "1 uur geleden" - other: "%{count} uren geleden" + other: "%{count} uur geleden" x_days: one: "1 dag geleden" other: "%{count} dagen geleden" @@ -442,12 +452,12 @@ nl: other: "ongeveer %{count} jaar geleden" over_x_years: one: "meer dan 1 jaar geleden" - other: "meer dan %{count} jaren geleden" + other: "meer dan %{count} jaar geleden" almost_x_years: one: "bijna 1 jaar geleden" - other: "bijna %{count} jaren geleden" + other: "bijna %{count} jaar geleden" password_reset: - no_token: "Sorry, die link voor het wijzigen van je wachtwoord is te oud. Selecteer de Inloggen knop en kies 'Ik ben mijn wachtwoord vergeten' om een nieuwe link te krijgen." + no_token: "Sorry, die koppeling voor het wijzigen van uw wachtwoord is te oud. Selecteer de knop Aanmelden en gebruik 'Ik ben mijn wachtwoord vergeten' om een nieuwe koppeling te ontvangen." update: 'Wijzig wachtwoord' save: 'Bewaar wachtwoord' title: 'Herstel wachtwoord' @@ -470,6 +480,7 @@ nl: welcome_to: "Welkom bij %{site_name}!" approval_required: "Een moderator moet je nieuwe account handmatig activeren voordat je toegang krijgt tot dit forum. Je krijgt een e-mail van ons wanneer je account is goedgekeurd!" missing_session: "We kunnen niet vaststellen of je account is aangemaakt, wees er alsjeblieft zeker van dat je cookies accepteert." + activated: "Sorry, deze account is al geactiveerd." post_action_types: off_topic: title: 'Off-topic' @@ -512,6 +523,10 @@ nl: user_activity: no_bookmarks: self: "Je hebt geen favoriete berichten, als favoriet gemarkeerde berichten kun je later makkelijk terugvinden." + others: "Geen bladwijzers." + no_likes_given: + self: "U hebt geen berichten geliket." + others: "Geen gelikete berichten." topic_flag_types: spam: title: 'Spam' @@ -542,7 +557,13 @@ nl: title: "Afgemeld!" unsubscribe: title: "Afmelden" - log_out: "Uitloggen" + mailing_list_mode: "Mailinglijstmodus uitschakelen" + log_out: "Afmelden" + user_api_key: + title: "Toegang tot toepassingen autoriseren" + authorize: "Autoriseren" + read: "lezen" + read_write: "lezen/schrijven" reports: visits: title: "Bezoeken" @@ -689,12 +710,12 @@ nl: gc_warning: 'Je server gebruikt de standaard ruby garbage collection instellingen, en daarmee krijg je niet de beste prestaties. Lees deze topic over instellingen voor prestaties: Tuning Ruby and Rails for Discourse.' sidekiq_warning: 'Sidekiq draait niet. Veel taken, zoals het versturen van e-mails, worden asynchroon uitgevoerd door sidekiq. Zorg ervoor dat er altijd een sidekiq process draait. Hier is meer informatie over sidekiq.' queue_size_warning: 'Het aantal taken in de wachtrij %{queue_size} is hoog. Dit kan duiden op problemen met het Sidekiq proces. Of je moet meer Sidekiq workers toevoegen.' - memory_warning: 'Jouw server draait met minder dan 1 GB aan geheugen. Ten minste 1 GB geheugen is aanbevolen.' + memory_warning: 'Uw server werkt met minder dan 1 GB aan totaal geheugen. Minstens 1 GB geheugen wordt aanbevolen.' google_oauth2_config_warning: 'De server is geconfigureerd om aanmelden en inloggen via Google OAuth2 (enable_google_oauth2_logins) toe te staan, maar de client id en client secret values zijn niet ingesteld. Ga naar de Site Instellingen en stel deze in. Bekijk deze gids voor meer informatie.' facebook_config_warning: 'De server is geconfigureerd om registratie en inloggen via Facebook mogelijk te maken (enable_facebook_logins), maar er zijn geen app id en app secret waarden opgegeven. Ga naar de Instellingen en vul de waarden in. Zie deze uitleg voor meer informatie.' twitter_config_warning: 'De server is geconfigureerd om registratie en inloggen via Twitter mogelijk te maken (enable_twitter_logins), maar er zijn geen key en secret waarden opgegeven. Ga naar de Instellingen en vul de waarden in. Zie deze uitleg voor meer informatie.' github_config_warning: 'De server is geconfigureerd om registratie en inloggen via Github mogelijk te maken (enable_github_logins), maar er zijn geen client id en secret waarden opgegeven. Ga naar de Instellingen en vul de waarden in. Zie deze uitleg voor meer informatie.' - image_magick_warning: 'De server is geconfigureerd om thumbnails te maken van grote afbeeldingen, maar ImageMagick is niet geïnstalleerd. Installeer ImageMagick met je favoriete package manager of download de laatste release.' + image_magick_warning: 'De server is geconfigureerd om miniaturen van grote afbeeldingen te maken, maar ImageMagick is niet geïnstalleerd. Installeer ImageMagick met uw favoriete pakketbeheerder, of download de nieuwste versie.' failing_emails_warning: 'Er zijn %{num_failed_jobs} e-mail jobs mislukt. Controleer in app.yml of de e-mailserver instelling correct zijn. Toon de mislukte jobs in Sidekiq.' subfolder_ends_in_slash: "Je submap setup is onjuist; de DISCOURSE_RELATIVE_URL_ROOT eindigt in een schuine streep." site_settings: @@ -705,9 +726,9 @@ nl: min_post_length: "Minimum lengte van een bericht in tekens" min_first_post_length: "Minimale toegestane lengte voor het eerste bericht (topic body) in tekens" min_private_message_post_length: "Minimale toegestane lengte in tekens voor berichten" - max_post_length: "Maximum lengte van een bericht in tekens" + max_post_length: "Maximaal toegestane lengte van een bericht in tekens" min_topic_title_length: "Minimum lengte van een topictitel" - max_topic_title_length: "Maximum lengte van een topictitel" + max_topic_title_length: "Maximaal toegestane lengte van een topictitel in tekens" min_private_message_title_length: "Minimale toegestane titel lengte in tekens voor berichten" min_search_term_length: "Minimum lengte van een zoekterm in tekens" allow_uncategorized_topics: "Topics zonder categorie toestaan. WAARSCHUWING: Alle topics moet weer aan een categorie zijn toegekend voor dit wordt uitgezet." @@ -771,7 +792,7 @@ nl: enable_noscript_support: "Ondersteun <noscript> tag" allow_moderators_to_create_categories: "Moderators mogen nieuwe categorieën maken" cors_origins: "Toegestane domeinen voor ´cross-origin requests´ (CORS). Elk domein moet http:// of https:// bevatten. De DISCOURSE_ENABLE_CORS omgevingsvariabele moet staan ingesteld op ´WAAR´ om CORS te kunnen gebruiken." - use_admin_ip_whitelist: "Admins kunnen alleen inloggen vanaf een IP-adres dat is gedefinieerd in de gescreende IP-lijst (Beheer > Logs > Gescreende IP's)" + use_admin_ip_whitelist: "Beheerders kunnen zich alleen aanmelden vanaf een IP-adres dat in de lijst Gecontroleerde IP-nummers is gedefinieerd (Beheer > Logboeken > Gecontroleerde IP-adressen)." top_menu: "Bepaal de volgorde en selectie van items in het hoofdmenu. Bijvoorbeeld latest|new|unread|categories|top|read|posted|bookmarks" post_menu: "De volgorde en selectie van items in het berichtmenu. Bijvoorbeeld like|edit|flag|delete|share|bookmark|reply" post_menu_hidden_items: "De menu-items die standaard verborgen moeten worden in het post menu totdat er op de uitbreidings-ellips is geklikt." @@ -793,7 +814,7 @@ nl: allow_index_in_robots_txt: "Specificeer in robots.txt dat de site geïndexeerd mag worden door zoekmachines." email_domains_blacklist: "Een lijst van e-maildomeinen gescheiden door een vertikaal streepje (pipe), die niet worden toegestaan. Voorbeeld: mailingen.com|trashmail.net" email_domains_whitelist: "Een lijst van e-maildomeinen gescheiden door een vertikaal streepje (pipe), die zijn voorgeschreven om te worden toegelaten. WAARSCHUWING: Gebruikers met andere e-maildomeinen dan opgenomen in de lijst worden NIET toegelaten." - log_out_strict: "Sluit bij het uitloggen ALLE sessies voor de gebruiker op alle apparaten." + log_out_strict: "Bij het afmelden ALLE sessies voor de gebruiker op alle apparaten afmelden" version_checks: "Ping de Discourse-Hub voor updates en laat meldingen van nieuwe versies zien op het dashboard van de beheerder." new_version_emails: "Stuur een email naar het contact_email adres wanneer een nieuwe versie van Discourse beschikbaar is." port: "DEVELOPER ONLY! WARNING! Mocht je een specifieke poort willen toewijzen aan de URL. Handig in ontwikkelaars-modus. Laat leeg voor geen toewijzing." @@ -817,22 +838,22 @@ nl: enable_local_logins: "Accounts op basis van een lokale gebruikersnaam en wachtwoord toestaan. (Let op: dit moet aan staan voor toegang op basis van een uitnodiging.)" allow_new_registrations: "Nieuwe gebruikers registreren toestaan. Uitschakelen om te voorkomen dat iedereen een nieuw account kan maken." enable_signup_cta: "Toon een notificatie aan terugkerende anonieme gebruikers waarin gevraagd wordt zich aan te melden voor een account." - enable_yahoo_logins: "Zet inloggen met Yahoo! aan" + enable_yahoo_logins: "Yahoo-authenticatie inschakelen" enable_google_oauth2_logins: "Google Oauth2 authenticatie toestaan. Dit is de authenticatiemethode die momenteel door Google wordt ondersteund. Vereist key en secret." google_oauth2_client_id: "Client ID van je Google applicatie." google_oauth2_client_secret: "Client secret van je Google applicatie." - enable_twitter_logins: "Zet inloggen met Twitter aan. Hiervoor heb je een twitter_consumer_key en twitter_consumer_secret nodig." + enable_twitter_logins: "Twitter-authenticatie inschakelen; vereist twitter_consumer_key en twitter_consumer_secret." twitter_consumer_key: "consumer_key (registreer op dev.twitter.com)" twitter_consumer_secret: "consumer secret (registreer op dev.twitter.com)" - enable_instagram_logins: "Zet inloggen met Instagram aan. Hiervoor heb je een instagram_consumer_key and instagram_consumer_secret nodig" - enable_facebook_logins: "Zet inloggen met Facebook aan. Hiervoor heb je een facebook_app_id en facebook_app_secret nodig." + enable_instagram_logins: "Instagram-authenticatie inschakelen; vereist instagram_consumer_key en instagram_consumer_secret." + enable_facebook_logins: "Facebook-authenticatie inschakelen; vereist facebook_app_id en facebook_app_secret." facebook_app_id: "app_id (registreer op https://developers.facebook.com/apps)" facebook_app_secret: "app_secret (registreer op https://developers.facebook.com/apps)" - enable_github_logins: "Zet inloggen met Github aan. Hiervoor heb je een github_client_id en github_client_secret nodig." + enable_github_logins: "Github-authenticatie inschakelen; vereist github_client_id en github_client_secret." github_client_id: "github_client_id (registreer op https://github.com/settings/applications)" github_client_secret: "github_client_secret (registreer op https://github.com/settings/applications)" allow_restore: "Herstellen van data toestaan, waarbij ALLE site-data wordt overschreven! Laat op 'false' staan, tenzij je een back-up terug wil zetten." - maximum_backups: "Het maximum aantal backups om te bewaren. Oudere backups worden automatisch verwijderd." + maximum_backups: "Het maximale aantal back-ups om op schijf te bewaren. Oudere back-ups worden automatisch verwijderd." automatic_backups_enabled: "Automatische back-ups uitvoeren volgens de opgegeven back-up frequentie." backup_frequency: "Hoe vaak we een back-up van de site maken, in dagen." enable_s3_backups: "Upload voltooide back-ups naar S3. LET OP: Zorg ervoor dat je je S3 inloggegevens hebt ingevuld in de Bestanden instellingen." @@ -846,14 +867,16 @@ nl: rate_limit_create_post: "Na het plaatsen van een bericht moeten gebruikers (n) seconden wachten voor ze een ander bericht kunnen plaatsen." rate_limit_new_user_create_topic: "Na het maken van een topic moeten nieuwe gebruikers (n) seconden wachten voor ze een andere topic kunnen maken." rate_limit_new_user_create_post: "Na het plaatsen van een bericht moeten nieuwe gebruikers (n) seconden wachten voor ze een ander bericht kunnen plaatsen." - max_likes_per_day: "Het maximum aantal likes per gebruiker per dag." - max_flags_per_day: "Het maximum aantal markeringen per gebruiker per dag." - max_bookmarks_per_day: "Het maximum aantal favoriet aanduidingen per gebruiker per dag." - max_edits_per_day: "Het maximum aantal bewerkingen per gebruiker per dag." - max_topics_per_day: "Het maximum aantal topics dat een gebruiker per dag kan maken." - max_private_messages_per_day: "Het maximum aantal berichten dat een gebruiker per dag kan maken." - max_invites_per_day: "Het maximum aantal uitnodigingen dat een gebruiker per dag kan versturen." - max_topic_invitations_per_day: "Het maximum aantal uitnodigingen voor een topic dat een gebruiker per dag kan sturen." + max_likes_per_day: "Maximale aantal likes per gebruiker per dag." + max_flags_per_day: "Maximale aantal markeringen per gebruiker per dag." + max_bookmarks_per_day: "Maximale aantal bladwijzers per gebruiker per dag." + max_edits_per_day: "Maximale aantal bewerkingen per gebruiker per dag." + max_topics_per_day: "Maximale aantal topics dat een gebruiker per dag kan plaatsen." + max_private_messages_per_day: "Maximale aantal berichten dat een gebruiker per dag kan plaatsen." + max_invites_per_day: "Maximale aantal uitnodigingen dat een gebruiker per dag kan versturen." + max_topic_invitations_per_day: "Maximale aantal uitnodigingen voor een topic dat een gebruiker per dag kan versturen." + max_logins_per_ip_per_hour: "Maximale aantal toegestane aanmeldingen per IP-adres per uur" + max_logins_per_ip_per_minute: "Maximale aantal toegestane aanmeldingen per IP-adres per minuut" alert_admins_if_errors_per_minute: "Aantal foutmeldingen per minuut waarbij de beheerder een melding krijgt. Een waarde van 0 schakelt deze mogelijkheid uit. LET OP: herstart vereist." alert_admins_if_errors_per_hour: "Aantal foutmeldingen per uur waarbij de beheerder een melding krijgt. Een waarde van 0 schakelt deze mogelijkheid uit. LET OP: herstart vereist." suggested_topics: "Aantal aanbevolen topics onderaan een topic." @@ -888,6 +911,7 @@ nl: tl3_requires_topics_viewed_all_time: "Het minimum totaal aantal topics dat een lid moet hebben bekeken om te kwalificeren voor trustlevel 3." tl3_requires_posts_read_all_time: "Het minimum totaal aantal berichten dat een lid moet hebben bekeken om te kwalificeren voor trustlevel 3." tl3_promotion_min_duration: "Het minimum aantal dagen van de duur van een promotie naar trustlevel 3 voordat een lid kan worden gedegradeerd naar trustlevel 2." + tl3_requires_likes_given: "Het minimale aantal likes dat in de afgelopen (tl3-tijdsperiode) dagen moet worden gegeven om voor promotie naar vertrouwensniveau 3 in aanmerking te komen." tl3_links_no_follow: "rel=nofollow niet verwijderen van links geplaatst door leden met trustlevel 3." min_trust_to_create_topic: "Het minimale trust level dat nodig is om een topic te mogen maken." min_trust_to_edit_wiki_post: "Het minimale trust level dat nodig is om een bericht te wijzigen dat als wiki gemarkeerd is." @@ -895,16 +919,16 @@ nl: newuser_max_links: "Hoeveel links een nieuw lid in een bericht kan plaatsen." newuser_max_images: "Hoeveel afbeeldingen een nieuw lid in een bericht kan plaatsen." newuser_max_attachments: "Hoeveel bestanden een nieuw lid in een bericht kan plaatsen." - newuser_max_mentions_per_post: "Het maximum aantal @naam notificaties dat een nieuw lid kan gebruiken in een bericht. " - newuser_max_replies_per_topic: "Het maximum aantal reacties dat een nieuw lid kan maken in een enkel topic totdat iemand terug reageert." - max_mentions_per_post: "Het maximum aantal @naam notificaties iedereen kan gebruiken in een bericht." + newuser_max_mentions_per_post: "Maximale aantal @naam-vermeldingen dat een nieuwe gebruiker in een bericht kan gebruiken." + newuser_max_replies_per_topic: "Maximale aantal antwoorden dat een nieuwe gebruiker in één topic kan plaatsen totdat iemand ze beantwoordt." + max_mentions_per_post: "Maximale aantal @naam-vermeldingen dat iedereen in een bericht kan gebruiken." create_thumbnails: "Maak miniaturen en lightbox afbeeldingen die te groot zijn en niet in een post passen." email_time_window_mins: "Wacht (n) minuten met verzenden van notificaties, geef gebruikers de kans om hun berichten te bewerken en af te ronden." email_posts_context: "Hoeveel voorgaande antwoorden bijvoegen als context in de notificatie e-mails." flush_timings_secs: "Hoe frequent we de timing data naar de server sturen, in seconden. " - title_max_word_length: "De maximum toegestane woordlengte, in letters, in een topic titel." - title_min_entropy: "De minimum entropie (unieke karakters, niet-Engels telt zwaarder) vereist voor een topic titel." - body_min_entropy: "De minimum entropie (unieke karakters, niet-Engels telt zwaarder) vereist voor de inhoud van een bericht." + title_max_word_length: "De maximaal toegestane woordlengte, in tekens, in een topictitel." + title_min_entropy: "De minimale entropie (unieke tekens, niet-Engels telt zwaarder) die voor een topictitel is vereist." + body_min_entropy: "De minimale entropie (unieke tekens, niet-Engels telt zwaarder) die voor de hoofdtekst van een bericht is vereist." allow_uppercase_posts: "Sta alleen hoofdletters toe in een topic titel of bericht inhoud." title_fancy_entities: "Converteer algemene ASCII-tekens naar fancy HTML in topictitels, zoals SmartyPants (http://daringfireball.net/projects/smartypants)" min_title_similar_length: "De minimale lengte die een titel van een topic moet hebben voordat er wordt gezocht naar vergelijkbare topics." @@ -935,7 +959,7 @@ nl: staff_like_weight: "Hoeveel zwaarder de weegfactor moet zijn voor likes gegeven door staf." topic_view_duration_hours: "Tel een nieuw topic bekeken één keer per IP/Gebruiker elke N uur." user_profile_view_duration_hours: "Tel een nieuw gebruikersprofiel bekeken één keer per IP/Gebruiker elke N uur." - levenshtein_distance_spammer_emails: "Bij het matchen van spammer e-mails , het aantal verschillende karakters waarbij nog steeds een fuzzy match kan bestaan." + levenshtein_distance_spammer_emails: "Bij het vergelijken van spam-e-mails, het aantal verschillende tekens waarbij nog steeds een wazige overeenkomst kan bestaan." max_new_accounts_per_registration_ip: "Als er al (n) accounts met trustlevel 0 zijn van een bepaald IP-adres (en geen daarvan is staflid of heeft een trustlevel 2 of hoger), stop met het accepteren van nieuwe aanmeldingen van dat IP-adres." min_ban_entries_for_roll_up: "Bij het klikken op de Roll up knop, maak een nieuwe subnet ban boeking aan als er tenminste (N) boekingen zijn." max_age_unmatched_emails: "Verwijder niet-gekoppelde gecontroleerde e-mail boekingen na (N) dagen." @@ -945,7 +969,7 @@ nl: auto_respond_to_flag_actions: "Automatisch antwoord Inschakelen op moment van weggooien van een markering." min_first_post_typing_time: "Minimum tijd in milliseconden dat een gebruiker moet typen tijdens een eerste post, als de drempelwaarde niet wordt bereikt zal de post automatisch in de wachtrij voor goedkeuring gezet worden. Zet op 0 om uit te schakelen (niet aanbevolen)" auto_block_fast_typers_on_first_post: "Blokkeer gebruikers automatisch als ze niet voldoen aan min_first_post_typing_time" - auto_block_fast_typers_max_trust_level: "Maximum vertrouwensniveau om snelle typers automatisch te blokkeren " + auto_block_fast_typers_max_trust_level: "Maximale vertrouwensniveau om snelle typers automatisch te blokkeren " auto_block_first_post_regex: "Hoofdlettergevoelige regex die, indien een resultaat gevonden, de eerste post van een gebruiker zal blokkeren en in de wachtirj voor goedkeuring zal zetten. Bijvoorbeeld: raging|a[bc]a , zal alle posts die raging of aba of aca bevatten blokkeren. Geldt alleen voor eerste posts." reply_by_email_enabled: "Mogelijk inschakelen om te antwoorden per e-mail." reply_by_email_address: "Template voor antwoorden per e-mail, bijvoorbeeld: %{reply_key}@reageer.mijnforum.nl" @@ -954,7 +978,7 @@ nl: short_email_length: "Korte e-mail lengte in Bytes" display_name_on_email_from: "Toon de volledige naam in het afzenderveld van e-mails." enable_staged_users: "Maak automatisch staged gebruikers aan bij het verwerken van inkomende e-mails." - maximum_staged_users_per_email: "Het maximum aantal staged gebruikers dat bij het verwerken van een inkomende e-mail wordt aangemaakt, is bereikt." + maximum_staged_users_per_email: "Maximale aantal staged gebruikers dat bij het verwerken van een inkomende e-mail wordt aangemaakt." pop3_polling_enabled: "Poll via POP3 voor antwoorden per e-mail." pop3_polling_ssl: "Gebruik SSL bij de verbinding naar de POP3 server. (Aanbevolen)" pop3_polling_period_mins: "De periode in minuten tussen controleren van het POP3 account voor e-mail. LET OP: vereist een herstart." @@ -966,7 +990,7 @@ nl: email_in: "Sta toe dat gebruikers een nieuw topic via e-mail (vereist het pollen van pop3). Configureer het adres in de \"Instellingen\" tabblad van elke categorie." email_in_min_trust: "Het minium trustlevel dat een gebruiker moet hebben om nieuwe topics te kunnen mailen." email_prefix: "Het [label] gebruikt in het onderwerp van e-mails. Als standaard wordt 'titel' gebruikt als niet gezet." - email_site_title: "De titel van de website, wordt gebruikt als de naam van de afzender van e-mails van de website. Als standaard wordt 'titel' gebruikt als niets is ingesteld. Gebruik deze instelling als uw 'titel' karakters bevat die niet zijn toegestaan in een e-mail afzender tekst." + email_site_title: "De titel van de website die als de afzender van e-mails van de website wordt gebruikt. Standaard wordt 'titel' gebruikt als niets is ingesteld. Gebruik deze instelling als uw 'titel' tekens bevat die niet in tekenreeksen van e-mailafzenders zijn toegestaan." minimum_topics_similar: "Hoeveel topics moeten er aanwezig zijn voordat er vergelijkbare topics worden voorgesteld bij het opstellen van nieuwe topics." relative_date_duration: "Na hoeveel dagen moet een post datum niet meer worden getoond als relatieve datum (7d) maar als absolute datum (20 feb)." delete_user_max_post_age: "Gebruikers wiens eerste bericht ouder dan (x) dagen is kunnen niet meer verwijderd worden." @@ -995,6 +1019,7 @@ nl: global_notice: "Laat een LET OP, BELANGRIJK-banner zien aan alle gebruikers. Laat leeg om niet te tonen (HTML is toegestaan)." disable_edit_notifications: "Schakelt bewerkingsnotificaties van de systeemgebruiker uit als 'download_remote_images_to_local' actief is." automatically_unpin_topics: "Automatisch ont-pinnen van topics als de gebruiker onderaan de pagina komt." + topic_page_title_includes_category: "Paginatitel van topic bevat de categorienaam." full_name_required: "Volledige naam is een verplicht veld van het gebruikersprofiel." enable_names: "Toon de volledige naam van de gebruiker op hun profiel, gebruikerskaart en e-mails. Scahkel uit om volledige naam overal te verbergen." display_name_on_posts: "Laat de volledige naam van een gebruiker bij zijn berichten zien, na de @gebruikersnaam" @@ -1009,7 +1034,7 @@ nl: embed_by_username: "Discourse gebruikersnaam van de gebruiker die de ingesloten topics aanmaakt." embed_username_key_from_feed: "Sleutel waarmee de discourse gebruikersnaam uit de feed kan worden gehaald." embed_truncate: "Kort de geembedde berichten in" - embed_post_limit: "Maximum aantal in te sluiten posts." + embed_post_limit: "Maximale aantal te embedden berichten." embed_username_required: "De gebruikersnaam om topics aan te maken is vereist." embed_whitelist_selector: "CSS-selector voor de elementen die zijn toegestaan in invoegberichten." embed_blacklist_selector: "CSS-selector voor de elementen die zijn verwijderd uit invoegberichten." @@ -1019,7 +1044,7 @@ nl: prevent_anons_from_downloading_files: "Voorkom dat anonieme gebruikers bijlagen mogen downloaden. WAARSCHUWING: hierdoor zullen website onderdelen, anders dan afbeeldingen, die zijn gepost als bijlage niet langer werken." slug_generation_method: "Kies een slug generate methode. 'encoded' zal een percentage encoderen string genereren. 'none' zal slug helemaal uitschakelen." enable_emoji: "Inschakelen emoji" - emoji_set: "Hoe wil je jouw emoji hebben?" + emoji_set: "Welke emoji wilt u gebruiken?" enforce_square_emoji: "Forceer een vierkant aspect ratio bij alle emojis." approve_post_count: "Het aantal berichten van een nieuwe of normale gebruiker dat moet worden goedgekeurd" approve_unless_trust_level: "Posts voor gebruikers onder dit vertrouwensniveau moeten worden goedgekeurd" @@ -1046,7 +1071,7 @@ nl: invalid_integer_max: "Waarde kan maximaal %{max} zijn." invalid_integer: "Waarde moet een integer zijn." regex_mismatch: "Waarde voldoet niet aan het vereiste formaat." - must_include_latest: "Top menu moet 'nieuwste' tabblad bevatten." + must_include_latest: "Topmenu moet het tabblad 'nieuwste' bevatten." invalid_string: "Ongeldige waarde." invalid_string_min_max: "Moet tussen %{min} en %{max} tekens zijn." invalid_string_min: "Moet te minste uit %{min} tekens bestaan." @@ -1063,8 +1088,8 @@ nl: most_recent_poster: "Meest recente schrijver" frequent_poster: "Frequente schrijver" redirected_to_top_reasons: - new_user: "Welkom bij deze community! Dit zijn een aantal van de meest populaire topics." - not_seen_in_a_month: "Welkom terug! We hebben je een tijdje niet gezien. Dit is een overzicht van de meest populaire topics die zijn gemaakt tijdens je afwezigheid." + new_user: "Welkom bij onze gemeenschap! Dit zijn de meest populaire recente topics." + not_seen_in_a_month: "Welkom terug! We hebben u een tijdje niet gezien. Dit zijn de meest populaire topics sinds uw afwezigheid." move_posts: new_topic_moderator_post: one: "Een bericht is gesplitst naar een nieuw topic: %{topic_link}" @@ -1088,8 +1113,8 @@ nl: one: "Dit topic is automatisch na één dag gesloten. Reageren is niet meer mogelijk." other: "Dit topic is automatisch na %{count} dagen gesloten. Reageren is niet meer mogelijk." autoclosed_enabled_hours: - one: "Dit topic is automatisch na één uur gesloten. Reageren is niet meer mogelijk." - other: "Dit topic is automatisch na %{count} uren gesloten. Reageren is niet meer mogelijk." + one: "Dit topic is na 1 uur automatisch gesloten. Nieuwe antwoorden zijn niet meer toegestaan." + other: "Dit topic is na %{count} uur automatisch gesloten. Nieuwe antwoorden zijn niet meer toegestaan." autoclosed_enabled_minutes: one: "Dit topic is automatisch na één minuut gesloten. Reageren is niet meer mogelijk." other: "Dit topic is automatisch na %{count} minuten gesloten. Reageren is niet meer mogelijk." @@ -1097,8 +1122,8 @@ nl: one: "Dit topic is automatisch gesloten één dag na het laatste antwoord. Reageren is niet meer mogelijk." other: "Dit topic is automatisch gesloten %{count} dagen na het laatste antwoord. Reageren is niet meer mogelijk." autoclosed_enabled_lastpost_hours: - one: "Dit topic is automatisch gesloten één uur na het laatste antwoord. Reageren is niet meer mogelijk." - other: "Dit topic is automatisch gesloten %{count} uren na het laatste antwoord. Reageren is niet meer mogelijk." + one: "Dit topic is 1 uur na het laatste antwoord automatisch gesloten. Nieuwe antwoorden zijn niet meer toegestaan." + other: "Dit topic is %{count} uur na het laatste antwoord automatisch gesloten. Nieuwe antwoorden zijn niet meer toegestaan." autoclosed_enabled_lastpost_minutes: one: "Dit topic is automatisch gesloten één minuut na het laatste antwoord. Reageren is niet meer mogelijk." other: "Dit topic is automatisch gesloten %{count} minuten na het laatste antwoord. Reageren is niet meer mogelijk." @@ -1116,16 +1141,16 @@ nl: wait_approval: "Bedankt voor je inschrijving. We zullen je laten weten als je account is goedgekeurd." active: "Je account is actief en klaar voor gebruik!" activate_email: "

    Je bent er bijna! We hebben een activatiemail verstuurd naar %{email}. Volg de instructies in de mail om je account te activeren.

    Als de mail niet aankomt, check je spam folder, of probeer opnieuw aan te melden om een nieuwe activatiemail te versturen.

    " - not_activated: "Je kan nog niet inloggen. We hebben je een activatiemail gestuurd. Volg de instructies in de mail om je account te activeren." - not_allowed_from_ip_address: "Je kan niet inloggen als %{username} vanaf dat IP-adres." - admin_not_allowed_from_ip_address: "Je kan niet inloggen als admin vanaf dat IP-adres." - suspended: "Je kan tot %{date} niet inloggen." + not_activated: "U kunt zich nog niet aanmelden. We hebben u een activeringsmail gestuurd. Volg de instructies in het e-mailbericht om uw account te activeren." + not_allowed_from_ip_address: "U kunt zich niet als %{username} aanmelden vanaf dat IP-adres." + admin_not_allowed_from_ip_address: "U kunt zich niet als beheerder aanmelden vanaf dat IP-adres." + suspended: "U kunt zich tot %{date} niet aanmelden." suspended_with_reason: "Account geschorst tot %{date}: %{reason}" errors: "%{errors}" not_available: "Niet beschikbaar. Probeer %{suggestion}?" something_already_taken: "Er ging iets mis, misschien zijn de gebruikersnaam en/of e-mailadres al in gebruik? Gebruik dan de 'wachtwoord vergeten' link" omniauth_error: "Sorry, er is iets mis gegaan met de bevestiging van je account. Misschien heb je de bevestiging niet geaccepteerd?" - omniauth_error_unknown: "Er is iets misgegaan bij het inloggen. Probeer het opnieuw." + omniauth_error_unknown: "Er is iets misgegaan bij het verwerken van uw aanmelding. Probeer het opnieuw." new_registrations_disabled: "Het registeren van nieuwe accounts is niet toegestaan op dit moment." password_too_long: "Wachtwoorden mogen maximaal 200 tekens lang zijn." email_too_long: "De e-mail die je hebt opgegeven is te lang. Mailbox namen mogen niet langer zijn dan 254 tekens, en domeinnamen niet langer dan 253 tekens." @@ -1142,27 +1167,18 @@ nl: blank: "mag niet leeg zijn" must_begin_with_alphanumeric_or_underscore: "moet beginnen met een letter, een nummer of een laag streepje" must_end_with_alphanumeric: "moet eindigen op een letter of een nummer" - must_not_contain_two_special_chars_in_seq: "mag niet 2 of meer opvolgende speciale karakters bevatten (.-_)" + must_not_contain_two_special_chars_in_seq: "mag geen 2 of meer opeenvolgende speciale tekens bevatten (.-_)" must_not_end_with_confusing_suffix: "mag niet eindigen op een verwarrend achtervoegsel zoals .json, .png etc." email: not_allowed: "is niet toegestaan vanaf die e-mailprovider. Gebruik een ander e-mailadres." blocked: "is niet toegestaan." ip_address: - blocked: "Nieuwe registraties vanaf jouw IP-adres zijn niet toegestaan." - max_new_accounts_per_registration_ip: "Nieuwe registraties vanaf jouw IP-adres zijn niet toegestaan (maximum limiet bereikt). Neem contact op met een staflid." + blocked: "Nieuwe registraties zijn niet toegestaan vanaf uw IP-adres." + max_new_accounts_per_registration_ip: "Nieuwe registraties vanaf uw IP-adres zijn niet toegestaan (maximumlimiet bereikt). Neem contact op met een staflid." flags_reminder: subject_template: one: "Eén vlag af te handelen" other: "%{count} vlaggen af te handelen" - unsubscribe_mailer: - text_body_template: | - Iemand (jij misschien?) heeft verzocht om op dit adres niet langer e-mails met nieuws van %{site_domain_name} te ontvangen. - Klik op de volgende link als je dit wil bevestigen: - - %{confirm_unsubscribe_link} - - - Als je deze e-mails wel wil blijven ontvangen, kan je deze e-mail negeren. invite_mailer: subject_template: "%{invitee_name} nodigt je uit voor '%{topic_title}' op %{site_domain_name}" invite_forum_mailer: @@ -1375,6 +1391,12 @@ nl: subject_template: "[%{site_name}] [PM] %{topic_title}" digest: why: "Een korte samenvatting van %{site_link} sinds we je voor het laatst zagen op %{last_seen_at}." + liked_received: "Ontvangen likes" + new_posts: "Nieuwe berichten" + new_users: "Nieuwe gebruikers" + popular_topics: "Populaire topics" + follow_topic: "Dit topic volgen" + popular_posts: "Populaire berichten" click_here: "klik hier" forgot_password: subject_template: "[%{site_name}] Wachtwoord herstellen" @@ -1460,9 +1482,9 @@ nl: store_failure: "Het opslaan van upload #%{upload_id} voor gebruiker #%{user_id} is mislukt." file_missing: "Sorry, maar je moet een bestand selecteren om te uploaden." attachments: - too_large: "Sorry, het bestand dat je wil uploaden is te groot (maximum grootte is %{max_size_kb}%KB)." + too_large: "Sorry, het bestand dat u probeert te uploaden is te groot (maximumgrootte is %{max_size_kb}%KB)." images: - too_large: "De afbeelding die je wil uploaden is te groot (maximum grootte is %{max_size_kb}%KB). Verklein de afbeelding en probeer het opnieuw." + too_large: "Sorry, de afbeelding die u probeert te uploaden is te groot (maximumgrootte is %{max_size_kb}%KB). Verklein de afbeelding en probeer het opnieuw." size_not_found: "Het is niet gelukt de afmetingen van de afbeelding te bepalen. Misschien is het bestand corrupt?" email_log: no_user: "Kan geen gebruiker met id %{user_id} vinden" @@ -1499,21 +1521,33 @@ nl: admin_login: success: "E-mail verstuurd" error: "Fout!" - email_input: "Beheerder E-mail" + email_input: "E-mailadres van beheerder" submit_button: "E-mail versturen" discourse_hub: access_token_problem: "Licht een admin in: Gelieve de site instellingen bijwerken met de juiste discourse_org_access_key." performance_report: initial_post_raw: Deze topic bevat dagelijkse performancerapporten van je site initial_topic_title: Performancerapportages van de website + finish_installation: + congratulations: "Gefeliciteerd, u hebt Discourse geïnstalleerd!" safe_mode: no_customizations: "Alle website-aanpassingen uitschakelen" only_official: "Niet-officiële plug-ins uitschakelen" no_plugins: "Alle plug-ins uitschakelen" wizard: step: + locale: + title: "Welkom bij uw Discourse!" forum_title: title: "Naam" + contact: + fields: + contact_url: + label: "Webpagina" + corporate: + description: "Deze namen worden in uw Privacybeleid en Servicevoorwaarden ingevoerd, welke bewerkbare topics in de categorie Staf zijn. Als u geen bedrijf hebt, kunt u deze stap nu gerust overslaan." + colors: + title: "Thema" icons: title: "Pictogrammen" fields: @@ -1522,15 +1556,21 @@ nl: apple_touch_icon_url: label: "Groot pictogram" homepage: + description: "Het tonen van de nieuwste topics op uw startpagina wordt aanbevolen, maar als u dat liever hebt, kunt u ook categorieën (groepen of topics) op de startpagina tonen." fields: homepage_style: choices: + latest: + label: "Nieuwste topics" categories: label: "Categorieën" + emoji: + title: "Emoji" invites: + title: "Staf uitnodigen" description: "Je bent bijna klaar! Nodig wat stafleden uit om te helpen met het starten van discussies met interessante topics en berichten om je gemeenschap op te zetten." finished: - title: "Je Discourse staat klaar!" + title: "Uw Discourse is gereed!" description: |

    Als u deze instellingen ooit wilt wijzigen, bezoek dan uw beheersectie; deze vindt u naast het moersleutelpictogram in het websitemenu.

    Veel plezier, en succes met het opbouwen van uw nieuwe gemeenschap!

    diff --git a/config/locales/server.ru.yml b/config/locales/server.ru.yml index 0ec49b1e9b..2f734e6b6a 100644 --- a/config/locales/server.ru.yml +++ b/config/locales/server.ru.yml @@ -210,6 +210,12 @@ ru: latest: "Последние темы" hot: "Популярные темы" top: "Лучшие темы" + top_all: "Обсуждаемые темы за всё время" + top_yearly: "Обуждаемые темы за год" + top_quarterly: "Обсуждаемые темы за квартал" + top_monthly: "Обуждаемые темы за месяц" + top_weekly: "Обсуждаемые темы за неделю" + top_daily: "Обуждаемые темы за день" posts: "Последние сообщения" private_posts: "Последние личные сообщения" group_posts: "Последние сообщения от %{group_name}" @@ -277,6 +283,14 @@ ru: Рассматривали ли вы **[посетить свой профиль пользователя] (%{профиль_дорожка})** и загрузить изображение, которое представляет вас? Это легче следить за ходом обсуждений и найти интересных людей в разговорах, когда каждый человек имеет уникальный профиль картину! + sequential_replies: | + ### Лучше совмещать несколько ответов в один + + Вместо того, чтобы писать и отправлять много отдельных ответов подряд, можно ответить всем по порядку в одном сообщении. Для этого нужно вставлять цитату, затем ответ на нее, затем снова цитату, затем ответ, и т.д. Также, можно упоминать участников диалога через ссылки на @имя. + + Вместо нового ответа, сейчас можно начать редактировать свой предыдущий ответ и просто добавить в него новые цитаты и ответы на них. Для этого нужно выделить требуемый текст и нажать на появившуюся кнопку Цитата. + + Для большинства читатей, намного проще читать темы, в которых длинные ответы и их мало, чем когда много коротеньких ответов. activerecord: attributes: category: diff --git a/config/locales/server.sk.yml b/config/locales/server.sk.yml index 36fded7227..48af670378 100644 --- a/config/locales/server.sk.yml +++ b/config/locales/server.sk.yml @@ -31,8 +31,10 @@ sk: purge_reason: "Automaticky zmazaný ako opustený, dezaktivovaný účet" disable_remote_images_download_reason: "Sťahovanie vzdialených obrázkov je vypnuté kvôli nedostatku diskového priestoru." anonymous: "Anonymný" + remove_posts_deleted_by_author: "Zmazané autorom" emails: incoming: + default_subject: "Táto téma musí mať názov" show_trimmed_content: "Ukázať orezaný obsah" maximum_staged_user_per_email_reached: "Dosiahnutý maximálny počet dočasných používateľov vytvorených emailom." errors: @@ -172,7 +174,7 @@ sk: rss_description: latest: "Najnovšie témy" hot: "Horúce témy" - top: "Najvýznamnejšie témy" + top: "Top témy" posts: "Najnovšie príspevky" private_posts: "Najnovšie súkromné správy" group_posts: "Najnovšie príspevky od %{group_name}" @@ -1608,6 +1610,11 @@ sk: performance_report: initial_post_raw: Táto téma obsahuje denné reporty rýchlosti Vašich stránok. initial_topic_title: Reporty rýchlosti stránok + wizard: + step: + invites: + title: "Pozvite členov" + description: "Už ste takmer hotový(á)! Poďme pozvať nejakých členov, aby pomohli vytvoriť diskusie na zaujímavé témy a svojimi odpoveďami naštartovali komunitu." activemodel: errors: <<: *errors diff --git a/config/locales/server.sq.yml b/config/locales/server.sq.yml index db82f207f1..a6d562cdf0 100644 --- a/config/locales/server.sq.yml +++ b/config/locales/server.sq.yml @@ -32,8 +32,10 @@ sq: purge_reason: "Automatically deleted as abandoned, deactivated account" disable_remote_images_download_reason: "Remote images download was disabled because there wasn't enough disk space available." anonymous: "Anonim" + remove_posts_deleted_by_author: "Fshirë nga autori" emails: incoming: + default_subject: "Duhet të shkruani titullin" show_trimmed_content: "Show trimmed content" maximum_staged_user_per_email_reached: "Reached maximum number of staged users created per email." errors: @@ -57,6 +59,7 @@ sq: exclusion: është i rezervuar invalid: është i pavlefshëm not_a_number: nuk është një numër + record_invalid: 'Verifikimi dështoj: %{errors}' embed: load_from_remote: "Postimi nuk mundi të ngarkohet. Riprovoheni!" site_settings: diff --git a/config/locales/server.zh_TW.yml b/config/locales/server.zh_TW.yml index 9e672ace37..6b6ce242c0 100644 --- a/config/locales/server.zh_TW.yml +++ b/config/locales/server.zh_TW.yml @@ -240,6 +240,40 @@ zh_TW: **[造訪個人檔案](%{profile_path})** 並上傳代表你的頭像吧! 當每個人都有獨特的頭像時,大家能更容易的關注討論內容,以及找到對話中有趣的使用者! + sequential_replies: | + ### 請考慮在單一貼文中回覆多則貼文 + + 與其發好幾篇回應,來回覆各則貼文,不如在同一篇貼文中包含各則貼文的摘錄,並使用 @使用者名稱 來回應。 + + 你可以編輯你先前的回應訊息,選擇字句後點選 引用 來回應。 + + 對於大家而言,閱讀包含較多回覆的少量貼文,會比閱讀多篇瑣碎貼文更為輕鬆。 + dominating_topic: | + ### 讓其他人能一起加入討論 + + 這篇主題真的對你很重要 – 你在這個討論中已回覆多於 %{percent}% 的回應。 + + 你有沒有提供其他人充足的時間,以便表達意見呢? + get_a_room: | + ### 考慮回應更多參與者 + + 你已經在這個特定主題中,回應了 @%{reply_username} %{count} 次。 + + 你有考慮回應討論中的 *其他* 人嗎?一個好的討論,需要納入更多人的觀點與意見。 + + 如果你還是想要與他繼續討論,請考慮透過[個人訊息](/users/%{reply_username})來進行。 + too_many_replies: | + ### 你發表的回應數量已經達到主題的回覆上限 + + 非常抱歉,新用戶有臨時限制,只能回覆同一主題 %{newuser_max_replies_per_topic} 次。 + + 除了繼續回覆外,可以考慮修改你先前的回應,或參與其他主題。 + reviving_old_topic: | + ### 討論串考古? + + 這個主題中最新的回應已經是 **%{days} 天** 前的事情了。你的回應會讓主題跳到最上方,並且通知所有曾參與過討論的人。 + + 你確定你想要喚醒這個舊主題嗎? activerecord: attributes: category: @@ -270,6 +304,7 @@ zh_TW: same_as_username: "與你的用戶名稱相同。請使用其他更安全的密碼。" same_as_email: "與你的電郵相同。請使用其他更安全的密碼。" same_as_current: "與您目前的密碼相同。" + unique_characters: "你的密碼有太多重複字元了。請使用其他更安全的密碼。" ip_address: signup_not_allowed: "不能使用這個帳戶進行登入" color_scheme_color: @@ -716,6 +751,8 @@ zh_TW: facebook_config_warning: '伺服器允許使用 Facebook 帳號登入 (enable_facebook_logins), 但未有設定 app id 及 app secret values 。 請在 網站設定 裡更改設定。 設定教學指南。' twitter_config_warning: '伺服器允許使用 Twitter 帳號登入 (enable_twitter_logins), 但未有設定 key 和 secret values 。 請在 網站設定 裡更改設定。 設定教學指南。' github_config_warning: '伺服器允許使用 GitHub 帳號登入 (enable_github_logins), 但未有設定 client id 和 secret values。 請在 網站設定 裡更改設定。 設定教學指南。' + s3_config_warning: '伺服器被設定為上傳文件到 s3,但是至少有一個值未被設定: s3_access_key_id, s3_secret_access_key, s3_use_iam_profile, or s3_upload_bucket。到 網站設定更新此設定。請查閱「如何設置圖片上傳至 S3」.' + s3_backup_config_warning: '伺服器被設定為上傳備份到 s3,但是至少有一個值未被設定: s3_access_key_id, s3_secret_access_key, s3_use_iam_profile, or s3_upload_bucket。到 網站設定更新此設定。請查閱「如何設置圖片上傳至 S3」.' image_magick_warning: '伺服器被設置為給大圖片創建縮略圖,但是 ImageMagick 沒有被安裝。使用你喜愛的包裝管理器安裝 ImageMagick 或下載最新版。' failing_emails_warning: '有 %{num_failed_jobs} 個郵件任務失敗。請檢查 app.yml 檔案是否正確配置了郵件伺服器。查看 Sidekiq 中失敗的任務。' subfolder_ends_in_slash: "你的子目錄設置不正確;DISCOURSE_RELATIVE_URL_ROOT以斜杠結尾。" @@ -734,7 +771,7 @@ zh_TW: set_locale_from_accept_language_header: "為未登錄用戶按照他們的瀏覽器發送的請求頭部設置界面語言。(實驗性,無法和匿名緩存共同使用)" min_post_length: "文章允許的最小文字數" min_first_post_length: "第一篇文章允許的最少文字數" - min_private_message_post_length: "文章允許的最小文字數" + min_private_message_post_length: "私訊允許的最小文字數" max_post_length: "文章允許的最大文字數" topic_featured_link_enabled: "允許發連結帖。" show_topic_featured_link_in_digest: "在摘要郵件中顯示主題特色連結。" @@ -860,7 +897,8 @@ zh_TW: invite_passthrough_hours: "邀請號碼如已被使用,用戶仍可使用多少小時" invite_only: "已經禁止開放註冊,新的使用者必須取得其他用戶,或是管理員的邀請" login_required: "需要登入才能進入網站,不允許匿名操作" - reserved_usernames: "註冊時不可使用的用戶名。" + min_username_length: "最短用戶名長度。警告:如果任何現有帳號或群組名稱短於此,你的網站會炸掉。" + max_username_length: "最長用戶名長度。警告:如果任何現有帳號或群組名稱長於此,你的網站會炸掉。" min_password_length: "最小密碼長度" min_admin_password_length: "管理員最短密碼長度" block_common_passwords: "不允許使用 10,000 個最常用的密碼" @@ -1095,12 +1133,13 @@ zh_TW: allow_animated_thumbnails: "為 gif 動畫生成動態縮略圖。" default_avatars: "新用戶將會使用的默認頭像的網址。" automatically_download_gravatars: "當用戶註冊或更改EMail時下載 Gravatars 圖片" - digest_topics: "郵件摘要中顯示的流行主題的最大數目。" - digest_posts: "郵件摘要中顯示的最流行帖子的數量。" - digest_other_topics: "郵件摘要中“你關注的主題和分類中的新內容”欄目顯示的主題數目上限。" - digest_min_excerpt_length: "郵件摘要中顯示的帖子摘要字元數下限。" + digest_topics: "郵件摘要中顯示的熱門主題的數目上限。" + digest_posts: "郵件摘要中顯示的熱門貼文數目上限。" + digest_other_topics: "郵件摘要中「你關注的主題和分類中的新內容」欄目顯示的主題數目上限。" + digest_min_excerpt_length: "郵件摘要中顯示的貼文摘要字元數下限。" + suppress_digest_email_after_days: "對於 (n) 日以上未上站的用戶,停止發送摘要郵件。" digest_suppress_categories: "不在摘要郵件中顯示這些分類的內容。" - disable_digest_emails: "禁用所有用戶摘要郵件功能。" + disable_digest_emails: "停用發送摘要郵件給所有用戶的功能。" email_accent_bg_color: "HTML 郵件中某些元素的背景使用的強調顏色。輸入色彩名(“red”)或十六進制值(“#FF0000”)。" email_accent_fg_color: "HTML 郵件中背景使用的字型顏色。輸入色彩名(“white”)或十六進制值(“#FFFFFF”)。" email_link_color: "HTML 郵件中的連結顏色。輸入色彩名字(“blue”)或十六進制值(“#0000FF”)。" @@ -1167,7 +1206,7 @@ zh_TW: auto_close_topics_post_count: "主題中貼子數上限,達到後自動關閉主題 ( 0 為禁用 )" code_formatting_style: "編輯器中的代碼格式化按鈕設置的預設格式" default_email_digest_frequency: "用戶收到摘要郵件的預設頻率。" - default_include_tl0_in_digests: "在摘要郵件中預設包含新用戶帖子。用戶可以自行在參數設置中更改這個設置。" + default_include_tl0_in_digests: "在摘要郵件中預設包含新用戶的貼文。用戶可以自行在參數設置中更改這個設定。" default_email_private_messages: "預設在有人發消息給用戶時發送一封郵件通知。" default_email_direct: "預設在有人引用、回覆、提及或者邀請用戶時發送一封郵件通知。" default_email_mailing_list_mode: "預設為每一個新帖子發送一封郵件通知。" @@ -1306,7 +1345,7 @@ zh_TW: incorrect_username_email_or_password: "用戶名、電子郵箱或密碼不正確" wait_approval: "謝謝註冊帳號。我們會在你的帳號獲得批准之後通知你。" active: "你的帳號已經被啟用,可以使用了。" - activate_email: "

    快完成了!我們發送了一封激活郵件到%{email}。請按照郵件中的步驟來激活你的帳號。

    如果你沒有收到郵件,請檢查你的垃圾郵件收件箱,或者試試再登錄一次,看看能不能收到另一封激活郵件。

    " + activate_email: "

    快完成了!我們已寄送了一封確認信件到 %{email},請按照信中的步驟來啟用你的帳號。

    如果你沒有收到郵件,請檢查你的垃圾郵件收件夾,或者試試再登錄一次,以再次發送另一封確認信件。

    " not_activated: "你還不能登入。我們發送了一封啟用郵件給你,請按照郵件中的步驟來啟用你的帳號。" not_allowed_from_ip_address: "你無法透過此 IP 登入成為 %{username}。" admin_not_allowed_from_ip_address: "你無法透過此 IP 登入成為管理員。" @@ -1358,35 +1397,90 @@ zh_TW: title: "取消訂閱 Mailer" subject_template: "確認你不想要收到%{site_title}的電子郵件更新" text_body_template: | - 有人(可能是你?)請求不再接受來自%{site_domain_name}的郵件更新。 - 點擊連結以確認退訂: + 有人(可能是你?)要求不再接收來自 %{site_domain_name} 的郵件更新。 + 請點擊連結以確認退訂: %{confirm_unsubscribe_link} - - 如果你想要繼續接受郵件更新,你可以忽略這封郵件。 + 如果你想要繼續接收郵件更新,你可以直接忽略這封郵件。 invite_mailer: title: "邀請 Mailer" subject_template: "%{invitee_name} 邀請你參與在 %{site_domain_name} 討論的話題 '%{topic_title}'" + text_body_template: | + %{invitee_name} 邀請你參與位於 + + > %{site_title} -- %{site_description} + + 的以下討論 + + > **%{topic_title}** + > + > %{topic_excerpt} + + 如果你有興趣,請點擊下面的連結: + + %{invite_link} custom_invite_mailer: title: "客製邀請 Mailer" subject_template: "%{invitee_name}邀請你'%{topic_title}'在%{site_domain_name}" + text_body_template: | + %{invitee_name} 留下以下留言 + + > %{user_custom_message} + + 邀請你參與位於 + + > %{site_title} -- %{site_description} + + 的討論 + + > **%{topic_title}** + > + > %{topic_excerpt} + + 如果你有興趣,請點擊下面的連結: + + %{invite_link} invite_forum_mailer: title: "邀請論壇 Mailer" subject_template: "%{invitee_name} 邀請你加入 %{site_domain_name}" + text_body_template: | + %{invitee_name} 邀請你加入 + + > **%{site_title}** + > + > %{site_description} + + 如果你感興趣,請點擊下面的連結: + + %{invite_link} custom_invite_forum_mailer: title: "邀請論壇 Mailer" subject_template: "%{invitee_name}邀請你加入%{site_domain_name}" + text_body_template: | + %{invitee_name} 留下以下留言 + + > %{user_custom_message} + + 邀請你加入 + + > **%{site_title}** + > + > %{site_description} + + 如果你感興趣,請點擊下面的連結: + + %{invite_link} invite_password_instructions: title: "邀請密碼的說明" subject_template: "為 %{site_name} 的帳戶設置密碼" text_body_template: | - 感謝你接受來自%{site_name}的邀請——歡迎! + 感謝你接受來自 %{site_name} 的邀請,歡迎! - 點擊下面的連結立即選擇一個密碼: + 點擊下面的連結,立即設定你的密碼: %{base_url}/users/password-reset/%{email_token} - (如果連結已經過期,在登錄時用,選擇“我忘記了密碼”,再次輸入你的郵箱即可。) + (如果連結已經過期,在登入頁面選擇「我忘了我的密碼」,再次輸入你的 email 即可) test_mailer: title: "測試 Mailer" subject_template: "[%{site_name}] 電子郵件發送測試" @@ -1596,10 +1690,18 @@ zh_TW: csv_export_succeeded: title: "CSV 檔匯出成功" subject_template: "資料匯出完成" + text_body_template: | + 資料成功匯出了!:dvd: + + %{file_name} (%{file_size}) + + 以上的下載連結將在 48 小時後失效。 + + 資料以 gzip 格式壓縮,如果你無法開啟壓縮檔,可以使用這裡推薦的工具: http://www.gzip.org/#faq4 csv_export_failed: title: "CSV 檔匯出失敗" subject_template: "資料匯出失敗" - text_body_template: "我們很抱歉,但是你的數據導出請求失敗了。請檢查日誌或聯繫一位管理人員。" + text_body_template: "很抱歉,你的資料匯出失敗了。請檢查日誌,或聯繫管理人員。" email_reject_insufficient_trust_level: title: "電子郵件拒絕 信任等級不足" subject_template: "[%{site_name}] 電子郵件錯誤 -- 信任等級不足" @@ -1833,13 +1935,13 @@ zh_TW: [請檢查並修復他們](%{base_url}/admin)。 unsubscribe_link: | - 要退訂這些郵件,[點擊這裡](%{unsubscribe_url})。 + 要退訂這些郵件,[請點擊這裡](%{unsubscribe_url})。 unsubscribe_link_and_mail: | - 要退訂這些郵件,[點擊這裡](%{unsubscribe_url})。 + 要退訂這些郵件,[請點擊這裡](%{unsubscribe_url})。 unsubscribe_mailing_list: | - 你啟用了郵件列表模式,所以收到了這些郵件。 + 你啟用了郵件列表模式,所以收到本郵件。 - 要退訂這些郵件,[點擊這裡](%{unsubscribe_url})。 + 要退訂這些郵件,[請點擊這裡](%{unsubscribe_url})。 subject_re: "回覆:" subject_pm: "[私訊]" user_notifications: @@ -1853,8 +1955,8 @@ zh_TW: reply_by_email: "[訪問主題](%{base_url}%{url})或者發郵件回覆。" reply_by_email_pm: "[訪問消息](%{base_url}%{url})或者發郵件回覆。" only_reply_by_email: "發郵件回覆。" - visit_link_to_respond: "[訪問主題](%{base_url}%{url})以回覆." - visit_link_to_respond_pm: "[訪問消息](%{base_url}%{url})以回覆." + visit_link_to_respond: "[訪問主題](%{base_url}%{url})以回覆。" + visit_link_to_respond_pm: "[訪問\"私訊\"](%{base_url}%{url})以回覆。" posted_by: "由 %{username} 張貼於 %{post_date}" invited_to_private_message_body: | %{username} 邀請你至消息交流: @@ -2010,18 +2112,18 @@ zh_TW: %{message} digest: why: "在你上一次於 %{last_seen_at} 訪問後,在 %{site_link} 上的摘要。" - since_last_visit: "自從你上次訪問" + since_last_visit: "自你上次訪問至今" new_topics: "新主題" - unread_messages: "未讀私信" + unread_messages: "未讀私訊" unread_notifications: "未讀通知" liked_received: "獲得贊" - new_posts: "新帖子" + new_posts: "新文章" new_users: "新用戶" popular_topics: "熱門主題" follow_topic: "關注主題" join_the_discussion: "閲讀更多" - popular_posts: "流行帖子" - more_new: "新內容" + popular_posts: "熱門貼文" + more_new: "新內容與你分享" subject_template: "[%{site_name}] 摘要" unsubscribe: "這是封來自%{site_link}的摘要郵件,因為你長時間沒有訪問而發送。%{unsubscribe_link}取消訂閲。" click_here: "點擊此處" @@ -2103,32 +2205,32 @@ zh_TW: title: "在同意之後註冊" subject_template: "你已受到 %{site_name} 的認可!" text_body_template: | - 歡迎加入%{site_name}! + 歡迎加入 %{site_name}! - 一個管理人員批准了你在%{site_name}的賬戶。 + 管理人員已批准了你在 %{site_name} 的帳戶申請。 - 點擊下面的連結來確認並激活你在 %{site_name} 上的新賬號: + 請點擊以下連結,以確認和啟用你的新帳號: %{base_url}/users/activate-account/%{email_token} - 如果上面的連結無法點擊,請拷貝該連結並粘貼到你的瀏覽器的地址欄裡。 + 如果上面的連結無法點擊,請複製該連結,並貼到瀏覽器中開啟。 %{new_user_tips} - 我們始終相信[討論應該文明](%{base_url}/guidelines)。 + 我們始終相信[社群守則](%{base_url}/guidelines)。 好好享受你在論壇的時光吧! - (如果你在新用戶級別需要和[管理人員](%{base_url/about)溝通的話,直接回覆這個消息。) + (如果你需要和[管理人員](%{base_url}/about)聯繫的話,請直接回覆這則訊息。) signup: title: "註冊" subject_template: "[%{site_name}] 確認你的新賬戶" text_body_template: | 歡迎來到 %{site_name}! - 點擊以下連結來確認和啟用你的新帳號: + 請點擊以下連結,以確認和啟用你的新帳號: %{base_url}/users/activate-account/%{email_token} - 如果上面的連結無法點擊,請拷貝該連結並粘貼到你的流覽器的地址欄裡。 + 如果上面的連結無法點擊,請複製該連結,並貼到瀏覽器中開啟。 page_not_found: title: "抱歉!這個頁面不存在或者是私密的。" popular_topics: "熱門" @@ -2751,10 +2853,10 @@ zh_TW: no_emails: "不幸的是,在嚮導中你沒有設置管理員郵件地址,所以完善配置可能有點困難。" confirm_email: title: "配置你的郵件" - message: "

    我們發送了一封激活郵件到%{email}。請按照郵件中的步驟來激活你的帳號。

    如果你沒有收到郵件,請檢查你正確設置了 Discourse 郵件配置,然後查看你的垃圾郵件收件箱。

    " + message: "

    我們已寄送了一封確認信件到 %{email},請按照信中的步驟來啟用你的帳號。

    如果你沒有收到郵件,請檢查你的 Discourse 郵件設定正確,並檢查你的垃圾郵件收件夾。

    " resend_email: - title: "重發激活郵件" - message: "

    我們重發了激活郵件至%{email}" + title: "重發啟用信件" + message: "

    我們已重發啟用信件至 %{email}" safe_mode: title: "進入安全模式" description: "安全模式讓你的站點不載入插件或站點自定義設置。" @@ -2785,9 +2887,11 @@ zh_TW: fields: welcome: label: "歡迎主題" + description: "

    你會如何在一分鐘內向陌生人描述你的社群?

    • 誰會對這些討論感興趣?
    • 我能獲得什麼?
    • 為什麼我應該參與?

    你的歡迎主題,是新訪客將首先看到的訊息。請將它視為一段「電梯宣傳」或者「任務說明」。

    " one_paragraph: "請限制你的歡迎消息至一段話。" privacy: title: "訪問" + description: "

    你的社群對是否對大眾公開,或僅限於會員使用、邀請制或須審核加入?如果你願意,你可以先在私密模式下準備,稍後再將其設為公開。

    你隨時可以在主題中邀請別人參與,或者從你的用戶頁面發送邀請也行。

    " fields: privacy: choices: diff --git a/config/routes.rb b/config/routes.rb index fc53ffb18f..038472ef46 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -54,6 +54,7 @@ Discourse::Application.routes.draw do end get "site/basic-info" => 'site#basic_info' + get "site/statistics" => 'site#statistics' get "site_customizations/:key" => "site_customizations#show" @@ -133,6 +134,7 @@ Discourse::Application.routes.draw do get "users/:id.json" => 'users#show', defaults: {format: 'json'} get 'users/:id/:username' => 'users#show', constraints: {username: USERNAME_ROUTE_FORMAT} get 'users/:id/:username/badges' => 'users#show' + get 'users/:id/:username/tl3_requirements' => 'users#show' post "users/sync_sso" => "users#sync_sso", constraints: AdminConstraint.new @@ -502,6 +504,7 @@ Discourse::Application.routes.draw do get "category_hashtags/check" => "category_hashtags#check" TopTopic.periods.each do |period| + get "top/#{period}.rss" => "list#top_#{period}_feed", format: :rss get "top/#{period}" => "list#top_#{period}" get "c/:category/l/top/#{period}" => "list#category_top_#{period}", as: "category_top_#{period}" get "c/:category/none/l/top/#{period}" => "list#category_none_top_#{period}", as: "category_none_top_#{period}" diff --git a/config/site_settings.yml b/config/site_settings.yml index 1fbc412056..b82e2b8be8 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -1308,6 +1308,8 @@ uncategorized: native_app_install_banner: false + share_anonymized_statistics: true + user_preferences: default_email_digest_frequency: diff --git a/config/unicorn.conf.rb b/config/unicorn.conf.rb index 74723ef125..5f51df510a 100644 --- a/config/unicorn.conf.rb +++ b/config/unicorn.conf.rb @@ -77,6 +77,11 @@ before_fork do |server, worker| Demon::Sidekiq.start(sidekiqs) + Signal.trap("SIGTSTP") do + STDERR.puts "#{Time.now}: Issuing stop to sidekiq" + Demon::Sidekiq.stop + end + class ::Unicorn::HttpServer alias :master_sleep_orig :master_sleep diff --git a/db/migrate/20170201085745_create_custom_emojis.rb b/db/migrate/20170201085745_create_custom_emojis.rb new file mode 100644 index 0000000000..15590fba61 --- /dev/null +++ b/db/migrate/20170201085745_create_custom_emojis.rb @@ -0,0 +1,12 @@ +class CreateCustomEmojis < ActiveRecord::Migration + def change + create_table :custom_emojis do |t| + t.string :name, null: false + t.integer :upload_id, null: false + + t.timestamps null: false + end + + add_index :custom_emojis, :name, unique: true + end +end diff --git a/db/migrate/20170308201552_add_subcategory_list_style_to_categories.rb b/db/migrate/20170308201552_add_subcategory_list_style_to_categories.rb new file mode 100644 index 0000000000..0c2f5159e4 --- /dev/null +++ b/db/migrate/20170308201552_add_subcategory_list_style_to_categories.rb @@ -0,0 +1,14 @@ +class AddSubcategoryListStyleToCategories < ActiveRecord::Migration + def up + add_column :categories, :subcategory_list_style, :string, limit: 50, default: 'rows_with_featured_topics' + + result = execute("select value from site_settings where name = 'desktop_category_page_style' and value != 'categories_with_featured_topics'") + if result.count > 0 + execute "UPDATE categories SET subcategory_list_style = 'rows' WHERE parent_category_id IS NULL" + end + end + + def down + remove_column :categories, :subcategory_list_style + end +end diff --git a/lib/backup_restore/backup_restore.rb b/lib/backup_restore/backup_restore.rb index 0b50e094fb..12a9ecd21d 100644 --- a/lib/backup_restore/backup_restore.rb +++ b/lib/backup_restore/backup_restore.rb @@ -1,4 +1,3 @@ -require "backup_restore/utils" require "backup_restore/backuper" require "backup_restore/restorer" diff --git a/lib/backup_restore/backuper.rb b/lib/backup_restore/backuper.rb index bc885e8fe1..37bb897a7e 100644 --- a/lib/backup_restore/backuper.rb +++ b/lib/backup_restore/backuper.rb @@ -1,8 +1,6 @@ module BackupRestore class Backuper - include BackupRestore::Utils - attr_reader :success def initialize(user_id, opts={}) @@ -198,7 +196,7 @@ module BackupRestore def move_dump_backup log "Finalizing database dump file: #{@backup_filename}" - execute_command( + Discourse::Utils.execute_command( 'mv', @dump_filename, File.join(@archive_directory, @backup_filename), failure_message: "Failed to move database dump file." ) @@ -212,15 +210,15 @@ module BackupRestore tar_filename = "#{@archive_basename}.tar" log "Making sure archive does not already exist..." - execute_command('rm', '-f', tar_filename) - execute_command('rm', '-f', "#{tar_filename}.gz") + Discourse::Utils.execute_command('rm', '-f', tar_filename) + Discourse::Utils.execute_command('rm', '-f', "#{tar_filename}.gz") log "Creating empty archive..." - execute_command('tar', '--create', '--file', tar_filename, '--files-from', '/dev/null') + Discourse::Utils.execute_command('tar', '--create', '--file', tar_filename, '--files-from', '/dev/null') log "Archiving data dump..." FileUtils.cd(File.dirname(@dump_filename)) do - execute_command( + Discourse::Utils.execute_command( 'tar', '--append', '--dereference', '--file', tar_filename, File.basename(@dump_filename), failure_message: "Failed to archive data dump." ) @@ -231,7 +229,7 @@ module BackupRestore log "Archiving uploads..." FileUtils.cd(File.join(Rails.root, "public")) do if File.directory?(upload_directory) - execute_command( + Discourse::Utils.execute_command( 'tar', '--append', '--dereference', '--file', tar_filename, upload_directory, failure_message: "Failed to archive uploads." ) @@ -243,7 +241,7 @@ module BackupRestore remove_tmp_directory log "Gzipping archive, this may take a while..." - execute_command('gzip', '-5', tar_filename, failure_message: "Failed to gzip archive.") + Discourse::Utils.execute_command('gzip', '-5', tar_filename, failure_message: "Failed to gzip archive.") end def after_create_hook @@ -259,11 +257,11 @@ module BackupRestore def notify_user log "Notifying '#{@user.username}' of the end of the backup..." - if @success - SystemMessage.create_from_system_user(@user, :backup_succeeded, logs: pretty_logs(@logs)) - else - SystemMessage.create_from_system_user(@user, :backup_failed, logs: pretty_logs(@logs)) - end + status = @success ? :backup_succeeded : :backup_failed + + SystemMessage.create_from_system_user(@user, status, + logs: Discouse::Utils.pretty_logs(@logs) + ) end def clean_up diff --git a/lib/backup_restore/restorer.rb b/lib/backup_restore/restorer.rb index f7606e871e..de6e133df1 100644 --- a/lib/backup_restore/restorer.rb +++ b/lib/backup_restore/restorer.rb @@ -6,8 +6,6 @@ module BackupRestore class FilenameMissingError < RuntimeError; end class Restorer - include BackupRestore::Utils - attr_reader :success def initialize(user_id, opts={}) @@ -166,7 +164,7 @@ module BackupRestore def copy_archive_to_tmp_directory log "Copying archive to tmp directory..." - execute_command('cp', @source_filename, @archive_filename, failure_message: "Failed to copy archive to tmp directory.") + Discourse::Utils.execute_command('cp', @source_filename, @archive_filename, failure_message: "Failed to copy archive to tmp directory.") end def unzip_archive @@ -175,7 +173,7 @@ module BackupRestore log "Unzipping archive, this may take a while..." FileUtils.cd(@tmp_directory) do - execute_command('gzip', '--decompress', @archive_filename, failure_message: "Failed to unzip archive.") + Discourse::Utils.execute_command('gzip', '--decompress', @archive_filename, failure_message: "Failed to unzip archive.") end end @@ -185,7 +183,7 @@ module BackupRestore @metadata = if system('tar', '--list', '--file', @tar_filename, BackupRestore::METADATA_FILE) FileUtils.cd(@tmp_directory) do - execute_command( + Discourse::Utils.execute_command( 'tar', '--extract', '--file', @tar_filename, BackupRestore::METADATA_FILE, failure_message: "Failed to extract metadata file." ) @@ -233,7 +231,7 @@ module BackupRestore log "Extracting dump file..." FileUtils.cd(@tmp_directory) do - execute_command( + Discourse::Utils.execute_command( 'tar', '--extract', '--file', @tar_filename, File.basename(@dump_filename), failure_message: "Failed to extract dump file." ) @@ -364,7 +362,7 @@ module BackupRestore log "Extracting uploads..." FileUtils.cd(@tmp_directory) do - execute_command( + Discourse::Utils.execute_command( 'tar', '--extract', '--keep-newer-files', '--file', @tar_filename, 'uploads/', failure_message: "Failed to extract uploads." ) @@ -379,7 +377,7 @@ module BackupRestore previous_db_name = File.basename(tmp_uploads_path) current_db_name = RailsMultisite::ConnectionManagement.current_db - execute_command( + Discourse::Utils.execute_command( 'rsync', '-avp', '--safe-links', "#{tmp_uploads_path}/", "uploads/#{current_db_name}/", failure_message: "Failed to restore uploads." ) @@ -404,11 +402,11 @@ module BackupRestore def notify_user if user = User.find_by(email: @user_info[:email]) log "Notifying '#{user.username}' of the end of the restore..." - if @success - SystemMessage.create_from_system_user(user, :restore_succeeded, logs: pretty_logs(@logs)) - else - SystemMessage.create_from_system_user(user, :restore_failed, logs: pretty_logs(@logs)) - end + status = @success ? :restore_succeeded : :restore_failed + + SystemMessage.create_from_system_user(user, status, + logs: Discourse::Utils.pretty_logs(@logs) + ) else log "Could not send notification to '#{@user_info[:username]}' (#{@user_info[:email]}), because the user does not exists..." end diff --git a/lib/backup_restore/utils.rb b/lib/backup_restore/utils.rb deleted file mode 100644 index b782f61bee..0000000000 --- a/lib/backup_restore/utils.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'open3' - -module BackupRestore - module Utils - def execute_command(*command, failure_message: "") - stdout, stderr, status = Open3.capture3(*command) - - if !status.success? - failure_message = "#{failure_message}\n" if !failure_message.blank? - raise "#{failure_message}#{stderr}" - end - - stdout - end - - def pretty_logs(logs) - logs.join("\n") - end - end -end diff --git a/lib/discourse.rb b/lib/discourse.rb index d8e66fa405..086ed28b72 100644 --- a/lib/discourse.rb +++ b/lib/discourse.rb @@ -1,4 +1,5 @@ require 'cache' +require 'open3' require_dependency 'plugin/instance' require_dependency 'auth/default_current_user_provider' require_dependency 'version' @@ -16,6 +17,23 @@ module Discourse extend Sidekiq::ExceptionHandler end + class Utils + def self.execute_command(*command, failure_message: "") + stdout, stderr, status = Open3.capture3(*command) + + if !status.success? + failure_message = "#{failure_message}\n" if !failure_message.blank? + raise "#{failure_message}#{stderr}" + end + + stdout + end + + def self.pretty_logs(logs) + logs.join("\n".freeze) + end + end + # Log an exception. # # If your code is in a scheduled job, it is recommended to use the diff --git a/lib/email.rb b/lib/email.rb index f37d81aa65..0bae995d17 100644 --- a/lib/email.rb +++ b/lib/email.rb @@ -29,4 +29,21 @@ module Email name ? name.gsub(/[:<>,"]/, '') : name end + def self.extract_parts(raw) + mail = Mail.new(raw) + text = nil + html = nil + + if mail.multipart? + text = mail.text_part + html = mail.html_part + elsif mail.content_type.to_s["text/html"] + html = mail + else + text = mail + end + + [text&.decoded, html&.decoded] + end + end diff --git a/lib/email/sender.rb b/lib/email/sender.rb index 444ae7d1cb..cf9695583c 100644 --- a/lib/email/sender.rb +++ b/lib/email/sender.rb @@ -81,7 +81,7 @@ module Email topic = Topic.find_by(id: topic_id) first_post = topic.ordered_posts.first - topic_message_id = first_post.incoming_email&.message_id.present? ? + topic_message_id = first_post.incoming_email&.message_id.present? ? "<#{first_post.incoming_email.message_id}>" : "" diff --git a/lib/file_store/local_store.rb b/lib/file_store/local_store.rb index 411b93ed0d..5b23505998 100644 --- a/lib/file_store/local_store.rb +++ b/lib/file_store/local_store.rb @@ -59,7 +59,7 @@ module FileStore end def purge_tombstone(grace_period) - `find #{tombstone_dir} -mtime +#{grace_period} -type f -delete` + Discourse::Utils.execute_command('find', tombstone_dir, '-mtime', "+#{grace_period}", '-type f -delete') end def get_path_for(type, upload_id, sha, extension) diff --git a/lib/html_prettify.rb b/lib/html_prettify.rb index 6d0b3d065b..39a8ca7d30 100644 --- a/lib/html_prettify.rb +++ b/lib/html_prettify.rb @@ -120,9 +120,6 @@ class HtmlPrettify < String unless in_pre t.gsub!("'", "'") - - t = process_escapes t - t.gsub!(""", '"') if do_dashes @@ -176,22 +173,6 @@ class HtmlPrettify < String protected - # Return the string, with after processing the following backslash - # escape sequences. This is useful if you want to force a "dumb" quote - # or other character to appear. - # - # Escaped are: - # \\ \" \' \. \- \` - # - def process_escapes(str) - str = str.gsub('\\\\', '\') - str.gsub!('\"', '"') - str.gsub!("\\\'", ''') - str.gsub!('\.', '.') - str.gsub!('\-', '-') - str.gsub!('\`', '`') - str - end # The string, with each instance of "--" translated to an # em-dash HTML entity. diff --git a/lib/letter_avatar.rb b/lib/letter_avatar.rb index 79e1a9b884..62915edcab 100644 --- a/lib/letter_avatar.rb +++ b/lib/letter_avatar.rb @@ -74,15 +74,15 @@ class LetterAvatar -size #{FULLSIZE}x#{FULLSIZE} xc:#{to_rgb(color)} -pointsize #{POINTSIZE} - -fill '#FFFFFFCC' - -font 'Helvetica' + -fill #FFFFFFCC + -font Helvetica -gravity Center - -annotate -0+26 '#{letter}' + -annotate -0+26 #{letter} -depth 8 - '#{filename}' + #{filename} } - `convert #{instructions.join(" ")}` + Discourse::Utils.execute_command('convert', *instructions) ## do not optimize image, it will end up larger than original filename @@ -90,7 +90,7 @@ class LetterAvatar def to_rgb(color) r,g,b = color - "'rgb(#{r},#{g},#{b})'" + "rgb(#{r},#{g},#{b})" end def image_magick_version diff --git a/lib/new_post_manager.rb b/lib/new_post_manager.rb index 27aebae663..537c7faff0 100644 --- a/lib/new_post_manager.rb +++ b/lib/new_post_manager.rb @@ -104,8 +104,10 @@ class NewPostManager result = manager.enqueue('default') - if is_fast_typer?(manager) || matches_auto_block_regex?(manager) - UserBlocker.block(manager.user, Discourse.system_user, keep_posts: true) + if is_fast_typer?(manager) + UserBlocker.block(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.new_user_typed_too_fast")) + elsif matches_auto_block_regex?(manager) + UserBlocker.block(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.content_matches_auto_block_regex")) end result diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb index af1174aab2..e6b8c04756 100644 --- a/lib/plugin/instance.rb +++ b/lib/plugin/instance.rb @@ -356,11 +356,12 @@ JS public_data = File.dirname(path) + "/public" if Dir.exists?(public_data) target = Rails.root.to_s + "/public/plugins/" - `mkdir -p #{target}` + + Discourse::Utils.execute_command('mkdir', '-p', target) target << name.gsub(/\s/,"_") # TODO a cleaner way of registering and unregistering - `rm -f #{target}` - `ln -s #{public_data} #{target}` + Discourse::Utils.execute_command('rm', '-f', target) + Discourse::Utils.execute_command('ln', '-s', public_data, target) end end diff --git a/lib/search.rb b/lib/search.rb index ef30676570..7c055e0a40 100644 --- a/lib/search.rb +++ b/lib/search.rb @@ -315,6 +315,29 @@ class Search end end + advanced_filter(/in:seen/) do |posts| + if @guardian.user + posts + .joins("INNER JOIN post_timings ON + post_timings.topic_id = posts.topic_id + AND post_timings.post_number = posts.post_number + AND post_timings.user_id = #{Post.sanitize(@guardian.user.id)} + ") + end + end + + advanced_filter(/in:unseen/) do |posts| + if @guardian.user + posts + .joins("LEFT JOIN post_timings ON + post_timings.topic_id = posts.topic_id + AND post_timings.post_number = posts.post_number + AND post_timings.user_id = #{Post.sanitize(@guardian.user.id)} + ") + .where("post_timings.user_id IS NULL") + end + end + advanced_filter(/category:(.+)/) do |posts,match| exact = false @@ -642,7 +665,8 @@ class Search end elsif @search_context.is_a?(Category) - posts = posts.where("topics.category_id = #{@search_context.id}") + category_ids = [@search_context.id] + Category.where(parent_category_id: @search_context.id).pluck(:id) + posts = posts.where("topics.category_id in (?)", category_ids) elsif @search_context.is_a?(Topic) posts = posts.where("topics.id = #{@search_context.id}") .order("posts.post_number") @@ -729,10 +753,10 @@ class Search if @order == :likes # likes are a pain to aggregate so skip posts_query(@limit, private_messages: opts[:private_messages]) - .select('topics.id', "post_number") + .select('topics.id', "posts.post_number") else posts_query(@limit, aggregate_search: true, private_messages: opts[:private_messages]) - .select('topics.id', "#{min_or_max}(post_number) post_number") + .select('topics.id', "#{min_or_max}(posts.post_number) post_number") .group('topics.id') end @@ -761,6 +785,7 @@ class Search post_sql = aggregate_post_sql(opts) added = 0 + aggregate_posts(post_sql[:default]).each do |p| @results.add(p) added += 1 diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake index 53d3ea80cd..2f2a46b409 100644 --- a/lib/tasks/assets.rake +++ b/lib/tasks/assets.rake @@ -15,6 +15,10 @@ task 'assets:precompile:before' do $node_uglify = true end + unless ENV['USE_SPROCKETS_UGLIFY'] + $bypass_sprockets_uglify = true + end + puts "Bundling assets" # in the past we applied a patch that removed asset postfixes, but it is terrible practice @@ -28,7 +32,7 @@ task 'assets:precompile:before' do load "#{Rails.root}/lib/global_path.rb" include GlobalPath - if $node_uglify + if $bypass_sprockets_uglify Rails.configuration.assets.js_compressor = nil Rails.configuration.assets.gzip = false end @@ -84,14 +88,18 @@ def compress_ruby(from,to) uglified, map = Uglifier.new(comments: :none, screw_ie8: true, - source_filename: File.basename(from), - output_filename: File.basename(to) + source_map: { + filename: File.basename(from), + output_filename: File.basename(to) + } ) .compile_with_map(data) dest = "#{assets_path}/#{to}" File.write(dest, uglified << "\n//# sourceMappingURL=#{cdn_path "/assets/#{to}.map"}") File.write(dest + ".map", map) + + GC.start end def gzip(path) @@ -108,7 +116,7 @@ def brotli(path) end def compress(from,to) - if @has_uglifyjs ||= !`which uglifyjs`.empty? + if $node_uglify compress_node(from,to) else compress_ruby(from,to) @@ -129,7 +137,7 @@ task 'assets:precompile' => 'assets:precompile:before' do # Run after assets:precompile Rake::Task["assets:precompile:css"].invoke - if $node_uglify + if $bypass_sprockets_uglify puts "Compressing Javascript and Generating Source Maps" manifest = Sprockets::Manifest.new(assets_path) diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index b460d550c6..0c88c62c55 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -6,6 +6,7 @@ end # we need to run seed_fu every time we run rake db:migrate task 'db:migrate' => ['environment', 'set_locale'] do SeedFu.seed + Jobs::Onceoff.enqueue_all end task 'test:prepare' => 'environment' do diff --git a/lib/twitter_api.rb b/lib/twitter_api.rb index ff1bd9c7ad..373c6838f1 100644 --- a/lib/twitter_api.rb +++ b/lib/twitter_api.rb @@ -4,7 +4,7 @@ class TwitterApi class << self def prettify_tweet(tweet) - text = tweet["text"].dup + text = tweet["full_text"].dup if entities = tweet["entities"] and urls = entities["urls"] urls.each do |url| text.gsub!(url["url"], "#{url["display_url"]}") @@ -22,6 +22,10 @@ class TwitterApi if large = m['sizes']['large'] result << "" end + elsif m['type'] == 'video' + if large = m['sizes']['large'] + result << "" + end end end result << "
    " @@ -81,7 +85,7 @@ class TwitterApi end def tweet_uri_for(id) - URI.parse "#{BASE_URL}/1.1/statuses/show.json?id=#{id}" + URI.parse "#{BASE_URL}/1.1/statuses/show.json?id=#{id}&tweet_mode=extended" end unless defined? BASE_URL diff --git a/lib/version.rb b/lib/version.rb index 8699653467..c807b4a69c 100644 --- a/lib/version.rb +++ b/lib/version.rb @@ -5,7 +5,7 @@ module Discourse MAJOR = 1 MINOR = 8 TINY = 0 - PRE = 'beta7' + PRE = 'beta8' STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') end diff --git a/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 b/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 index 391a5d76ac..19cfc33d6d 100644 --- a/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 +++ b/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 @@ -120,9 +120,20 @@ export default Ember.Controller.extend({ return output; }, - @computed("pollOptionsCount", "isNumber") - disableInsert(count, isNumber) { - return isNumber ? false : (count < 2); + @computed("pollOptionsCount", "isNumber", "pollMin", "pollMax") + disableInsert(count, isNumber, pollMin, pollMax) { + return (pollMin >= pollMax) || (isNumber ? false : (count < 2)); + }, + + @computed("pollMin", "pollMax") + minMaxValueValidation(pollMin, pollMax) { + let options = { ok: true }; + + if (pollMin >= pollMax) { + options = { failed: true, reason: I18n.t("poll.ui_builder.help.invalid_values") }; + } + + return InputValidation.create(options); }, @computed("disableInsert") diff --git a/plugins/poll/assets/javascripts/discourse/templates/modal/poll-ui-builder.hbs b/plugins/poll/assets/javascripts/discourse/templates/modal/poll-ui-builder.hbs index a3e7566f58..50ed74ce9b 100644 --- a/plugins/poll/assets/javascripts/discourse/templates/modal/poll-ui-builder.hbs +++ b/plugins/poll/assets/javascripts/discourse/templates/modal/poll-ui-builder.hbs @@ -11,28 +11,29 @@ {{#if showMinMax}}
    - {{combo-box content=pollMinOptions - value=pollMin - valueAttribute="value" - class="poll-options-min"}} + {{input type='number' + value=pollMin + valueAttribute="value" + class="poll-options-min"}} + {{input-tip validation=minMaxValueValidation}}
    - {{combo-box content=pollMaxOptions - value=pollMax - valueAttribute="value" - class="poll-options-max"}} + {{input type='number' + value=pollMax + valueAttribute="value" + class="poll-options-max"}}
    {{#if isNumber}}
    - {{combo-box content=pollStepOptions - value=pollStep - valueAttribute="value" - class="poll-options-step"}} + {{input type='number' + value=pollStep + valueAttribute="value" + class="poll-options-step"}}
    {{/if}} {{/if}} diff --git a/plugins/poll/config/locales/client.en.yml b/plugins/poll/config/locales/client.en.yml index d70520a375..f2d8cb01d2 100644 --- a/plugins/poll/config/locales/client.en.yml +++ b/plugins/poll/config/locales/client.en.yml @@ -74,6 +74,7 @@ en: insert: Insert Poll help: options_count: Enter at least 2 options + invalid_values: Minimum value must be smaller than the maximum value. poll_type: label: Type regular: Single Choice diff --git a/public/500.ar.html b/public/500.ar.html index 22d7282604..72323ee844 100644 --- a/public/500.ar.html +++ b/public/500.ar.html @@ -1,11 +1,11 @@ -الخطأ 500 +آخ - الخطأ 500

    آخ

    -

    البرمجية وراء منصة المناقشة هذه واجهت مشكلة غير متوقعة. نعتذر عن الإزعاج.

    +

    البرمجية المشغّلة لمنصة المناقشة هذه واجهت مشكلة غير متوقعة. نعتذر على الإزعاج.

    خُزّنت معلومات مفصلة عن الخطأ، ووُلّد إشعار آلي. سنفحص المعلومات ونرى ما المشكلة.

    لا حاجة لاتخاذ أي إجراء آخر. ولكن لو استمر حدوث الخطأ، فيمكنك توفير تفاصيل إضافية أهمها الخطوات المتبعة لتكرار حدوث الخطأ، ونشرها بعد ذلك في موضوع في فئة المشاكل والأخطاء داخل الموقع.

    diff --git a/public/503.ar.html b/public/503.ar.html index aab544219f..f9c1f9e500 100644 --- a/public/503.ar.html +++ b/public/503.ar.html @@ -1,6 +1,6 @@ -الموقع تحت الصيانة +الموقع تحت الصيانة - Discourse.org diff --git a/script/import_scripts/socialcast/README.md b/script/import_scripts/socialcast/README.md index 84e5d66c89..403acc7147 100644 --- a/script/import_scripts/socialcast/README.md +++ b/script/import_scripts/socialcast/README.md @@ -10,12 +10,22 @@ password: 'my-socialcast-password' ``` Create the directory for the json files to export: `mkdir output` -Then run `ruby export.rb /path/to/config.yml` +Then run `bundle exec ruby export.rb /path/to/config.yml` -Create a category named "Socialcast Import" or all topics will be imported into -the "Uncategorized" category. +If desired, edit the `socialcast_message.rb` file to set the category +and tags for each topic based on the name of the Socialcast group it was +originally posted to. -Topics will be tagged with the names of the groups they were originally posted -in on Socialcast. +You must create categories with the same names first in your site. -To run the import, run `ruby import.rb` +All topics will get the `DEFAULT_TAG` at minimum. + +Topics posted to a group that matches any group name in the `TAGS_AND_CATEGORIES` +map will get the associated category and tags. + +Other topics will be tagged with the original groupname and placed in the +`DEFAULT_CATEGORY`. + +To run the import, run `bundle exec ruby import.rb` + +To run the import in a production, run `RAILS_ENV=production bundle exec ruby import.rb` diff --git a/script/import_scripts/socialcast/import.rb b/script/import_scripts/socialcast/import.rb index b28b1e5058..7aaee20e18 100644 --- a/script/import_scripts/socialcast/import.rb +++ b/script/import_scripts/socialcast/import.rb @@ -65,7 +65,6 @@ class ImportScripts::Socialcast < ImportScripts::Base post = Post.find(post_id) # already imported this topic else topic[:user_id] = user_id_from_imported_user_id(topic[:author_id]) || -1 - topic[:category] = 'Socialcast Import' post = create_post(topic, topic[:id]) diff --git a/script/import_scripts/socialcast/socialcast_message.rb b/script/import_scripts/socialcast/socialcast_message.rb index 115ab77b12..602252be94 100644 --- a/script/import_scripts/socialcast/socialcast_message.rb +++ b/script/import_scripts/socialcast/socialcast_message.rb @@ -5,6 +5,19 @@ require_relative 'create_title.rb' class SocialcastMessage + DEFAULT_CATEGORY = "Socialcast Import" + DEFAULT_TAG = "socialcast-import" + TAGS_AND_CATEGORIES = { + "somegroupname" => { + category: "Apple Stems", + tags: ["waxy", "tough"] + }, + "someothergroupname" => { + category: "Orange Peels", + tags: ["oily"] + } + } + def initialize message_json @parsed_json = JSON.parse message_json end @@ -16,7 +29,8 @@ class SocialcastMessage topic[:title] = title topic[:raw] = @parsed_json['body'] topic[:created_at] = Time.parse @parsed_json['created_at'] - topic[:tags] = [group] if group + topic[:tags] = tags + topic[:category] = category topic end @@ -24,8 +38,30 @@ class SocialcastMessage CreateTitle.from_body @parsed_json['body'] end + def tags + tags = [] + if group + if TAGS_AND_CATEGORIES[group] + tags = TAGS_AND_CATEGORIES[group][:tags] + else + tags << group + end + end + tags << DEFAULT_TAG + tags + end + + + def category + category = DEFAULT_CATEGORY + if group && TAGS_AND_CATEGORIES[group] + category = TAGS_AND_CATEGORIES[group][:category] + end + category + end + def group - @parsed_json['group']['groupname'] if @parsed_json['group'] + @parsed_json['group']['groupname'].downcase if @parsed_json['group'] && @parsed_json['group']['groupname'] end def url diff --git a/spec/components/html_prettify_spec.rb b/spec/components/html_prettify_spec.rb index 1f1b6fad2c..189bfec8b3 100644 --- a/spec/components/html_prettify_spec.rb +++ b/spec/components/html_prettify_spec.rb @@ -24,6 +24,8 @@ describe HtmlPrettify do t 'src="test.png"> yay', "src=“test.png”> yay" + t '\\\\mnt\\c', "\\\\mnt\\c" + t ERB::Util.html_escape(' yay'), "<img src=“test.png”> yay" end diff --git a/spec/components/post_creator_spec.rb b/spec/components/post_creator_spec.rb index b59758adb4..b7368c7851 100644 --- a/spec/components/post_creator_spec.rb +++ b/spec/components/post_creator_spec.rb @@ -4,9 +4,6 @@ require 'topic_subtype' describe PostCreator do - before do - end - let(:user) { Fabricate(:user) } let(:topic) { Fabricate(:topic, user: user) } @@ -80,7 +77,6 @@ describe PostCreator do end it "triggers extensibility events" do - creator # bypass a user_created event, can be removed when there is a UserCreator DiscourseEvent.expects(:trigger).with(:before_create_post, anything).once DiscourseEvent.expects(:trigger).with(:validate_post, anything).once DiscourseEvent.expects(:trigger).with(:topic_created, anything, anything, user).once diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index 3a409471f4..2d973fd3b6 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -431,7 +431,9 @@ HTML describe "custom emoji" do it "replaces the custom emoji" do - Emoji.stubs(:custom).returns([ Emoji.create_from_path('trout') ]) + CustomEmoji.create!(name: 'trout', upload: Fabricate(:upload)) + Emoji.clear_cache + expect(PrettyText.cook("hello :trout:")).to match(/]+trout[^>]+>/) end end diff --git a/spec/components/search_spec.rb b/spec/components/search_spec.rb index 5f1c210337..0cf29c59aa 100644 --- a/spec/components/search_spec.rb +++ b/spec/components/search_spec.rb @@ -397,12 +397,17 @@ describe Search do topic = Fabricate(:topic, category: category) topic_no_cat = Fabricate(:topic) + # includes subcategory in search + subcategory = Fabricate(:category, parent_category_id: category.id) + sub_topic = Fabricate(:topic, category: subcategory) + post = Fabricate(:post, topic: topic, user: topic.user ) _another_post = Fabricate(:post, topic: topic_no_cat, user: topic.user ) + sub_post = Fabricate(:post, raw: 'I am saying hello from a subcategory', topic: sub_topic, user: topic.user ) search = Search.execute('hello', search_context: category) - expect(search.posts.length).to eq(1) - expect(search.posts.first.id).to eq(post.id) + expect(search.posts.map(&:id).sort).to eq([post.id,sub_post.id].sort) + expect(search.posts.length).to eq(2) end end @@ -462,9 +467,49 @@ describe Search do it 'supports wiki' do topic = Fabricate(:topic) - Fabricate(:post, raw: 'this is a test 248', wiki: true, topic: topic) + topic_2 = Fabricate(:topic) + post = Fabricate(:post, raw: 'this is a test 248', wiki: true, topic: topic) + Fabricate(:post, raw: 'this is a test 248', wiki: false, topic: topic_2) - expect(Search.execute('test 248 in:wiki').posts.length).to eq(1) + expect(Search.execute('test 248').posts.length).to eq(2) + expect(Search.execute('test 248 in:wiki').posts.first).to eq(post) + end + + it 'supports searching for posts that the user has seen/unseen' do + topic = Fabricate(:topic) + topic_2 = Fabricate(:topic) + post = Fabricate(:post, raw: 'logan is longan', topic: topic) + post_2 = Fabricate(:post, raw: 'longan is logan', topic: topic_2) + + [post.user, topic.user].each do |user| + PostTiming.create!( + post_number: post.post_number, + topic: topic, + user: user, + msecs: 1 + ) + end + + expect(post.seen?(post.user)).to eq(true) + + expect(Search.execute('longan').posts.sort).to eq([post, post_2]) + + expect(Search.execute('longan in:seen', guardian: Guardian.new(post.user)).posts) + .to eq([post]) + + expect(Search.execute('longan in:seen').posts.sort).to eq([post, post_2]) + + expect(Search.execute('longan in:seen', guardian: Guardian.new(post_2.user)).posts) + .to eq([]) + + expect(Search.execute('longan', guardian: Guardian.new(post_2.user)).posts.sort) + .to eq([post, post_2]) + + expect(Search.execute('longan in:unseen', guardian: Guardian.new(post_2.user)).posts.sort) + .to eq([post, post_2]) + + expect(Search.execute('longan in:unseen', guardian: Guardian.new(post.user)).posts) + .to eq([post_2]) end it 'supports before and after, in:first, user:, @username' do diff --git a/spec/controllers/admin/emojis_controller_spec.rb b/spec/controllers/admin/emojis_controller_spec.rb index fa776bb892..5b769ab90a 100644 --- a/spec/controllers/admin/emojis_controller_spec.rb +++ b/spec/controllers/admin/emojis_controller_spec.rb @@ -16,10 +16,6 @@ describe Admin::EmojisController do end end - it "is a subclass of AdminController" do - expect(Admin::EmojisController < Admin::AdminController).to eq(true) - end - context "when logged in" do let!(:user) { log_in(:admin) } @@ -33,56 +29,6 @@ describe Admin::EmojisController do expect(json[0]["url"]).to eq(custom_emoji.url) end end - - context ".create" do - - before { Emoji.expects(:custom).returns([custom_emoji]) } - - context "name already exist" do - it "throws an error" do - message = MessageBus.track_publish do - xhr :post, :create, { name: "hello", file: "" } - end.first - - expect(response).to be_success - expect(message.data["errors"]).to be - end - end - - context "error while saving emoji" do - it "throws an error" do - Emoji.expects(:create_for).returns(nil) - message = MessageBus.track_publish do - xhr :post, :create, { name: "garbage", file: "" } - end.first - - expect(response).to be_success - expect(message.data["errors"]).to be - end - end - - it "works" do - Emoji.expects(:create_for).returns(custom_emoji2) - - message = MessageBus.track_publish do - xhr :post, :create, { name: "hello2", file: ""} - end.first - - expect(response).to be_success - - expect(message.data["name"]).to eq(custom_emoji2.name) - expect(message.data["url"]).to eq(custom_emoji2.url) - end - end - - context ".destroy" do - it "deletes the custom emoji" do - custom_emoji.expects(:remove) - Emoji.expects(:custom).returns([custom_emoji]) - xhr :delete, :destroy, id: "hello" - expect(response).to be_success - end - end end end diff --git a/spec/controllers/list_controller_spec.rb b/spec/controllers/list_controller_spec.rb index db81150915..5a4a94d800 100644 --- a/spec/controllers/list_controller_spec.rb +++ b/spec/controllers/list_controller_spec.rb @@ -49,13 +49,53 @@ describe ListController do end describe 'RSS feeds' do - - it 'renders RSS' do + it 'renders latest RSS' do get "latest_feed", format: :rss expect(response).to be_success expect(response.content_type).to eq('application/rss+xml') end + it 'renders top RSS' do + get "top_feed", format: :rss + expect(response).to be_success + expect(response.content_type).to eq('application/rss+xml') + end + + it 'renders all time top RSS' do + get "top_all_feed", format: :rss + expect(response).to be_success + expect(response.content_type).to eq('application/rss+xml') + end + + it 'renders yearly top RSS' do + get "top_yearly_feed", format: :rss + expect(response).to be_success + expect(response.content_type).to eq('application/rss+xml') + end + + it 'renders quarterly top RSS' do + get "top_quarterly_feed", format: :rss + expect(response).to be_success + expect(response.content_type).to eq('application/rss+xml') + end + + it 'renders monthly top RSS' do + get "top_monthly_feed", format: :rss + expect(response).to be_success + expect(response.content_type).to eq('application/rss+xml') + end + + it 'renders weekly top RSS' do + get "top_weekly_feed", format: :rss + expect(response).to be_success + expect(response.content_type).to eq('application/rss+xml') + end + + it 'renders daily top RSS' do + get "top_daily_feed", format: :rss + expect(response).to be_success + expect(response.content_type).to eq('application/rss+xml') + end end context 'category' do diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index 8c8ba76a89..98b198550a 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -426,7 +426,8 @@ describe PostsController do include_examples 'action requires login', :put, :bookmark, post_id: 2 describe 'when logged in' do - let(:post) { Fabricate(:post, user: log_in) } + let(:user) { log_in } + let(:post) { Fabricate(:post, user: user) } let(:private_message) { Fabricate(:private_message_post) } it "raises an error if the user doesn't have permission to see the post" do @@ -436,13 +437,39 @@ describe PostsController do end it 'creates a bookmark' do - PostAction.expects(:act).with(post.user, post, PostActionType.types[:bookmark]) xhr :put, :bookmark, post_id: post.id, bookmarked: 'true' + + post_action = PostAction.find_by(user:user, post: post) + + expect(post_action.post_action_type_id).to eq(PostActionType.types[:bookmark]) end - it 'removes a bookmark' do - PostAction.expects(:remove_act).with(post.user, post, PostActionType.types[:bookmark]) - xhr :put, :bookmark, post_id: post.id + context "removing a bookmark" do + let(:post_action) { PostAction.act(user, post, PostActionType.types[:bookmark]) } + let(:admin) { Fabricate(:admin) } + + it 'should be able to remove a bookmark' do + post_action + xhr :put, :bookmark, post_id: post.id + + expect(PostAction.find_by(id: post_action.id)).to eq(nil) + end + + describe "when user doesn't have permission to see bookmarked post" do + it "should still be able to remove a bookmark" do + post_action + post = post_action.post + topic = post.topic + topic.convert_to_private_message(admin) + topic.remove_allowed_user(admin, user.username) + + expect(Guardian.new(user).can_see_post?(post.reload)).to eq(false) + + xhr :put, :bookmark, post_id: post.id + + expect(PostAction.find_by(id: post_action.id)).to eq(nil) + end + end end end diff --git a/spec/controllers/site_controller_spec.rb b/spec/controllers/site_controller_spec.rb index 5e328f5a3e..1dccba86ad 100644 --- a/spec/controllers/site_controller_spec.rb +++ b/spec/controllers/site_controller_spec.rb @@ -24,4 +24,38 @@ describe SiteController do expect(json["mobile_logo_url"]).to eq("https://a.a/a.png") end end + + describe '.statistics' do + + it 'is visible for sites requiring login' do + SiteSetting.login_required = true + SiteSetting.share_anonymized_statistics = true + + xhr :get, :statistics + json = JSON.parse(response.body) + + expect(response).to be_success + expect(json["topic_count"]).to be_present + expect(json["post_count"]).to be_present + expect(json["user_count"]).to be_present + expect(json["topics_7_days"]).to be_present + expect(json["topics_30_days"]).to be_present + expect(json["posts_7_days"]).to be_present + expect(json["posts_30_days"]).to be_present + expect(json["users_7_days"]).to be_present + expect(json["users_30_days"]).to be_present + expect(json["active_users_7_days"]).to be_present + expect(json["active_users_30_days"]).to be_present + expect(json["like_count"]).to be_present + expect(json["likes_7_days"]).to be_present + expect(json["likes_30_days"]).to be_present + end + + it 'is not visible if site setting share_anonymized_statistics is disabled' do + SiteSetting.share_anonymized_statistics = false + + xhr :get, :statistics + expect(response).to redirect_to '/' + end + end end diff --git a/spec/controllers/user_avatars_controller_spec.rb b/spec/controllers/user_avatars_controller_spec.rb index 38c93ccb6f..d09bc36568 100644 --- a/spec/controllers/user_avatars_controller_spec.rb +++ b/spec/controllers/user_avatars_controller_spec.rb @@ -10,7 +10,7 @@ describe UserAvatarsController do end it 'returns an avatar if we are allowing the proxy' do - response = get :show_proxy_letter, version: 'v2', letter: 'a', color: 'aaaaaa', size: 20 + response = get :show_proxy_letter, version: 'v2', letter: 'a', color: 'aaaaaa', size: 360 expect(response.status).to eq(200) end end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index cc8d418516..e227dd7afd 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -191,6 +191,27 @@ describe UsersController do end end + describe '#perform_account_activation' do + describe 'when cookies contains a destination URL' do + let(:token) { 'asdadwewq' } + let(:user) { Fabricate(:user) } + + before do + UsersController.any_instance.stubs(:honeypot_or_challenge_fails?).returns(false) + EmailToken.expects(:confirm).with(token).returns(user) + end + + it 'should redirect to the URL' do + destination_url = 'http://thisisasite.com/somepath' + request.cookies[:destination_url] = destination_url + + put :perform_account_activation, token: token + + expect(response).to redirect_to(destination_url) + end + end + end + describe '.password_reset' do let(:user) { Fabricate(:user) } diff --git a/spec/fabricators/web_hook_fabricator.rb b/spec/fabricators/web_hook_fabricator.rb index 3d10b267a9..d9354fb59e 100644 --- a/spec/fabricators/web_hook_fabricator.rb +++ b/spec/fabricators/web_hook_fabricator.rb @@ -28,3 +28,11 @@ Fabricator(:topic_web_hook, from: :web_hook) do web_hook.web_hook_event_types = [transients[:topic_hook]] end end + +Fabricator(:user_web_hook, from: :web_hook) do + transient user_hook: WebHookEventType.find_by(name: 'user') + + after_build do |web_hook, transients| + web_hook.web_hook_event_types = [transients[:user_hook]] + end +end diff --git a/spec/integration/admin/emojis_spec.rb b/spec/integration/admin/emojis_spec.rb new file mode 100644 index 0000000000..5ea92ea6f3 --- /dev/null +++ b/spec/integration/admin/emojis_spec.rb @@ -0,0 +1,76 @@ +require 'rails_helper' + +RSpec.describe "Managing custom emojis" do + let(:admin) { Fabricate(:admin) } + let(:upload) { Fabricate(:upload) } + + before do + sign_in(admin) + end + + describe "creating a custom emoji" do + describe 'when upload is invalid' do + it 'should publish the right error' do + message = MessageBus.track_publish do + post("/admin/customize/emojis.json", { + name: 'test', + file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/fake.jpg") + }) + end.first + + expect(message.channel).to eq("/uploads/emoji") + expect(message.data["errors"]).to eq([I18n.t('upload.images.size_not_found')]) + end + end + + describe 'when emoji name already exists' do + it 'should publish the right error' do + CustomEmoji.create!(name: 'test', upload: upload) + + message = MessageBus.track_publish do + post("/admin/customize/emojis.json", { + name: 'test', + file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png") + }) + end.first + + expect(message.channel).to eq("/uploads/emoji") + + expect(message.data["errors"]).to eq([ + "Name #{I18n.t('activerecord.errors.models.custom_emoji.attributes.name.taken')}" + ]) + end + end + + it 'should allow an admin to add a custom emoji' do + Emoji.expects(:clear_cache) + + message = MessageBus.track_publish do + post("/admin/customize/emojis.json", { + name: 'test', + file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png") + }) + end.first + + custom_emoji = CustomEmoji.last + upload = custom_emoji.upload + + expect(upload.original_filename).to eq('logo.png') + expect(message.channel).to eq("/uploads/emoji") + expect(message.data["errors"]).to eq(nil) + expect(message.data["name"]).to eq(custom_emoji.name) + expect(message.data["url"]).to eq(upload.url) + end + end + + describe 'deleting a custom emoji' do + it 'should allow an admin to delete a custom emoji' do + custom_emoji = CustomEmoji.create!(name: 'test', upload: upload) + Emoji.clear_cache + + expect { delete "/admin/customize/emojis/#{custom_emoji.name}.json", name: 'test' } + .to change { Upload.count }.by(-1) + .and change { CustomEmoji.count }.by(-1) + end + end +end diff --git a/spec/jobs/about_stats_spec.rb b/spec/jobs/about_stats_spec.rb index 312b345db0..2f761bf4e2 100644 --- a/spec/jobs/about_stats_spec.rb +++ b/spec/jobs/about_stats_spec.rb @@ -5,8 +5,8 @@ describe Jobs::AboutStats do begin stats = About.fetch_stats.to_json cache_key = About.stats_cache_key + $redis.del(cache_key) - expect($redis.get(cache_key)).to eq(nil) expect(described_class.new.execute({})).to eq(stats) expect($redis.get(cache_key)).to eq(stats) ensure diff --git a/spec/jobs/clean_up_uploads_spec.rb b/spec/jobs/clean_up_uploads_spec.rb index 7f0bf461ae..e9f649cbe1 100644 --- a/spec/jobs/clean_up_uploads_spec.rb +++ b/spec/jobs/clean_up_uploads_spec.rb @@ -140,4 +140,14 @@ describe Jobs::CleanUpUploads do expect(Upload.find_by(id: upload.id)).to eq(upload) end + it "does not delete custom emojis" do + upload = fabricate_upload + CustomEmoji.create!(name: 'test', upload: upload) + + Jobs::CleanUpUploads.new.execute(nil) + + expect(Upload.find_by(id: @upload.id)).to eq(nil) + expect(Upload.find_by(id: upload.id)).to eq(upload) + end + end diff --git a/spec/jobs/emit_web_hook_event_spec.rb b/spec/jobs/emit_web_hook_event_spec.rb index c01ecb6569..b8e956c650 100644 --- a/spec/jobs/emit_web_hook_event_spec.rb +++ b/spec/jobs/emit_web_hook_event_spec.rb @@ -10,14 +10,10 @@ describe Jobs::EmitWebHookEvent do expect { subject.execute(event_type: 'post') }.to raise_error(Discourse::InvalidParameters) end - it 'raises an error when there is no event name' do + it 'raises an error when there is no event type' do expect { subject.execute(web_hook_id: 1) }.to raise_error(Discourse::InvalidParameters) end - it 'raises an error when event name is invalid' do - expect { subject.execute(web_hook_id: post_hook.id, event_type: 'post_random') }.to raise_error(Discourse::InvalidParameters) - end - it "doesn't emit when the hook is inactive" do Jobs::EmitWebHookEvent.any_instance.expects(:web_hook_request).never subject.execute(web_hook_id: inactive_hook.id, event_type: 'post', post_id: post.id) diff --git a/spec/jobs/enqueue_digest_emails_spec.rb b/spec/jobs/enqueue_digest_emails_spec.rb index f988629403..9d00e3dd4c 100644 --- a/spec/jobs/enqueue_digest_emails_spec.rb +++ b/spec/jobs/enqueue_digest_emails_spec.rb @@ -102,6 +102,15 @@ describe Jobs::EnqueueDigestEmails do end end + context 'too many bounces' do + let!(:bounce_user) { Fabricate(:active_user, last_seen_at: 6.month.ago) } + + it "doesn't return users with too many bounces" do + bounce_user.user_stat.update(bounce_score: SiteSetting.bounce_score_threshold + 1) + expect(Jobs::EnqueueDigestEmails.new.target_user_ids.include?(bounce_user.id)).to eq(false) + end + end + end describe '#execute' do diff --git a/spec/jobs/rebake_custom_emoji_posts_spec.rb b/spec/jobs/rebake_custom_emoji_posts_spec.rb new file mode 100644 index 0000000000..96d40decbd --- /dev/null +++ b/spec/jobs/rebake_custom_emoji_posts_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +RSpec.describe Jobs::RebakeCustomEmojiPosts do + it 'should rebake posts that are using a given custom emoji' do + upload = Fabricate(:upload) + custom_emoji = CustomEmoji.create!(name: 'test', upload: upload) + Emoji.clear_cache + post = Fabricate(:post, raw: 'some post with :test: yay') + + expect(post.reload.cooked).to eq( + "

    some post with \":test:\" yay

    " + ) + + custom_emoji.destroy! + Emoji.clear_cache + described_class.new.execute(name: 'test') + + expect(post.reload.cooked).to eq('

    some post with :test: yay

    ') + end +end diff --git a/spec/mailers/user_notifications_spec.rb b/spec/mailers/user_notifications_spec.rb index d24d76588f..3cd4ca74b4 100644 --- a/spec/mailers/user_notifications_spec.rb +++ b/spec/mailers/user_notifications_spec.rb @@ -471,7 +471,7 @@ describe UserNotifications do data: {original_username: username}.to_json ) end - describe '.user_mentioned' do + describe 'email building' do it "has a username" do expects_build_with(has_entry(:username, username)) end @@ -484,6 +484,10 @@ describe UserNotifications do expects_build_with(has_entry(:template, "user_notifications.#{mail_type}")) end + it "overrides the html part" do + expects_build_with(has_key(:html_override)) + end + it "has a message" do expects_build_with(has_key(:message)) end @@ -524,6 +528,18 @@ describe UserNotifications do User.any_instance.stubs(:suspended?).returns(true) expects_build_with(has_entry(:include_respond_instructions, false)) end + + context "when customized" do + let(:custom_body) { "You are now officially notified." } + + before do + TranslationOverride.upsert!("en", "user_notifications.user_#{notification_type}.text_body_template", custom_body) + end + + it "shouldn't use the default html_override" do + expects_build_with(Not(has_key(:html_override))) + end + end end end diff --git a/spec/models/embeddable_host_spec.rb b/spec/models/embeddable_host_spec.rb index fe73132851..700478871c 100644 --- a/spec/models/embeddable_host_spec.rb +++ b/spec/models/embeddable_host_spec.rb @@ -38,6 +38,12 @@ describe EmbeddableHost do expect(eh.host).to eq('localhost:8080') end + it "supports ports for ip addresses" do + eh = EmbeddableHost.new(host: '192.168.0.1:3000') + expect(eh).to be_valid + expect(eh.host).to eq('192.168.0.1:3000') + end + it "supports subdomains of localhost" do eh = EmbeddableHost.new(host: 'discourse.localhost') expect(eh).to be_valid diff --git a/spec/models/global_setting_spec.rb b/spec/models/global_setting_spec.rb index 7be0db648f..bc1ea0303f 100644 --- a/spec/models/global_setting_spec.rb +++ b/spec/models/global_setting_spec.rb @@ -1,7 +1,40 @@ require 'rails_helper' require 'tempfile' +class GlobalSetting + def self.reset_secret_key_base! + @safe_secret_key_base = nil + end +end + describe GlobalSetting do + + describe '.safe_secret_key_base' do + it 'sets redis token if it is somehow flushed after 30 seconds' do + + # we have to reset so we reset all times and test runs consistently + GlobalSetting.reset_secret_key_base! + + freeze_time Time.now + + token = GlobalSetting.safe_secret_key_base + $redis.without_namespace.del(GlobalSetting::REDIS_SECRET_KEY) + freeze_time Time.now + 20 + + GlobalSetting.safe_secret_key_base + new_token = $redis.without_namespace.get(GlobalSetting::REDIS_SECRET_KEY) + expect(new_token).to eq(nil) + + freeze_time Time.now + 11 + + GlobalSetting.safe_secret_key_base + + new_token = $redis.without_namespace.get(GlobalSetting::REDIS_SECRET_KEY) + expect(new_token).to eq(token) + + end + end + describe '.redis_config' do describe 'when slave config is not present' do it "should not set any connector" do diff --git a/spec/models/invite_redeemer_spec.rb b/spec/models/invite_redeemer_spec.rb index d1d93fda6b..39d718508e 100644 --- a/spec/models/invite_redeemer_spec.rb +++ b/spec/models/invite_redeemer_spec.rb @@ -43,6 +43,7 @@ describe InviteRedeemer do SiteSetting.must_approve_users = true inviter = invite.invited_by inviter.admin = true + Jobs.expects(:enqueue).with(:invite_password_instructions_email, has_entries(username: username)) user = invite_redeemer.redeem expect(user.name).to eq(name) @@ -88,6 +89,7 @@ describe InviteRedeemer do it "can set password" do inviter = invite.invited_by + Jobs.expects(:enqueue).with(:critical_user_email, has_entries(type: :signup)) user = InviteRedeemer.new(invite, username, name, password).redeem expect(user).to have_password expect(user.confirm_password?(password)).to eq(true) diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb index ed98c31ced..00ddc98ea7 100644 --- a/spec/models/invite_spec.rb +++ b/spec/models/invite_spec.rb @@ -224,6 +224,7 @@ describe Invite do it 'does not enqueue an email if the user has already set password' do Fabricate(:user, email: invite.email, password_hash: "7af7805c9ee3697ed1a83d5e3cb5a3a431d140933a87fdcdc5a42aeef9337f81") Jobs.expects(:enqueue).with(:invite_password_instructions_email, has_key(:username)).never + Jobs.expects(:enqueue).with(:critical_user_email, has_entries(type: :signup)) # should enqueue an account activation email invite.redeem end diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index 02ee99917c..fa45deb0e7 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -133,7 +133,7 @@ describe Notification do it 'updates the notification count on destroy' do Notification.any_instance.expects(:refresh_notification_count).returns(nil) - notification.destroy + notification.destroy! end end diff --git a/spec/models/post_mover_spec.rb b/spec/models/post_mover_spec.rb index 87d9384c8c..f67122fec4 100644 --- a/spec/models/post_mover_spec.rb +++ b/spec/models/post_mover_spec.rb @@ -206,7 +206,7 @@ describe PostMover do user, [p2.id, p3.id, p5.id], title: 'Logan is a pretty good movie' ) - expect(new_topic.posts.pluck(:id)).to eq([p2.id, p3.id]) + expect(new_topic.posts.pluck(:id).sort).to eq([p2.id, p3.id].sort) end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index f52089126b..dfee88c7fb 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1485,4 +1485,12 @@ describe User do end + describe '.human_users' do + it 'should only return users with a positive primary key' do + Fabricate(:user, id: -2) + user = Fabricate(:user) + + expect(User.human_users).to eq([user]) + end + end end diff --git a/spec/models/web_hook_event_type_spec.rb b/spec/models/web_hook_event_type_spec.rb deleted file mode 100644 index bd6b8ef41b..0000000000 --- a/spec/models/web_hook_event_type_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -describe WebHookEventType do - it { is_expected.to validate_presence_of :name } -end diff --git a/spec/models/web_hook_spec.rb b/spec/models/web_hook_spec.rb index 6c4c8fdfaa..f71ac30e11 100644 --- a/spec/models/web_hook_spec.rb +++ b/spec/models/web_hook_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'sidekiq/testing' describe WebHook do it { is_expected.to validate_presence_of :payload_url } @@ -100,49 +101,110 @@ describe WebHook do end describe 'enqueues hooks' do - let!(:post_hook) { Fabricate(:web_hook) } - let!(:topic_hook) { Fabricate(:topic_web_hook) } let(:user) { Fabricate(:user) } let(:admin) { Fabricate(:admin) } let(:topic) { Fabricate(:topic, user: user) } let(:post) { Fabricate(:post, topic: topic, user: user) } - let(:post2) { Fabricate(:post, topic: topic, user: user) } + + before do + SiteSetting.queue_jobs = true + end it 'should enqueue the right hooks for topic events' do - WebHook.expects(:enqueue_topic_hooks).once - PostCreator.create(user, { raw: 'post', title: 'topic', skip_validations: true }) + Fabricate(:topic_web_hook) - WebHook.expects(:enqueue_topic_hooks).once - PostDestroyer.new(user, post).destroy + Sidekiq::Testing.fake! do + post = PostCreator.create(user, { raw: 'post', title: 'topic', skip_validations: true }) + topic_id = post.topic_id + job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first - WebHook.expects(:enqueue_topic_hooks).once - PostDestroyer.new(user, post).recover + expect(job_args["event_name"]).to eq("topic_created") + expect(job_args["topic_id"]).to eq(topic_id) + + PostDestroyer.new(user, post).destroy + job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first + + expect(job_args["event_name"]).to eq("topic_destroyed") + expect(job_args["topic_id"]).to eq(topic_id) + + PostDestroyer.new(user, post).recover + job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first + + expect(job_args["event_name"]).to eq("topic_recovered") + expect(job_args["topic_id"]).to eq(topic_id) + end end it 'should enqueue the right hooks for post events' do - WebHook.expects(:enqueue_post_hooks).once - PostCreator.create(user, { raw: 'post', topic_id: topic.id, reply_to_post_number: 1, skip_validations: true }) + Fabricate(:web_hook) - # post destroy or recover triggers a moderator post - WebHook.expects(:enqueue_post_hooks).twice - PostDestroyer.new(user, post2).destroy + Sidekiq::Testing.fake! do + user + topic - WebHook.expects(:enqueue_post_hooks).twice - PostDestroyer.new(user, post2).recover + post = PostCreator.create(user, + raw: 'post', + topic_id: topic.id, + reply_to_post_number: 1, + skip_validations: true + ) + + job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first + Sidekiq::Worker.clear_all + + expect(job_args["event_name"]).to eq("post_created") + expect(job_args["post_id"]).to eq(post.id) + + # post destroy or recover triggers a moderator post + expect { PostDestroyer.new(user, post).destroy } + .to change { Jobs::EmitWebHookEvent.jobs.count }.by(2) + + job_args = Jobs::EmitWebHookEvent.jobs.first["args"].first + + expect(job_args["event_name"]).to eq("post_edited") + expect(job_args["post_id"]).to eq(post.id) + + job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first + + expect(job_args["event_name"]).to eq("post_destroyed") + expect(job_args["post_id"]).to eq(post.id) + + PostDestroyer.new(user, post).recover + job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first + + expect(job_args["event_name"]).to eq("post_recovered") + expect(job_args["post_id"]).to eq(post.id) + end end it 'should enqueue the right hooks for user events' do - WebHook.expects(:enqueue_hooks).once - user + user_web_hook = Fabricate(:user_web_hook, active: true) - WebHook.expects(:enqueue_hooks).once - admin + Sidekiq::Testing.fake! do + user + job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first - WebHook.expects(:enqueue_hooks).once - user.approve(admin) + expect(job_args["event_name"]).to eq("user_created") + expect(job_args["user_id"]).to eq(user.id) - WebHook.expects(:enqueue_hooks).once - UserUpdater.new(admin, user).update(username: 'testing123') + admin + job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first + + expect(job_args["event_name"]).to eq("user_created") + expect(job_args["user_id"]).to eq(admin.id) + + user.approve(admin) + job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first + + expect(job_args["event_name"]).to eq("user_approved") + expect(job_args["user_id"]).to eq(user.id) + + UserUpdater.new(admin, user).update(username: 'testing123') + job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first + + expect(job_args["event_name"]).to eq("user_updated") + expect(job_args["user_id"]).to eq(user.id) + end end end end diff --git a/test/javascripts/acceptance/category-edit-test.js.es6 b/test/javascripts/acceptance/category-edit-test.js.es6 index 389919018e..185cb7b216 100644 --- a/test/javascripts/acceptance/category-edit-test.js.es6 +++ b/test/javascripts/acceptance/category-edit-test.js.es6 @@ -57,3 +57,28 @@ test("Error Saving", assert => { assert.equal(find('#modal-alert').html(), "duplicate email"); }); }); + +test("Subcategory list settings", () => { + visit("/c/bug"); + + click('.edit-category'); + click('.edit-category-settings'); + + andThen(() => { + ok(!visible(".subcategory-list-style-field"), "subcategory list style isn't visible by default"); + }); + + click(".show-subcategory-list-field input[type=checkbox]"); + andThen(() => { + ok(visible(".subcategory-list-style-field"), "subcategory list style is shown if show subcategory list is checked"); + }); + + click('.edit-category-general'); + selectDropdown('.edit-category-tab-general .category-combobox', 2); + + click('.edit-category-settings'); + andThen(() => { + ok(!visible(".show-subcategory-list-field"), "show subcategory list isn't visible for child categories"); + ok(!visible(".subcategory-list-style-field"), "subcategory list style isn't visible for child categories"); + }); +}); diff --git a/test/javascripts/acceptance/group-edit-test.js.es6 b/test/javascripts/acceptance/group-edit-test.js.es6 index e4498bf793..023d9c95f4 100644 --- a/test/javascripts/acceptance/group-edit-test.js.es6 +++ b/test/javascripts/acceptance/group-edit-test.js.es6 @@ -1,10 +1,11 @@ -import { acceptance } from "helpers/qunit-helpers"; +import { acceptance, logIn } from "helpers/qunit-helpers"; -acceptance("Editing Group", { - loggedIn: true -}); +acceptance("Editing Group"); test("Editing group", () => { + logIn(); + Discourse.reset(); + visit("/groups/discourse/edit"); andThen(() => { @@ -29,3 +30,11 @@ test("Editing group", () => { ok(find('.group-edit-public[disabled]').length === 1, 'it should disable group public input'); }); }); + +test("Editing group as an anonymous user", () => { + visit("/groups/discourse/edit"); + + andThen(() => { + ok(count('.group-members tr') > 0, "it should redirect to members page for an anonymous user"); + }); +}); diff --git a/test/javascripts/acceptance/search-full-test.js.es6 b/test/javascripts/acceptance/search-full-test.js.es6 index 439ed16130..886dd4b13d 100644 --- a/test/javascripts/acceptance/search-full-test.js.es6 +++ b/test/javascripts/acceptance/search-full-test.js.es6 @@ -233,15 +233,18 @@ test("update in:private filter through advanced search ui", assert => { }); }); -test("update in:wiki filter through advanced search ui", assert => { +test("update in:seen filter through advanced search ui", assert => { visit("/search"); fillIn('.search input.full-page-search', 'none'); click('.search-advanced-btn'); - click('.search-advanced-options .in-wiki'); + click('.search-advanced-options .in-seen'); andThen(() => { - assert.ok(exists('.search-advanced-options .in-wiki:checked'), 'has "are wiki" populated'); - assert.equal(find('.search input.full-page-search').val(), "none in:wiki", 'has updated search term to "none in:wiki"'); + assert.ok(exists('.search-advanced-options .in-seen:checked'), 'it should check the right checkbox'); + + assert.equal(find('.search input.full-page-search').val(), "none in:seen", + 'it should update the search term' + ); }); }); diff --git a/test/javascripts/acceptance/topic-discovery-test.js.es6 b/test/javascripts/acceptance/topic-discovery-test.js.es6 index d6d1798d29..c0767e8282 100644 --- a/test/javascripts/acceptance/topic-discovery-test.js.es6 +++ b/test/javascripts/acceptance/topic-discovery-test.js.es6 @@ -13,6 +13,7 @@ test("Visit Discovery Pages", () => { andThen(() => { ok(exists(".topic-list"), "The list of topics was rendered"); ok(exists('.topic-list .topic-list-item'), "has topics"); + ok(!exists('.category-list'), "doesn't render subcategories"); ok($('body.category-bug').length, "has a custom css class for the category id on the body"); }); @@ -29,4 +30,17 @@ test("Visit Discovery Pages", () => { ok($('body.categories-list').length === 0, "removes the `categories-list` class"); ok(exists('.topic-list .topic-list-item'), "has topics"); }); + + visit("/c/feature"); + andThen(() => { + ok(exists(".topic-list"), "The list of topics was rendered"); + ok(exists(".category-boxes"), "The list of subcategories were rendered with box style"); + }); + + visit("/c/dev"); + andThen(() => { + ok(exists(".topic-list"), "The list of topics was rendered"); + ok(exists(".category-boxes-with-topics"), "The list of subcategories were rendered with box-with-featured-topics style"); + ok(exists(".category-boxes-with-topics .featured-topics"), "The featured topics are there too"); + }); }); diff --git a/test/javascripts/components/group-membership-button-test.js.es6 b/test/javascripts/components/group-membership-button-test.js.es6 index b1796078d8..90831ec9c5 100644 --- a/test/javascripts/components/group-membership-button-test.js.es6 +++ b/test/javascripts/components/group-membership-button-test.js.es6 @@ -58,4 +58,11 @@ test('userIsGroupUser', function() { this.subject().set('groupUserIds', undefined); equal(this.subject().get('userIsGroupUser'), false); + + this.subject().setProperties({ + groupUserIds: [1, 3], + model: { id: 1, is_group_user: false } + }); + + equal(this.subject().get('userIsGroupUser'), false); }); diff --git a/test/javascripts/fixtures/discovery_fixtures.js.es6 b/test/javascripts/fixtures/discovery_fixtures.js.es6 index 9e3c68bf2e..27bc78bd0c 100644 --- a/test/javascripts/fixtures/discovery_fixtures.js.es6 +++ b/test/javascripts/fixtures/discovery_fixtures.js.es6 @@ -3,5 +3,7 @@ export default { "/latest.json": {"users":[{"id":7204,"username":"reyman64","avatar_template":"/images/avatar.png"},{"id":1,"username":"sam","avatar_template":"/images/avatar.png"},{"id":5481,"username":"f0rkz","avatar_template":"/images/avatar.png"},{"id":6473,"username":"jkf","avatar_template":"/images/avatar.png"},{"id":6973,"username":"stellarhopper","avatar_template":"/images/avatar.png"},{"id":19,"username":"eviltrout","avatar_template":"/images/avatar.png"},{"id":14,"username":"clay","avatar_template":"/images/avatar.png"},{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"},{"id":1917,"username":"sil","avatar_template":"/images/avatar.png"},{"id":7197,"username":"peeja","avatar_template":"/images/avatar.png"},{"id":1995,"username":"zogstrip","avatar_template":"/images/avatar.png"},{"id":8021,"username":"Abhishek_Gupta","avatar_template":"/images/avatar.png"},{"id":2291,"username":"PabloC","avatar_template":"/images/avatar.png"},{"id":791,"username":"srid","avatar_template":"/images/avatar.png"},{"id":1580,"username":"ABillionSuns","avatar_template":"/images/avatar.png"},{"id":7270,"username":"mhurwi","avatar_template":"/images/avatar.png"},{"id":6695,"username":"illspirit","avatar_template":"/images/avatar.png"},{"id":6929,"username":"BCHK","avatar_template":"/images/avatar.png"},{"id":4385,"username":"jeans","avatar_template":"/images/avatar.png"},{"id":7073,"username":"5an1ty","avatar_template":"/images/avatar.png"},{"id":6626,"username":"riking","avatar_template":"/images/avatar.png"},{"id":4457,"username":"Lee_Ars","avatar_template":"/images/avatar.png"},{"id":4263,"username":"mcwumbly","avatar_template":"/images/avatar.png"},{"id":8134,"username":"iontishina","avatar_template":"/images/avatar.png"},{"id":2072,"username":"nXqd","avatar_template":"/images/avatar.png"},{"id":4983,"username":"hey_julien","avatar_template":"/images/avatar.png"},{"id":3657,"username":"steelmaiden","avatar_template":"/images/avatar.png"},{"id":2624,"username":"BowlingX","avatar_template":"/images/avatar.png"},{"id":8085,"username":"watchmanmonitor","avatar_template":"/images/avatar.png"},{"id":4612,"username":"Iszi","avatar_template":"/images/avatar.png"},{"id":8018,"username":"shivermetimbers","avatar_template":"/images/avatar.png"},{"id":6060,"username":"lightyear","avatar_template":"/images/avatar.png"},{"id":2,"username":"neil","avatar_template":"/images/avatar.png"},{"id":8037,"username":"printec","avatar_template":"/images/avatar.png"},{"id":3415,"username":"radq","avatar_template":"/images/avatar.png"},{"id":6283,"username":"hrishikesh","avatar_template":"/images/avatar.png"},{"id":471,"username":"BhaelOchon","avatar_template":"/images/avatar.png"},{"id":6548,"username":"michaeld","avatar_template":"/images/avatar.png"},{"id":7286,"username":"mrotsnahoj","avatar_template":"/images/avatar.png"},{"id":3169,"username":"dgw","avatar_template":"/images/avatar.png"},{"id":926,"username":"martinnormark","avatar_template":"/images/avatar.png"},{"id":2003,"username":"taylor","avatar_template":"/images/avatar.png"},{"id":369,"username":"CvX","avatar_template":"/images/avatar.png"},{"id":562,"username":"nightpool","avatar_template":"/images/avatar.png"},{"id":6653,"username":"amitfrid","avatar_template":"/images/avatar.png"},{"id":6677,"username":"Tropnevad","avatar_template":"/images/avatar.png"},{"id":5048,"username":"SneakySly","avatar_template":"/images/avatar.png"},{"id":7333,"username":"Jong","avatar_template":"/images/avatar.png"},{"id":3124,"username":"sipp11","avatar_template":"/images/avatar.png"},{"id":7604,"username":"citkane","avatar_template":"/images/avatar.png"},{"id":3929,"username":"ScotterC","avatar_template":"/images/avatar.png"},{"id":6680,"username":"cdman","avatar_template":"/images/avatar.png"},{"id":500,"username":"aeid","avatar_template":"/images/avatar.png"},{"id":8,"username":"geek","avatar_template":"/images/avatar.png"},{"id":606,"username":"Cafeine","avatar_template":"/images/avatar.png"}],"topic_list":{"can_create_topic":false,"more_topics_url":"/latest.json?page=1","draft":null,"draft_key":"new_topic","draft_sequence":null,"topics":[{"id":11557,"title":"Error after upgrade to 0.9.7.9+","fancy_title":"Error after upgrade to 0.9.7.9+","slug":"error-after-upgrade-to-0-9-7-9","posts_count":83,"reply_count":58,"highest_post_number":85,"image_url":null,"created_at":"2013-12-22T17:12:05.000-05:00","last_posted_at":"2014-01-16T00:52:30.000-05:00","bumped":true,"bumped_at":"2014-01-16T00:52:30.000-05:00","unseen":false,"pinned":true,"excerpt":"Hi, \n\nI'm using webfaction postgresql specific private instance to run discourse (custom port already configured for discourse 0.9.7.6). \n\nThis is not my first update, but this time i have an error. Impossible to upgrade…","visible":true,"closed":false,"archived":false,"views":1230,"like_count":40,"has_summary":true,"archetype":"regular","last_poster_username":"stellarhopper","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":7204},{"extras":null,"description":"Most Posts","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":5481},{"extras":null,"description":"Frequent Poster","user_id":6473},{"extras":"latest","description":"Most Recent Poster","user_id":6973}]},{"id":1,"title":"Welcome to meta.discourse.org","fancy_title":"Welcome to meta.discourse.org","slug":"welcome-to-meta-discourse-org","posts_count":5,"reply_count":5,"highest_post_number":23,"image_url":null,"created_at":"2013-01-31T23:52:28.000-05:00","last_posted_at":"2013-02-07T16:50:41.000-05:00","bumped":true,"bumped_at":"2013-02-07T11:57:34.000-05:00","unseen":false,"pinned":true,"excerpt":"Welcome to meta, the official site for discussing the next-gen open source Discourse forum software. You'll find topics on features, bugs, hosting, development, and general support here. \n\nDiscourse is early beta softwar…","visible":true,"closed":true,"archived":false,"views":13792,"like_count":108,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Most Posts","user_id":19},{"extras":null,"description":"Frequent Poster","user_id":14},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11997,"title":"Create topic in the future","fancy_title":"Create topic in the future","slug":"create-topic-in-the-future","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-16T12:14:36.000-05:00","last_posted_at":"2014-01-16T12:14:36.000-05:00","bumped":false,"bumped_at":"2014-01-16T12:14:36.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":7,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sil","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":1917}]},{"id":11996,"title":"It's really hard to navigate the Create Topic / Reply pane with the keyboard","fancy_title":"It’s really hard to navigate the Create Topic / Reply pane with the keyboard","slug":"its-really-hard-to-navigate-the-create-topic-reply-pane-with-the-keyboard","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2014-01-16T10:51:36.000-05:00","last_posted_at":"2014-01-16T11:11:10.000-05:00","bumped":true,"bumped_at":"2014-01-16T11:11:10.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":12,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":7197},{"extras":"latest","description":"Most Recent Poster","user_id":1995}]},{"id":11994,"title":"Cross domain rules, followed?","fancy_title":"Cross domain rules, followed?","slug":"cross-domain-rules-followed","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"/plugins/emoji/images/smile.png","created_at":"2014-01-16T09:59:15.000-05:00","last_posted_at":"2014-01-16T09:59:15.000-05:00","bumped":true,"bumped_at":"2014-01-16T11:04:32.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":15,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"Abhishek_Gupta","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":8021}]},{"id":11995,"title":"Discourse as a CAS Server","fancy_title":"Discourse as a CAS Server","slug":"discourse-as-a-cas-server","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-16T10:15:30.000-05:00","last_posted_at":"2014-01-16T10:15:31.000-05:00","bumped":true,"bumped_at":"2014-01-16T10:15:31.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":12,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"PabloC","category_id":6,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":2291}]},{"id":11993,"title":"How to check the user level via ajax?","fancy_title":"How to check the user level via ajax?","slug":"how-to-check-the-user-level-via-ajax","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-16T08:13:09.000-05:00","last_posted_at":"2014-01-16T08:13:09.000-05:00","bumped":true,"bumped_at":"2014-01-16T09:20:59.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":13,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"Abhishek_Gupta","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":8021}]},{"id":9540,"title":"Docker images for Discourse","fancy_title":"Docker images for Discourse","slug":"docker-images-for-discourse","posts_count":35,"reply_count":28,"highest_post_number":36,"image_url":null,"created_at":"2013-09-02T00:07:02.000-04:00","last_posted_at":"2014-01-16T07:47:18.000-05:00","bumped":true,"bumped_at":"2014-01-16T07:47:18.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":1322,"like_count":23,"has_summary":false,"archetype":"regular","last_poster_username":"illspirit","category_id":8,"posters":[{"extras":null,"description":"Original Poster","user_id":791},{"extras":null,"description":"Most Posts","user_id":1580},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":7270},{"extras":"latest","description":"Most Recent Poster","user_id":6695}]},{"id":11957,"title":"Daily Active Users, Monthly Active Users - Statistics Need","fancy_title":"Daily Active Users, Monthly Active Users - Statistics Need","slug":"daily-active-users-monthly-active-users-statistics-need","posts_count":8,"reply_count":4,"highest_post_number":8,"image_url":null,"created_at":"2014-01-14T13:40:56.000-05:00","last_posted_at":"2014-01-16T06:46:05.000-05:00","bumped":true,"bumped_at":"2014-01-16T06:46:05.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":97,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"jeans","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6929},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":4385}]},{"id":11973,"title":"Pressing Wrench Icon in the Categories section","fancy_title":"Pressing Wrench Icon in the Categories section","slug":"pressing-wrench-icon-in-the-categories-section","posts_count":6,"reply_count":3,"highest_post_number":6,"image_url":"/uploads/default/2907/d8d4e0accd5ee244.png","created_at":"2014-01-15T05:58:12.000-05:00","last_posted_at":"2014-01-16T05:15:52.000-05:00","bumped":true,"bumped_at":"2014-01-16T05:15:52.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":46,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"5an1ty","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":7073},{"extras":null,"description":"Most Posts","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6626}]},{"id":11835,"title":"The Road to Discourse 1.0","fancy_title":"The Road to Discourse 1.0","slug":"the-road-to-discourse-1-0","posts_count":6,"reply_count":2,"highest_post_number":6,"image_url":null,"created_at":"2014-01-08T19:08:44.000-05:00","last_posted_at":"2014-01-16T04:49:16.000-05:00","bumped":true,"bumped_at":"2014-01-16T04:49:16.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":421,"like_count":33,"has_summary":false,"archetype":"regular","last_poster_username":"iontishina","category_id":13,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Most Posts","user_id":4457},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":"latest","description":"Most Recent Poster","user_id":8134}]},{"id":11992,"title":"Specific customization for each category","fancy_title":"Specific customization for each category","slug":"specific-customization-for-each-category","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-16T04:04:58.000-05:00","last_posted_at":"2014-01-16T04:04:58.000-05:00","bumped":false,"bumped_at":"2014-01-16T04:04:58.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":18,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"nXqd","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":2072}]},{"id":9214,"title":"Please make category url shorter","fancy_title":"Please make category url shorter","slug":"please-make-category-url-shorter","posts_count":9,"reply_count":3,"highest_post_number":9,"image_url":null,"created_at":"2013-08-20T05:28:17.000-04:00","last_posted_at":"2014-01-16T04:02:46.000-05:00","bumped":true,"bumped_at":"2014-01-16T04:02:46.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":319,"like_count":13,"has_summary":false,"archetype":"regular","last_poster_username":"nXqd","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":4983},{"extras":null,"description":"Most Posts","user_id":3657},{"extras":null,"description":"Frequent Poster","user_id":2624},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":2072}]},{"id":11989,"title":"Where to change the email subject prefix","fancy_title":"Where to change the email subject prefix","slug":"where-to-change-the-email-subject-prefix","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":"/uploads/default/2919/adbfe0ff90353440.png","created_at":"2014-01-16T01:03:48.000-05:00","last_posted_at":"2014-01-16T03:20:09.000-05:00","bumped":true,"bumped_at":"2014-01-16T03:20:09.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":19,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":6,"posters":[{"extras":null,"description":"Original Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":10866,"title":"Header logo overflows the top header area","fancy_title":"Header logo overflows the top header area","slug":"header-logo-overflows-the-top-header-area","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2013-11-09T03:40:04.000-05:00","last_posted_at":"2014-01-16T02:27:52.000-05:00","bumped":true,"bumped_at":"2014-01-16T02:40:47.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":157,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"stellarhopper","category_id":6,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6973},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":11988,"title":"Could not locate Gemfile error","fancy_title":"Could not locate Gemfile error","slug":"could-not-locate-gemfile-error","posts_count":7,"reply_count":3,"highest_post_number":7,"image_url":null,"created_at":"2014-01-16T00:41:57.000-05:00","last_posted_at":"2014-01-16T01:20:46.000-05:00","bumped":true,"bumped_at":"2014-01-16T01:20:46.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":18,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":6,"posters":[{"extras":null,"description":"Original Poster","user_id":6973},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":6266,"title":"What sort of replies trigger a notice?","fancy_title":"What sort of replies trigger a notice?","slug":"what-sort-of-replies-trigger-a-notice","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2013-04-30T17:46:39.000-04:00","last_posted_at":"2014-01-16T00:52:21.000-05:00","bumped":true,"bumped_at":"2014-01-16T00:57:46.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":115,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":4612},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11610,"title":"Private replies that only admins can see","fancy_title":"Private replies that only admins can see","slug":"private-replies-that-only-admins-can-see","posts_count":21,"reply_count":20,"highest_post_number":23,"image_url":null,"created_at":"2013-12-26T20:31:10.000-05:00","last_posted_at":"2014-01-16T00:18:19.000-05:00","bumped":true,"bumped_at":"2014-01-16T00:18:19.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":206,"like_count":9,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":8018},{"extras":null,"description":"Most Posts","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":6060},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11888,"title":"Uncategorized topics not allowed, still seeing tag places","fancy_title":"Uncategorized topics not allowed, still seeing tag places","slug":"uncategorized-topics-not-allowed-still-seeing-tag-places","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2014-01-10T19:23:37.000-05:00","last_posted_at":"2014-01-15T22:41:25.000-05:00","bumped":true,"bumped_at":"2014-01-15T22:41:25.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":50,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"illspirit","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6695},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2}]},{"id":11985,"title":"Installation nearly installs on Centos 6.5 with Apache/Phusion","fancy_title":"Installation nearly installs on Centos 6.5 with Apache/Phusion","slug":"installation-nearly-installs-on-centos-6-5-with-apache-phusion","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-15T19:48:30.000-05:00","last_posted_at":"2014-01-15T19:48:30.000-05:00","bumped":false,"bumped_at":"2014-01-15T19:48:30.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":26,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"printec","category_id":6,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":8037}]},{"id":11981,"title":"Excluding categories from the top view?","fancy_title":"Excluding categories from the top view?","slug":"excluding-categories-from-the-top-view","posts_count":6,"reply_count":1,"highest_post_number":6,"image_url":"/uploads/default/_optimized/f01/22f/7ea01f77b9_690x355.png","created_at":"2014-01-15T15:01:37.000-05:00","last_posted_at":"2014-01-15T18:57:52.000-05:00","bumped":true,"bumped_at":"2014-01-15T18:57:47.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":43,"like_count":6,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":3415},{"extras":null,"description":"Most Posts","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":1995}]},{"id":9408,"title":"Different home page for regular vs. new user","fancy_title":"Different home page for regular vs. new user","slug":"different-home-page-for-regular-vs-new-user","posts_count":25,"reply_count":17,"highest_post_number":25,"image_url":null,"created_at":"2013-08-28T09:54:41.000-04:00","last_posted_at":"2014-01-15T18:33:16.000-05:00","bumped":true,"bumped_at":"2014-01-15T18:33:16.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":334,"like_count":21,"has_summary":false,"archetype":"regular","last_poster_username":"mcwumbly","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6283},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":1995},{"extras":null,"description":"Frequent Poster","user_id":471},{"extras":"latest","description":"Most Recent Poster","user_id":4263}]},{"id":11896,"title":"Problem creating new account","fancy_title":"Problem creating new account","slug":"problem-creating-new-account","posts_count":11,"reply_count":2,"highest_post_number":11,"image_url":null,"created_at":"2014-01-11T09:07:20.000-05:00","last_posted_at":"2014-01-15T20:50:05.000-05:00","bumped":true,"bumped_at":"2014-01-15T15:23:32.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":87,"like_count":6,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":6,"posters":[{"extras":null,"description":"Original Poster","user_id":6548},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":10511,"title":"External urls should open in new tab","fancy_title":"External urls should open in new tab","slug":"external-urls-should-open-in-new-tab","posts_count":7,"reply_count":3,"highest_post_number":7,"image_url":null,"created_at":"2013-10-20T14:54:27.000-04:00","last_posted_at":"2014-01-15T14:02:11.000-05:00","bumped":true,"bumped_at":"2014-01-15T14:01:55.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":242,"like_count":10,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":7286},{"extras":null,"description":"Most Posts","user_id":3169},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":1589,"title":"Keyboard shortcuts?","fancy_title":"Keyboard shortcuts?","slug":"keyboard-shortcuts","posts_count":19,"reply_count":10,"highest_post_number":20,"image_url":null,"created_at":"2013-02-06T14:05:01.000-05:00","last_posted_at":"2014-01-15T13:52:45.000-05:00","bumped":true,"bumped_at":"2014-01-15T13:52:45.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":754,"like_count":31,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":926},{"extras":null,"description":"Most Posts","user_id":2003},{"extras":null,"description":"Frequent Poster","user_id":369},{"extras":null,"description":"Frequent Poster","user_id":562},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11763,"title":"Google AdSense plugin is now available","fancy_title":"Google AdSense plugin is now available","slug":"google-adsense-plugin-is-now-available","posts_count":7,"reply_count":2,"highest_post_number":7,"image_url":"/uploads/default/_optimized/66d/cf0/d69e6709fe_496x500.PNG","created_at":"2014-01-05T14:28:58.000-05:00","last_posted_at":"2014-01-15T13:32:35.000-05:00","bumped":true,"bumped_at":"2014-01-15T13:32:35.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":213,"like_count":14,"has_summary":false,"archetype":"regular","last_poster_username":"michaeld","category_id":5,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6548},{"extras":null,"description":"Most Posts","user_id":6653},{"extras":null,"description":"Frequent Poster","user_id":6677},{"extras":null,"description":"Frequent Poster","user_id":5048},{"extras":null,"description":"Frequent Poster","user_id":7333}]},{"id":9151,"title":"Apple touch icon doesn't show if there is no sub domain","fancy_title":"Apple touch icon doesn’t show if there is no sub domain","slug":"apple-touch-icon-doesnt-show-if-there-is-no-sub-domain","posts_count":7,"reply_count":4,"highest_post_number":7,"image_url":null,"created_at":"2013-08-16T18:16:53.000-04:00","last_posted_at":"2014-01-15T17:10:18.000-05:00","bumped":true,"bumped_at":"2014-01-15T13:19:22.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":188,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3124},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":11977,"title":"Show subcategory topics in categories list summary","fancy_title":"Show subcategory topics in categories list summary","slug":"show-subcategory-topics-in-categories-list-summary","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":"/uploads/default/_optimized/084/4e4/8af88c0839_571x500.png","created_at":"2014-01-15T12:09:49.000-05:00","last_posted_at":"2014-01-15T12:50:04.000-05:00","bumped":true,"bumped_at":"2014-01-15T12:50:04.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":32,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":7604},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":10201,"title":"How To override an existing handlebars template from plugin","fancy_title":"How To override an existing handlebars template from plugin","slug":"how-to-override-an-existing-handlebars-template-from-plugin","posts_count":6,"reply_count":1,"highest_post_number":6,"image_url":null,"created_at":"2013-10-04T10:44:33.000-04:00","last_posted_at":"2014-01-15T12:35:01.000-05:00","bumped":true,"bumped_at":"2014-01-15T12:34:58.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":325,"like_count":6,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":3929},{"extras":null,"description":"Most Posts","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":6680},{"extras":null,"description":"Frequent Poster","user_id":2},{"extras":"latest","description":"Most Recent Poster","user_id":1995}]},{"id":531,"title":"Discourse and Wordpress Integration","fancy_title":"Discourse and Wordpress Integration","slug":"discourse-and-wordpress-integration","posts_count":76,"reply_count":64,"highest_post_number":78,"image_url":null,"created_at":"2013-02-05T18:56:37.000-05:00","last_posted_at":"2014-01-15T11:56:54.000-05:00","bumped":true,"bumped_at":"2014-01-15T11:56:54.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":3809,"like_count":84,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":5,"posters":[{"extras":null,"description":"Original Poster","user_id":500},{"extras":null,"description":"Most Posts","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":606},{"extras":"latest","description":"Most Recent Poster","user_id":32}]}]}}, "/categories.json": {"featured_users":[{"id":8021,"username":"Abhishek_Gupta","avatar_template":"/images/avatar.png"},{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"},{"id":6695,"username":"illspirit","avatar_template":"/images/avatar.png"},{"id":2,"username":"neil","avatar_template":"/images/avatar.png"},{"id":1995,"username":"zogstrip","avatar_template":"/images/avatar.png"},{"id":1917,"username":"sil","avatar_template":"/images/avatar.png"},{"id":4385,"username":"jeans","avatar_template":"/images/avatar.png"},{"id":2072,"username":"nXqd","avatar_template":"/images/avatar.png"},{"id":4263,"username":"mcwumbly","avatar_template":"/images/avatar.png"},{"id":2291,"username":"PabloC","avatar_template":"/images/avatar.png"},{"id":6973,"username":"stellarhopper","avatar_template":"/images/avatar.png"},{"id":1,"username":"sam","avatar_template":"/images/avatar.png"},{"id":8085,"username":"watchmanmonitor","avatar_template":"/images/avatar.png"},{"id":5428,"username":"abbat","avatar_template":"/images/avatar.png"},{"id":8208,"username":"maximaximums","avatar_template":"/images/avatar.png"},{"id":7995,"username":"Hunter","avatar_template":"/images/avatar.png"},{"id":7197,"username":"peeja","avatar_template":"/images/avatar.png"},{"id":7073,"username":"5an1ty","avatar_template":"/images/avatar.png"},{"id":6626,"username":"riking","avatar_template":"/images/avatar.png"},{"id":6548,"username":"michaeld","avatar_template":"/images/avatar.png"},{"id":8202,"username":"Matthieu","avatar_template":"/images/avatar.png"},{"id":6677,"username":"Tropnevad","avatar_template":"/images/avatar.png"},{"id":7333,"username":"Jong","avatar_template":"/images/avatar.png"},{"id":6018,"username":"robypez","avatar_template":"/images/avatar.png"},{"id":1580,"username":"ABillionSuns","avatar_template":"/images/avatar.png"},{"id":7030,"username":"naabster","avatar_template":"/images/avatar.png"},{"id":8163,"username":"znation","avatar_template":"/images/avatar.png"},{"id":19,"username":"eviltrout","avatar_template":"/images/avatar.png"},{"id":7796,"username":"almereyda","avatar_template":"/images/avatar.png"},{"id":8024,"username":"stefanobernardi","avatar_template":"/images/avatar.png"},{"id":5174,"username":"MaSe","avatar_template":"/images/avatar.png"},{"id":4534,"username":"Julien","avatar_template":"/images/avatar.png"},{"id":2316,"username":"pakl","avatar_template":"/images/avatar.png"},{"id":4457,"username":"Lee_Ars","avatar_template":"/images/avatar.png"},{"id":8134,"username":"iontishina","avatar_template":"/images/avatar.png"},{"id":8047,"username":"zooko","avatar_template":"/images/avatar.png"},{"id":7483,"username":"jhogendorn","avatar_template":"/images/avatar.png"},{"id":5548,"username":"pdbradley","avatar_template":"/images/avatar.png"},{"id":4755,"username":"andanthor","avatar_template":"/images/avatar.png"},{"id":7984,"username":"sophearak","avatar_template":"/images/avatar.png"},{"id":5351,"username":"erlend_sh","avatar_template":"/images/avatar.png"}],"category_list":{"can_create_category":false,"can_create_topic":false,"draft":null,"draft_key":"new_topic","draft_sequence":null,"categories":[{"id":1,"name":"bug","color":"e9dd00","text_color":"000000","slug":"bug","topic_count":660,"description":"Bug reports on Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","topic_url":"/t/category-definition-for-bug/2","read_restricted":false,"permission":null,"post_count":4318,"topics_day":0,"topics_week":18,"topics_month":54,"topics_year":658,"posts_day":0,"posts_week":330,"posts_month":574,"posts_year":4319,"description_excerpt":"Bug reports on Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","featured_user_ids":[8021,32,6695,2,1995],"topics":[{"id":11994,"title":"Cross domain rules, followed?","fancy_title":"Cross domain rules, followed?","slug":"cross-domain-rules-followed","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"/plugins/emoji/images/smile.png","created_at":"2014-01-16T09:59:15.000-05:00","last_posted_at":"2014-01-16T09:59:15.000-05:00","bumped":true,"bumped_at":"2014-01-16T11:04:32.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":8021,"username":"Abhishek_Gupta","avatar_template":"/images/avatar.png"}},{"id":11888,"title":"Uncategorized topics not allowed, still seeing tag places","fancy_title":"Uncategorized topics not allowed, still seeing tag places","slug":"uncategorized-topics-not-allowed-still-seeing-tag-places","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2014-01-10T19:23:37.000-05:00","last_posted_at":"2014-01-15T22:41:25.000-05:00","bumped":true,"bumped_at":"2014-01-15T22:41:25.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":6695,"username":"illspirit","avatar_template":"/images/avatar.png"}},{"id":9151,"title":"Apple touch icon doesn't show if there is no sub domain","fancy_title":"Apple touch icon doesn’t show if there is no sub domain","slug":"apple-touch-icon-doesnt-show-if-there-is-no-sub-domain","posts_count":7,"reply_count":4,"highest_post_number":7,"image_url":null,"created_at":"2013-08-16T18:16:53.000-04:00","last_posted_at":"2014-01-15T17:10:18.000-05:00","bumped":true,"bumped_at":"2014-01-15T13:19:22.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"last_poster":{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"}}]},{"id":2,"name":"feature","color":"0E76BD","text_color":"FFFFFF","slug":"feature","topic_count":727,"description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","topic_url":"/t/category-definition-for-feature/11","read_restricted":false,"permission":null,"post_count":6186,"topics_day":0,"topics_week":17,"topics_month":46,"topics_year":725,"posts_day":0,"posts_week":180,"posts_month":468,"posts_year":6187,"description_excerpt":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","featured_user_ids":[1917,4385,2072,32,4263],"topics":[{"id":11997,"title":"Create topic in the future","fancy_title":"Create topic in the future","slug":"create-topic-in-the-future","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-16T12:14:36.000-05:00","last_posted_at":"2014-01-16T12:14:36.000-05:00","bumped":false,"bumped_at":"2014-01-16T12:14:36.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":1917,"username":"sil","avatar_template":"/images/avatar.png"}},{"id":11957,"title":"Daily Active Users, Monthly Active Users - Statistics Need","fancy_title":"Daily Active Users, Monthly Active Users - Statistics Need","slug":"daily-active-users-monthly-active-users-statistics-need","posts_count":8,"reply_count":4,"highest_post_number":8,"image_url":null,"created_at":"2014-01-14T13:40:56.000-05:00","last_posted_at":"2014-01-16T06:46:05.000-05:00","bumped":true,"bumped_at":"2014-01-16T06:46:05.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":4385,"username":"jeans","avatar_template":"/images/avatar.png"}},{"id":11992,"title":"Specific customization for each category","fancy_title":"Specific customization for each category","slug":"specific-customization-for-each-category","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-16T04:04:58.000-05:00","last_posted_at":"2014-01-16T04:04:58.000-05:00","bumped":false,"bumped_at":"2014-01-16T04:04:58.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":2072,"username":"nXqd","avatar_template":"/images/avatar.png"}}]},{"id":6,"name":"support","color":"b99","text_color":"FFFFFF","slug":"support","topic_count":782,"description":"Support on configuring, using, and installing Discourse. Not for software development related topics, but for admins and end users configuring and using Discourse.","topic_url":"/t/category-definition-for-support/389","read_restricted":false,"permission":null,"post_count":5396,"topics_day":0,"topics_week":16,"topics_month":67,"topics_year":779,"posts_day":0,"posts_week":122,"posts_month":481,"posts_year":5400,"description_excerpt":"Support on configuring, using, and installing Discourse. Not for software development related topics, but for admins and end users configuring and using Discourse.","featured_user_ids":[2291,32,6973,1,8085],"topics":[{"id":11995,"title":"Discourse as a CAS Server","fancy_title":"Discourse as a CAS Server","slug":"discourse-as-a-cas-server","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-16T10:15:30.000-05:00","last_posted_at":"2014-01-16T10:15:31.000-05:00","bumped":true,"bumped_at":"2014-01-16T10:15:31.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":2291,"username":"PabloC","avatar_template":"/images/avatar.png"}},{"id":11989,"title":"Where to change the email subject prefix","fancy_title":"Where to change the email subject prefix","slug":"where-to-change-the-email-subject-prefix","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":"/uploads/default/2919/adbfe0ff90353440.png","created_at":"2014-01-16T01:03:48.000-05:00","last_posted_at":"2014-01-16T03:20:09.000-05:00","bumped":true,"bumped_at":"2014-01-16T03:20:09.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"}},{"id":10866,"title":"Header logo overflows the top header area","fancy_title":"Header logo overflows the top header area","slug":"header-logo-overflows-the-top-header-area","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2013-11-09T03:40:04.000-05:00","last_posted_at":"2014-01-16T02:27:52.000-05:00","bumped":true,"bumped_at":"2014-01-16T02:40:47.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":6973,"username":"stellarhopper","avatar_template":"/images/avatar.png"}}]},{"id":7,"name":"dev","color":"000","text_color":"FFFFFF","slug":"dev","topic_count":284,"description":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.","topic_url":"/t/category-definition-for-dev/1026","read_restricted":false,"permission":null,"post_count":2352,"topics_day":0,"topics_week":3,"topics_month":19,"topics_year":284,"posts_day":0,"posts_week":37,"posts_month":150,"posts_year":2353,"description_excerpt":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.","featured_user_ids":[8021,1995,5428,8208,7995],"topics":[{"id":3823,"title":"So, you want to help out with Discourse","fancy_title":"So, you want to help out with Discourse","slug":"so-you-want-to-help-out-with-discourse","posts_count":22,"reply_count":28,"highest_post_number":56,"image_url":null,"created_at":"2013-02-23T00:46:11.000-05:00","last_posted_at":"2014-01-12T21:33:12.000-05:00","bumped":true,"bumped_at":"2014-01-12T21:33:12.000-05:00","unseen":false,"pinned":true,"excerpt":"People are wondering, how it is they can help out with Discourse. \n\nWe have seen some chattering both here and on Github. \n\nI wanted to create a topic @eviltrout , @codinghorror and myself can keep up to date with clear…","visible":true,"closed":false,"archived":false,"last_poster":{"id":7995,"username":"Hunter","avatar_template":"/images/avatar.png"}},{"id":11993,"title":"How to check the user level via ajax?","fancy_title":"How to check the user level via ajax?","slug":"how-to-check-the-user-level-via-ajax","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-16T08:13:09.000-05:00","last_posted_at":"2014-01-16T08:13:09.000-05:00","bumped":true,"bumped_at":"2014-01-16T09:20:59.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":8021,"username":"Abhishek_Gupta","avatar_template":"/images/avatar.png"}},{"id":10201,"title":"How To override an existing handlebars template from plugin","fancy_title":"How To override an existing handlebars template from plugin","slug":"how-to-override-an-existing-handlebars-template-from-plugin","posts_count":6,"reply_count":1,"highest_post_number":6,"image_url":null,"created_at":"2013-10-04T10:44:33.000-04:00","last_posted_at":"2014-01-15T12:35:01.000-05:00","bumped":true,"bumped_at":"2014-01-15T12:34:58.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"last_poster":{"id":1995,"username":"zogstrip","avatar_template":"/images/avatar.png"}}]},{"id":9,"name":"ux","color":"5F497A","text_color":"FFFFFF","slug":"ux","topic_count":184,"description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","topic_url":"/t/category-definition-for-ux/2628","read_restricted":false,"permission":null,"post_count":1511,"topics_day":0,"topics_week":3,"topics_month":10,"topics_year":183,"posts_day":0,"posts_week":34,"posts_month":117,"posts_year":1511,"description_excerpt":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","featured_user_ids":[1995,7197,7073,1,6626],"topics":[{"id":11996,"title":"It's really hard to navigate the Create Topic / Reply pane with the keyboard","fancy_title":"It’s really hard to navigate the Create Topic / Reply pane with the keyboard","slug":"its-really-hard-to-navigate-the-create-topic-reply-pane-with-the-keyboard","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2014-01-16T10:51:36.000-05:00","last_posted_at":"2014-01-16T11:11:10.000-05:00","bumped":true,"bumped_at":"2014-01-16T11:11:10.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":1995,"username":"zogstrip","avatar_template":"/images/avatar.png"}},{"id":11973,"title":"Pressing Wrench Icon in the Categories section","fancy_title":"Pressing Wrench Icon in the Categories section","slug":"pressing-wrench-icon-in-the-categories-section","posts_count":6,"reply_count":3,"highest_post_number":6,"image_url":"/uploads/default/2907/d8d4e0accd5ee244.png","created_at":"2014-01-15T05:58:12.000-05:00","last_posted_at":"2014-01-16T05:15:52.000-05:00","bumped":true,"bumped_at":"2014-01-16T05:15:52.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":7073,"username":"5an1ty","avatar_template":"/images/avatar.png"}},{"id":5542,"title":"Title character requirements not very visible","fancy_title":"Title character requirements not very visible","slug":"title-character-requirements-not-very-visible","posts_count":24,"reply_count":11,"highest_post_number":24,"image_url":null,"created_at":"2013-04-02T20:09:59.000-04:00","last_posted_at":"2014-01-15T05:26:07.000-05:00","bumped":true,"bumped_at":"2014-01-15T05:26:04.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"last_poster":{"id":1995,"username":"zogstrip","avatar_template":"/images/avatar.png"}}]},{"id":5,"name":"extensibility","color":"FE8432","text_color":"FFFFFF","slug":"extensibility","topic_count":102,"description":"Topics about extending the functionality of Discourse with plugins, themes, add-ons, or other mechanisms for extensibility. ","topic_url":"/t/category-definition-for-extensibility/28","read_restricted":false,"permission":null,"post_count":964,"topics_day":0,"topics_week":2,"topics_month":18,"topics_year":102,"posts_day":0,"posts_week":17,"posts_month":76,"posts_year":964,"description_excerpt":"Topics about extending the functionality of Discourse with plugins, themes, add-ons, or other mechanisms for extensibility.","featured_user_ids":[6548,32,8202,6677,7333],"topics":[{"id":11763,"title":"Google AdSense plugin is now available","fancy_title":"Google AdSense plugin is now available","slug":"google-adsense-plugin-is-now-available","posts_count":7,"reply_count":2,"highest_post_number":7,"image_url":"/uploads/default/_optimized/66d/cf0/d69e6709fe_496x500.PNG","created_at":"2014-01-05T14:28:58.000-05:00","last_posted_at":"2014-01-15T13:32:35.000-05:00","bumped":true,"bumped_at":"2014-01-15T13:32:35.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":6548,"username":"michaeld","avatar_template":"/images/avatar.png"}},{"id":531,"title":"Discourse and Wordpress Integration","fancy_title":"Discourse and Wordpress Integration","slug":"discourse-and-wordpress-integration","posts_count":76,"reply_count":64,"highest_post_number":78,"image_url":null,"created_at":"2013-02-05T18:56:37.000-05:00","last_posted_at":"2014-01-15T11:56:54.000-05:00","bumped":true,"bumped_at":"2014-01-15T11:56:54.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"}},{"id":11965,"title":"In your opinion, what is the best wiki engine to be associated with discourse?","fancy_title":"In your opinion, what is the best wiki engine to be associated with discourse?","slug":"in-your-opinion-what-is-the-best-wiki-engine-to-be-associated-with-discourse","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-14T19:27:06.000-05:00","last_posted_at":"2014-01-14T19:27:06.000-05:00","bumped":false,"bumped_at":"2014-01-14T19:27:06.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":8202,"username":"Matthieu","avatar_template":"/images/avatar.png"}}]},{"id":8,"name":"hosting","color":"74CCED","text_color":"FFFFFF","slug":"hosting","topic_count":69,"description":"Topics about hosting Discourse, either on your own servers, in the cloud, or with specific hosting services.","topic_url":"/t/category-definition-for-hosting/2626","read_restricted":false,"permission":null,"post_count":664,"topics_day":0,"topics_week":2,"topics_month":2,"topics_year":69,"posts_day":0,"posts_week":15,"posts_month":35,"posts_year":664,"description_excerpt":"Topics about hosting Discourse, either on your own servers, in the cloud, or with specific hosting services.","featured_user_ids":[6695,1,6018,1580,7030],"topics":[{"id":9540,"title":"Docker images for Discourse","fancy_title":"Docker images for Discourse","slug":"docker-images-for-discourse","posts_count":35,"reply_count":28,"highest_post_number":36,"image_url":null,"created_at":"2013-09-02T00:07:02.000-04:00","last_posted_at":"2014-01-16T07:47:18.000-05:00","bumped":true,"bumped_at":"2014-01-16T07:47:18.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":6695,"username":"illspirit","avatar_template":"/images/avatar.png"}},{"id":11971,"title":"Installing Discourse on Ubuntu 12.04 with Parallels Plesk and Apache","fancy_title":"Installing Discourse on Ubuntu 12.04 with Parallels Plesk and Apache","slug":"installing-discourse-on-ubuntu-12-04-with-parallels-plesk-and-apache","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2014-01-15T04:23:38.000-05:00","last_posted_at":"2014-01-15T04:47:20.000-05:00","bumped":true,"bumped_at":"2014-01-15T04:47:20.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":7030,"username":"naabster","avatar_template":"/images/avatar.png"}},{"id":10844,"title":"Discourse in a Docker container","fancy_title":"Discourse in a Docker container","slug":"discourse-in-a-docker-container","posts_count":12,"reply_count":8,"highest_post_number":12,"image_url":null,"created_at":"2013-11-07T19:12:22.000-05:00","last_posted_at":"2014-01-11T14:43:53.000-05:00","bumped":true,"bumped_at":"2014-01-11T14:43:53.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":1,"username":"sam","avatar_template":"/images/avatar.png"}}]},{"id":17,"name":"uncategorized","color":"AB9364","text_color":"FFFFFF","slug":"uncategorized","topic_count":229,"description":"","topic_url":null,"read_restricted":false,"permission":null,"post_count":2138,"topics_day":0,"topics_week":0,"topics_month":9,"topics_year":229,"posts_day":1,"posts_week":11,"posts_month":183,"posts_year":2138,"description_excerpt":"","is_uncategorized":true,"featured_user_ids":[6973,32,1,1995,7073],"topics":[{"id":1,"title":"Welcome to meta.discourse.org","fancy_title":"Welcome to meta.discourse.org","slug":"welcome-to-meta-discourse-org","posts_count":5,"reply_count":5,"highest_post_number":23,"image_url":null,"created_at":"2013-01-31T23:52:28.000-05:00","last_posted_at":"2013-02-07T16:50:41.000-05:00","bumped":true,"bumped_at":"2013-02-07T11:57:34.000-05:00","unseen":false,"pinned":true,"excerpt":"Welcome to meta, the official site for discussing the next-gen open source Discourse forum software. You'll find topics on features, bugs, hosting, development, and general support here. \n\nDiscourse is early beta softwar…","visible":true,"closed":true,"archived":false,"last_poster":{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"}},{"id":11557,"title":"Error after upgrade to 0.9.7.9+","fancy_title":"Error after upgrade to 0.9.7.9+","slug":"error-after-upgrade-to-0-9-7-9","posts_count":83,"reply_count":58,"highest_post_number":85,"image_url":null,"created_at":"2013-12-22T17:12:05.000-05:00","last_posted_at":"2014-01-16T00:52:30.000-05:00","bumped":true,"bumped_at":"2014-01-16T00:52:30.000-05:00","unseen":false,"pinned":true,"excerpt":"Hi, \n\nI'm using webfaction postgresql specific private instance to run discourse (custom port already configured for discourse 0.9.7.6). \n\nThis is not my first update, but this time i have an error. Impossible to upgrade…","visible":true,"closed":false,"archived":false,"last_poster":{"id":6973,"username":"stellarhopper","avatar_template":"/images/avatar.png"}},{"id":6266,"title":"What sort of replies trigger a notice?","fancy_title":"What sort of replies trigger a notice?","slug":"what-sort-of-replies-trigger-a-notice","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2013-04-30T17:46:39.000-04:00","last_posted_at":"2014-01-16T00:52:21.000-05:00","bumped":true,"bumped_at":"2014-01-16T00:57:46.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"}}]},{"id":11,"name":"login","color":"edb400","text_color":"FFFFFF","slug":"login","topic_count":27,"description":"Topics about logging in to Discourse, using any standard third party provider (Twitter, Facebook, Google), traditional username and password, or with a custom plugin.","topic_url":"/t/category-definition-for-login/2828","read_restricted":false,"permission":null,"post_count":200,"topics_day":0,"topics_week":1,"topics_month":1,"topics_year":27,"posts_day":0,"posts_week":10,"posts_month":27,"posts_year":200,"description_excerpt":"Topics about logging in to Discourse, using any standard third party provider (Twitter, Facebook, Google), traditional username and password, or with a custom plugin.","featured_user_ids":[8163,19,7796,32,8024],"topics":[{"id":11959,"title":"Get current user information via JSON","fancy_title":"Get current user information via JSON","slug":"get-current-user-information-via-json","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2014-01-14T15:05:34.000-05:00","last_posted_at":"2014-01-14T16:43:28.000-05:00","bumped":true,"bumped_at":"2014-01-14T16:43:28.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":8163,"username":"znation","avatar_template":"/images/avatar.png"}},{"id":6242,"title":"Allow authentication via multiple services on one account","fancy_title":"Allow authentication via multiple services on one account","slug":"allow-authentication-via-multiple-services-on-one-account","posts_count":34,"reply_count":27,"highest_post_number":34,"image_url":null,"created_at":"2013-04-29T18:51:52.000-04:00","last_posted_at":"2014-01-14T00:25:42.000-05:00","bumped":true,"bumped_at":"2014-01-14T00:25:42.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":7796,"username":"almereyda","avatar_template":"/images/avatar.png"}},{"id":4738,"title":"Login support for browser password managers","fancy_title":"Login support for browser password managers","slug":"login-support-for-browser-password-managers","posts_count":6,"reply_count":2,"highest_post_number":6,"image_url":null,"created_at":"2013-03-13T17:55:29.000-04:00","last_posted_at":"2014-01-13T14:21:34.000-05:00","bumped":true,"bumped_at":"2014-01-13T14:21:34.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"}}]},{"id":3,"name":"meta","color":"aaa","text_color":"FFFFFF","slug":"meta","topic_count":79,"description":"Discussion about meta.discourse.org itself, the organization of this forum about Discourse, how it works, and how we can improve this site.","topic_url":"/t/category-definition-for-meta/24","read_restricted":false,"permission":null,"post_count":695,"topics_day":0,"topics_week":1,"topics_month":3,"topics_year":79,"posts_day":0,"posts_week":4,"posts_month":18,"posts_year":696,"description_excerpt":"Discussion about meta.discourse.org itself, the organization of this forum about Discourse, how it works, and how we can improve this site.","featured_user_ids":[19,8085,32,5174,4534],"topics":[{"id":5249,"title":"What is \"Meta\"?","fancy_title":"What is “Meta”?","slug":"what-is-meta","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2013-03-25T18:00:52.000-04:00","last_posted_at":"2013-03-25T18:00:56.000-04:00","bumped":false,"bumped_at":"2013-03-25T18:00:52.000-04:00","unseen":false,"pinned":true,"excerpt":"Meta means discussion of the discussion itself instead of the actual topic of the discussion. \n\nWhy do we need a meta category?\n\nMeta is where communities come together to decide who they are and what they are about. \n…","visible":true,"closed":false,"archived":false,"last_poster":{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"}},{"id":11943,"title":"How far to take user documentation?","fancy_title":"How far to take user documentation?","slug":"how-far-to-take-user-documentation","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":"/plugins/emoji/images/smile.png","created_at":"2014-01-13T19:21:26.000-05:00","last_posted_at":"2014-01-14T14:19:46.000-05:00","bumped":true,"bumped_at":"2014-01-14T14:19:46.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":19,"username":"eviltrout","avatar_template":"/images/avatar.png"}},{"id":11822,"title":"Search engine traffic share and level to Discourse","fancy_title":"Search engine traffic share and level to Discourse","slug":"search-engine-traffic-share-and-level-to-discourse","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2014-01-08T01:54:56.000-05:00","last_posted_at":"2014-01-08T02:21:25.000-05:00","bumped":true,"bumped_at":"2014-01-08T02:21:25.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"}}]},{"id":12,"name":"discourse hub","color":"b2c79f","text_color":"FFFFFF","slug":"discourse-hub","topic_count":4,"description":"Topics about current or future Discourse Hub functionality at discourse.org including nickname registration, global user pages, and the site directory.","topic_url":"/t/category-definition-for-discourse-hub/3038","read_restricted":false,"permission":null,"post_count":121,"topics_day":0,"topics_week":0,"topics_month":0,"topics_year":4,"posts_day":0,"posts_week":3,"posts_month":3,"posts_year":121,"description_excerpt":"Topics about current or future Discourse Hub functionality at discourse.org including nickname registration, global user pages, and the site directory.","featured_user_ids":[2,32,2316,6695,4457],"topics":[{"id":6547,"title":"Where to get discourse_org_access_key?","fancy_title":"Where to get discourse_org_access_key?","slug":"where-to-get-discourse-org-access-key","posts_count":13,"reply_count":4,"highest_post_number":13,"image_url":null,"created_at":"2013-05-10T22:06:08.000-04:00","last_posted_at":"2014-01-13T11:38:15.000-05:00","bumped":true,"bumped_at":"2014-01-13T11:38:15.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":2,"username":"neil","avatar_template":"/images/avatar.png"}},{"id":2544,"title":"Discourse central hub questions","fancy_title":"Discourse central hub questions","slug":"discourse-central-hub-questions","posts_count":51,"reply_count":44,"highest_post_number":52,"image_url":null,"created_at":"2013-02-09T04:28:21.000-05:00","last_posted_at":"2013-09-19T13:36:49.000-04:00","bumped":true,"bumped_at":"2013-09-19T14:04:08.000-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":2128,"username":"ultimape","avatar_template":"/images/avatar.png"}},{"id":424,"title":"What are the 'consequences' of changing your name?","fancy_title":"What are the ‘consequences’ of changing your name?","slug":"what-are-the-consequences-of-changing-your-name","posts_count":35,"reply_count":36,"highest_post_number":43,"image_url":null,"created_at":"2013-02-05T17:37:52.000-05:00","last_posted_at":"2013-09-19T13:55:11.000-04:00","bumped":true,"bumped_at":"2013-09-19T13:55:11.000-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":2128,"username":"ultimape","avatar_template":"/images/avatar.png"}}]},{"id":13,"name":"blog","color":"ED207B","text_color":"FFFFFF","slug":"blog","topic_count":14,"description":"Discussion topics generated from the official Discourse Blog. These topics are linked from the bottom of each blog entry where the blog comments would normally be.","topic_url":"/t/category-definition-for-blog/5250","read_restricted":false,"permission":null,"post_count":206,"topics_day":0,"topics_week":0,"topics_month":1,"topics_year":14,"posts_day":0,"posts_week":2,"posts_month":11,"posts_year":206,"description_excerpt":"Discussion topics generated from the official Discourse Blog. These topics are linked from the bottom of each blog entry where the blog comments would normally be.","featured_user_ids":[8134,32,4457,4263,1995],"topics":[{"id":11835,"title":"The Road to Discourse 1.0","fancy_title":"The Road to Discourse 1.0","slug":"the-road-to-discourse-1-0","posts_count":6,"reply_count":2,"highest_post_number":6,"image_url":null,"created_at":"2014-01-08T19:08:44.000-05:00","last_posted_at":"2014-01-16T04:49:16.000-05:00","bumped":true,"bumped_at":"2014-01-16T04:49:16.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":8134,"username":"iontishina","avatar_template":"/images/avatar.png"}},{"id":5751,"title":"Discourse as Your First Rails App","fancy_title":"Discourse as Your First Rails App","slug":"discourse-as-your-first-rails-app","posts_count":62,"reply_count":43,"highest_post_number":71,"image_url":null,"created_at":"2013-04-09T19:08:33.000-04:00","last_posted_at":"2013-12-19T18:27:37.000-05:00","bumped":true,"bumped_at":"2013-12-19T18:27:37.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":1995,"username":"zogstrip","avatar_template":"/images/avatar.png"}},{"id":5898,"title":"The Discourse Servers","fancy_title":"The Discourse Servers","slug":"the-discourse-servers","posts_count":42,"reply_count":32,"highest_post_number":42,"image_url":null,"created_at":"2013-04-15T15:19:09.000-04:00","last_posted_at":"2013-11-29T15:14:35.000-05:00","bumped":true,"bumped_at":"2013-11-29T15:14:35.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":6626,"username":"riking","avatar_template":"/images/avatar.png"}}]},{"id":4,"name":"faq","color":"33b","text_color":"FFFFFF","slug":"faq","topic_count":49,"description":"Topics that come up very often when discussing Discourse will eventually be classified into this Frequently Asked Questions category. Should only be added to popular topics.","topic_url":"/t/category-definition-for-faq/25","read_restricted":false,"permission":null,"post_count":450,"topics_day":0,"topics_week":0,"topics_month":0,"topics_year":49,"posts_day":0,"posts_week":1,"posts_month":10,"posts_year":450,"description_excerpt":"Topics that come up very often when discussing Discourse will eventually be classified into this Frequently Asked Questions category. Should only be added to popular topics.","featured_user_ids":[32,8047,7483,2,6626],"topics":[{"id":5372,"title":"UX confusion (or me confusion) is it possible to edit old posts or only your most recent post in a topic?","fancy_title":"UX confusion (or me confusion) is it possible to edit old posts or only your most recent post in a topic?","slug":"ux-confusion-or-me-confusion-is-it-possible-to-edit-old-posts-or-only-your-most-recent-post-in-a-topic","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-03-28T22:25:57.000-04:00","last_posted_at":"2014-01-13T13:44:39.000-05:00","bumped":true,"bumped_at":"2014-01-13T13:44:39.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"}},{"id":9631,"title":"All the options to deploy Discourse with their relative pros and cons","fancy_title":"All the options to deploy Discourse with their relative pros and cons","slug":"all-the-options-to-deploy-discourse-with-their-relative-pros-and-cons","posts_count":14,"reply_count":7,"highest_post_number":15,"image_url":null,"created_at":"2013-09-06T03:55:09.000-04:00","last_posted_at":"2013-09-26T18:49:04.000-04:00","bumped":true,"bumped_at":"2013-12-30T12:32:59.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":3929,"username":"ScotterC","avatar_template":"/images/avatar.png"}},{"id":4325,"title":"How to delete a user?","fancy_title":"How to delete a user?","slug":"how-to-delete-a-user","posts_count":31,"reply_count":23,"highest_post_number":33,"image_url":null,"created_at":"2013-03-01T23:18:55.000-05:00","last_posted_at":"2013-12-20T21:26:06.000-05:00","bumped":true,"bumped_at":"2013-12-20T21:26:06.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"}}]},{"id":14,"name":"marketplace","color":"8C6238","text_color":"FFFFFF","slug":"marketplace","topic_count":24,"description":"About commercial Discourse related stuff: jobs or paid gigs, plugins, themes, hosting, etc.","topic_url":"/t/category-definition-for-marketplace/5425","read_restricted":false,"permission":null,"post_count":106,"topics_day":0,"topics_week":1,"topics_month":3,"topics_year":24,"posts_day":0,"posts_week":1,"posts_month":7,"posts_year":106,"description_excerpt":"About commercial Discourse related stuff: jobs or paid gigs, plugins, themes, hosting, etc.","featured_user_ids":[6548,32,5548,2291,4755],"topics":[{"id":11866,"title":"DiscourseHosting is now accepting BTC payments","fancy_title":"DiscourseHosting is now accepting BTC payments","slug":"discoursehosting-is-now-accepting-btc-payments","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-10T10:17:28.000-05:00","last_posted_at":"2014-01-10T10:17:28.000-05:00","bumped":false,"bumped_at":"2014-01-10T10:17:28.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":6548,"username":"michaeld","avatar_template":"/images/avatar.png"}},{"id":11571,"title":"Looking for a developer for Discourse Customization","fancy_title":"Looking for a developer for Discourse Customization","slug":"looking-for-a-developer-for-discourse-customization","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2013-12-23T20:54:04.000-05:00","last_posted_at":"2013-12-24T13:12:17.000-05:00","bumped":true,"bumped_at":"2013-12-30T16:36:17.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":2291,"username":"PabloC","avatar_template":"/images/avatar.png"}},{"id":11594,"title":"Need someone to fix a topic in my discourse install that won't load for moderators. Will pay","fancy_title":"Need someone to fix a topic in my discourse install that won’t load for moderators. Will pay","slug":"need-someone-to-fix-a-topic-in-my-discourse-install-that-wont-load-for-moderators-will-pay","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2013-12-25T10:25:57.000-05:00","last_posted_at":"2013-12-26T17:01:41.000-05:00","bumped":true,"bumped_at":"2013-12-25T17:01:15.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"last_poster":{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"}}]},{"id":10,"name":"howto","color":"76923C","text_color":"FFFFFF","slug":"howto","topic_count":58,"description":"Tutorial topics that describe how to set up, configure, or install Discourse using a specific platform or environment. Topics in this category may only be created by trust level 2 and up. ","topic_url":"/t/category-definition-for-howto/2629","read_restricted":false,"permission":null,"post_count":677,"topics_day":0,"topics_week":0,"topics_month":1,"topics_year":58,"posts_day":0,"posts_week":0,"posts_month":13,"posts_year":675,"description_excerpt":"Tutorial topics that describe how to set up, configure, or install Discourse using a specific platform or environment. Topics in this category may only be created by trust level 2 and up.","featured_user_ids":[7984,4457,1995,6018,5351],"topics":[{"id":7582,"title":"Twitter login with Passenger + Varnish - quick lessons learned","fancy_title":"Twitter login with Passenger + Varnish - quick lessons learned","slug":"twitter-login-with-passenger-varnish-quick-lessons-learned","posts_count":9,"reply_count":3,"highest_post_number":9,"image_url":"/plugins/emoji/images/smile.png","created_at":"2013-06-17T19:46:31.000-04:00","last_posted_at":"2013-12-31T21:03:59.000-05:00","bumped":true,"bumped_at":"2013-12-31T21:03:59.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":7984,"username":"sophearak","avatar_template":"/images/avatar.png"}},{"id":7229,"title":"How to set up image uploads to S3?","fancy_title":"How to set up image uploads to S3?","slug":"how-to-set-up-image-uploads-to-s3","posts_count":14,"reply_count":11,"highest_post_number":14,"image_url":"/uploads/meta_discourse/1019/782cbc7e309ce43f.png","created_at":"2013-06-06T15:37:43.000-04:00","last_posted_at":"2013-12-31T11:54:18.000-05:00","bumped":true,"bumped_at":"2013-12-31T11:54:18.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":1995,"username":"zogstrip","avatar_template":"/images/avatar.png"}},{"id":11628,"title":"My experience with a successful migration (hints for a guide)","fancy_title":"My experience with a successful migration (hints for a guide)","slug":"my-experience-with-a-successful-migration-hints-for-a-guide","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-12-28T09:23:45.000-05:00","last_posted_at":"2013-12-28T10:38:48.000-05:00","bumped":true,"bumped_at":"2013-12-28T10:38:48.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"last_poster":{"id":6018,"username":"robypez","avatar_template":"/images/avatar.png"}}]}]}}, "/c/bug/l/latest.json": {"users":[{"id":1,"username":"sam","avatar_template":"/images/avatar.png"},{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"},{"id":8021,"username":"Abhishek_Gupta","avatar_template":"/images/avatar.png"},{"id":6695,"username":"illspirit","avatar_template":"/images/avatar.png"},{"id":2,"username":"neil","avatar_template":"/images/avatar.png"},{"id":3124,"username":"sipp11","avatar_template":"/images/avatar.png"},{"id":7513,"username":"digit","avatar_template":"/images/avatar.png"},{"id":19,"username":"eviltrout","avatar_template":"/images/avatar.png"},{"id":3,"username":"supermathie","avatar_template":"/images/avatar.png"},{"id":7073,"username":"5an1ty","avatar_template":"/images/avatar.png"},{"id":4996,"username":"wmertens","avatar_template":"/images/avatar.png"},{"id":6377,"username":"zh99998","avatar_template":"/images/avatar.png"},{"id":1496,"username":"cfstras","avatar_template":"/images/avatar.png"},{"id":7995,"username":"Hunter","avatar_template":"/images/avatar.png"},{"id":6626,"username":"riking","avatar_template":"/images/avatar.png"},{"id":1995,"username":"zogstrip","avatar_template":"/images/avatar.png"},{"id":5048,"username":"SneakySly","avatar_template":"/images/avatar.png"},{"id":7731,"username":"YOU","avatar_template":"/images/avatar.png"},{"id":7985,"username":"onlinedev","avatar_template":"/images/avatar.png"},{"id":3415,"username":"radq","avatar_template":"/images/avatar.png"},{"id":5351,"username":"erlend_sh","avatar_template":"/images/avatar.png"},{"id":471,"username":"BhaelOchon","avatar_template":"/images/avatar.png"},{"id":7,"username":"pekka","avatar_template":"/images/avatar.png"},{"id":4780,"username":"HugoAlmeida","avatar_template":"/images/avatar.png"},{"id":5053,"username":"Blue","avatar_template":"/images/avatar.png"},{"id":212,"username":"alxndr","avatar_template":"/images/avatar.png"},{"id":6118,"username":"lukelarris","avatar_template":"/images/avatar.png"},{"id":7076,"username":"philnelson","avatar_template":"/images/avatar.png"},{"id":4851,"username":"jab","avatar_template":"/images/avatar.png"},{"id":4457,"username":"Lee_Ars","avatar_template":"/images/avatar.png"},{"id":6280,"username":"mx2000","avatar_template":"/images/avatar.png"},{"id":3681,"username":"Ajarn","avatar_template":"/images/avatar.png"},{"id":1621,"username":"bnb","avatar_template":"/images/avatar.png"},{"id":6266,"username":"bragi","avatar_template":"/images/avatar.png"},{"id":5335,"username":"masda70","avatar_template":"/images/avatar.png"},{"id":6314,"username":"rafaelfranca","avatar_template":"/images/avatar.png"}],"topic_list":{"can_create_topic":false,"more_topics_url":"/latest.json?category=1&page=1","draft":null,"draft_key":"new_topic","draft_sequence":null,"topics":[{"id":2,"title":"Category definition for bug","fancy_title":"Category definition for bug","slug":"category-definition-for-bug","posts_count":2,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-01-31T23:56:34.000-05:00","last_posted_at":"2013-03-07T22:42:27.000-05:00","bumped":true,"bumped_at":"2013-02-26T18:52:56.000-05:00","unseen":false,"pinned":true,"excerpt":"Bug reports on Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","visible":true,"closed":false,"archived":false,"views":469,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11994,"title":"Cross domain rules, followed?","fancy_title":"Cross domain rules, followed?","slug":"cross-domain-rules-followed","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"/plugins/emoji/images/smile.png","created_at":"2014-01-16T09:59:15.000-05:00","last_posted_at":"2014-01-16T09:59:15.000-05:00","bumped":true,"bumped_at":"2014-01-16T11:04:32.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":15,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"Abhishek_Gupta","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":8021}]},{"id":11888,"title":"Uncategorized topics not allowed, still seeing tag places","fancy_title":"Uncategorized topics not allowed, still seeing tag places","slug":"uncategorized-topics-not-allowed-still-seeing-tag-places","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2014-01-10T19:23:37.000-05:00","last_posted_at":"2014-01-15T22:41:25.000-05:00","bumped":true,"bumped_at":"2014-01-15T22:41:25.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":50,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"illspirit","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6695},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2}]},{"id":9151,"title":"Apple touch icon doesn't show if there is no sub domain","fancy_title":"Apple touch icon doesn’t show if there is no sub domain","slug":"apple-touch-icon-doesnt-show-if-there-is-no-sub-domain","posts_count":7,"reply_count":4,"highest_post_number":7,"image_url":null,"created_at":"2013-08-16T18:16:53.000-04:00","last_posted_at":"2014-01-15T17:10:18.000-05:00","bumped":true,"bumped_at":"2014-01-15T13:19:22.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":188,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3124},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":10911,"title":"/users/activate-account pulling blank logo instead of defaulting to h2","fancy_title":"/users/activate-account pulling blank logo instead of defaulting to h2","slug":"users-activate-account-pulling-blank-logo-instead-of-defaulting-to-h2","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-11-12T14:49:04.000-05:00","last_posted_at":"2014-01-15T10:21:37.000-05:00","bumped":true,"bumped_at":"2014-01-15T10:21:37.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":121,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":7513},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":11937,"title":"Smiley parser is busted","fancy_title":"Smiley parser is busted","slug":"smiley-parser-is-busted","posts_count":4,"reply_count":4,"highest_post_number":7,"image_url":"/plugins/emoji/images/smile.png","created_at":"2014-01-13T15:42:00.000-05:00","last_posted_at":"2014-01-15T05:51:16.000-05:00","bumped":true,"bumped_at":"2014-01-15T05:51:16.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":66,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3},{"extras":null,"description":"Most Posts","user_id":7073},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":6625,"title":"Error 500 on PUT of site config","fancy_title":"Error 500 on PUT of site config","slug":"error-500-on-put-of-site-config","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2013-05-14T18:13:56.000-04:00","last_posted_at":"2014-01-16T04:55:50.000-05:00","bumped":true,"bumped_at":"2014-01-15T04:43:23.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":132,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":4996},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":11225,"title":"Forum acts weirdly after client side updates","fancy_title":"Forum acts weirdly after client side updates","slug":"forum-acts-weirdly-after-client-side-updates","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2013-12-02T18:32:10.000-05:00","last_posted_at":"2014-01-15T04:04:55.000-05:00","bumped":true,"bumped_at":"2014-01-15T02:55:18.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":117,"like_count":7,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":11903,"title":"Error after update to 0.9.8.1","fancy_title":"Error after update to 0.9.8.1","slug":"error-after-update-to-0-9-8-1","posts_count":14,"reply_count":6,"highest_post_number":17,"image_url":null,"created_at":"2014-01-12T06:55:45.000-05:00","last_posted_at":"2014-01-15T01:48:58.000-05:00","bumped":true,"bumped_at":"2014-01-15T01:48:58.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":121,"like_count":6,"has_summary":false,"archetype":"regular","last_poster_username":"zh99998","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6377},{"extras":null,"description":"Most Posts","user_id":1496},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":19}]},{"id":11969,"title":"Qunit error and possibly related ember.js problem","fancy_title":"Qunit error and possibly related ember.js problem","slug":"qunit-error-and-possibly-related-ember-js-problem","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-14T22:51:32.000-05:00","last_posted_at":"2014-01-14T22:51:32.000-05:00","bumped":false,"bumped_at":"2014-01-14T22:51:32.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":32,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"Hunter","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":7995}]},{"id":11945,"title":"Stuff disappears on the groups page","fancy_title":"Stuff disappears on the groups page","slug":"stuff-disappears-on-the-groups-page","posts_count":7,"reply_count":2,"highest_post_number":7,"image_url":null,"created_at":"2014-01-13T23:03:53.000-05:00","last_posted_at":"2014-01-15T01:26:07.000-05:00","bumped":true,"bumped_at":"2014-01-14T21:09:01.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":54,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":6695},{"extras":null,"description":"Most Posts","user_id":6626},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1995}]},{"id":11520,"title":"Discourse WordPress Plugin: Emoji's do not properly display","fancy_title":"Discourse WordPress Plugin: Emoji’s do not properly display","slug":"discourse-wordpress-plugin-emojis-do-not-properly-display","posts_count":9,"reply_count":4,"highest_post_number":9,"image_url":"/uploads/default/_optimized/638/4db/eff43a45b8_690x420.png","created_at":"2013-12-19T23:32:03.000-05:00","last_posted_at":"2014-01-15T04:32:19.000-05:00","bumped":true,"bumped_at":"2014-01-14T17:53:34.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":168,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5048},{"extras":null,"description":"Frequent Poster","user_id":7731},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":11597,"title":"All categories drop down does not close after clicking on first menu \"all categories\"","fancy_title":"All categories drop down does not close after clicking on first menu “all categories”","slug":"all-categories-drop-down-does-not-close-after-clicking-on-first-menu-all-categories","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":"/uploads/default/2495/f9efe463ae67632d.png","created_at":"2013-12-25T15:09:27.000-05:00","last_posted_at":"2014-01-14T17:46:41.000-05:00","bumped":true,"bumped_at":"2014-01-14T17:46:41.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":73,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"radq","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":7985},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":3415}]},{"id":11962,"title":"Editor When Clicking on Wrench Issue","fancy_title":"Editor When Clicking on Wrench Issue","slug":"editor-when-clicking-on-wrench-issue","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":"/uploads/default/_optimized/ca4/f70/ac7278b8f6_690x176.png","created_at":"2014-01-14T17:23:20.000-05:00","last_posted_at":"2014-01-14T17:24:02.000-05:00","bumped":true,"bumped_at":"2014-01-14T17:24:02.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":30,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":7073},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11831,"title":"Broken links, possibly related to HTTPS","fancy_title":"Broken links, possibly related to HTTPS","slug":"broken-links-possibly-related-to-https","posts_count":17,"reply_count":13,"highest_post_number":18,"image_url":null,"created_at":"2014-01-08T17:40:45.000-05:00","last_posted_at":"2014-01-14T16:03:07.000-05:00","bumped":true,"bumped_at":"2014-01-14T16:03:07.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":102,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5351},{"extras":null,"description":"Most Posts","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":471},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":11916,"title":"Unable to save user preferences","fancy_title":"Unable to save user preferences","slug":"unable-to-save-user-preferences","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2014-01-13T02:29:26.000-05:00","last_posted_at":"2014-01-14T14:39:32.000-05:00","bumped":true,"bumped_at":"2014-01-14T14:39:29.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":34,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":1995}]},{"id":10425,"title":"Editing category permissions: select value doesn't change","fancy_title":"Editing category permissions: select value doesn’t change","slug":"editing-category-permissions-select-value-doesnt-change","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"/uploads/meta_discourse/1956/d55fba29dbd7e1fe.png","created_at":"2013-10-17T18:20:20.000-04:00","last_posted_at":"2013-10-17T18:20:21.000-04:00","bumped":true,"bumped_at":"2014-01-14T13:35:37.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":92,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"pekka","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":7}]},{"id":6557,"title":"Middle clicking a link twice does not work as expected","fancy_title":"Middle clicking a link twice does not work as expected","slug":"middle-clicking-a-link-twice-does-not-work-as-expected","posts_count":10,"reply_count":7,"highest_post_number":10,"image_url":null,"created_at":"2013-05-11T13:56:02.000-04:00","last_posted_at":"2014-01-14T13:13:04.000-05:00","bumped":true,"bumped_at":"2014-01-14T13:13:04.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":401,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"neil","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":4780},{"extras":null,"description":"Most Posts","user_id":5053},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":2}]},{"id":11944,"title":"Regression: Cannot sort topic list","fancy_title":"Regression: Cannot sort topic list","slug":"regression-cannot-sort-topic-list","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":null,"created_at":"2014-01-13T20:14:06.000-05:00","last_posted_at":"2014-01-14T19:31:28.000-05:00","bumped":true,"bumped_at":"2014-01-14T07:31:19.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":true,"views":37,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":1995}]},{"id":10462,"title":"Rebake error when posts contain deleted YouTube video","fancy_title":"Rebake error when posts contain deleted YouTube video","slug":"rebake-error-when-posts-contain-deleted-youtube-video","posts_count":7,"reply_count":1,"highest_post_number":7,"image_url":null,"created_at":"2013-10-19T00:01:21.000-04:00","last_posted_at":"2014-01-14T02:24:19.000-05:00","bumped":true,"bumped_at":"2014-01-14T02:24:12.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":178,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":6695},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11932,"title":"Use of blockquote tag causes text outside a paragraph","fancy_title":"Use of blockquote tag causes text outside a paragraph","slug":"use-of-blockquote-tag-causes-text-outside-a-paragraph","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2014-01-13T13:38:15.000-05:00","last_posted_at":"2014-01-13T19:30:37.000-05:00","bumped":true,"bumped_at":"2014-01-14T02:22:58.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":54,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":10357,"title":"Displaced Wrench Icon Chrome","fancy_title":"Displaced Wrench Icon Chrome","slug":"displaced-wrench-icon-chrome","posts_count":12,"reply_count":4,"highest_post_number":12,"image_url":"/uploads/default/_optimized/9f3/f35/c5379beffe_690x300.jpg","created_at":"2013-10-14T05:48:21.000-04:00","last_posted_at":"2014-01-14T03:21:32.000-05:00","bumped":true,"bumped_at":"2014-01-13T19:03:33.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":206,"like_count":10,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":7073},{"extras":null,"description":"Frequent Poster","user_id":212},{"extras":null,"description":"Frequent Poster","user_id":6118},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":10114,"title":"Invitation expiry workflow is wonky","fancy_title":"Invitation expiry workflow is wonky","slug":"invitation-expiry-workflow-is-wonky","posts_count":14,"reply_count":7,"highest_post_number":14,"image_url":null,"created_at":"2013-09-30T00:59:36.000-04:00","last_posted_at":"2014-01-13T18:51:26.000-05:00","bumped":true,"bumped_at":"2014-01-13T18:51:26.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":176,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Most Posts","user_id":7076},{"extras":null,"description":"Frequent Poster","user_id":2},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":6330,"title":"Reply not disabled if topic closed while viewing","fancy_title":"Reply not disabled if topic closed while viewing","slug":"reply-not-disabled-if-topic-closed-while-viewing","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s=40&r=pg&d=identicon","created_at":"2013-05-02T06:02:06.000-04:00","last_posted_at":"2014-01-13T11:54:22.000-05:00","bumped":true,"bumped_at":"2014-01-13T11:54:22.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":164,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":4851},{"extras":null,"description":"Most Posts","user_id":2},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8367,"title":"Very fast scrolling fails to mark all posts read in a thread","fancy_title":"Very fast scrolling fails to mark all posts read in a thread","slug":"very-fast-scrolling-fails-to-mark-all-posts-read-in-a-thread","posts_count":11,"reply_count":7,"highest_post_number":13,"image_url":null,"created_at":"2013-07-14T12:37:02.000-04:00","last_posted_at":"2014-01-13T11:16:56.000-05:00","bumped":true,"bumped_at":"2014-01-13T11:16:33.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":288,"like_count":5,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":4457},{"extras":null,"description":"Most Posts","user_id":6280},{"extras":null,"description":"Frequent Poster","user_id":3681},{"extras":null,"description":"Frequent Poster","user_id":1621},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8815,"title":"Cache headers confuse proxies","fancy_title":"Cache headers confuse proxies","slug":"cache-headers-confuse-proxies","posts_count":9,"reply_count":3,"highest_post_number":9,"image_url":null,"created_at":"2013-08-02T05:45:26.000-04:00","last_posted_at":"2014-01-13T11:12:09.000-05:00","bumped":true,"bumped_at":"2014-01-13T10:41:44.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":314,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":6266},{"extras":null,"description":"Most Posts","user_id":19},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4457},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":32}]},{"id":11371,"title":"Search not working for Staff users","fancy_title":"Search not working for Staff users","slug":"search-not-working-for-staff-users","posts_count":15,"reply_count":10,"highest_post_number":15,"image_url":null,"created_at":"2013-12-11T13:22:56.000-05:00","last_posted_at":"2014-01-13T01:41:50.000-05:00","bumped":true,"bumped_at":"2014-01-13T01:41:46.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":217,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5335},{"extras":null,"description":"Most Posts","user_id":19},{"extras":null,"description":"Frequent Poster","user_id":6314},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":9908,"title":"Draft bar overrides pagination widget","fancy_title":"Draft bar overrides pagination widget","slug":"draft-bar-overrides-pagination-widget","posts_count":4,"reply_count":0,"highest_post_number":4,"image_url":null,"created_at":"2013-09-19T17:19:52.000-04:00","last_posted_at":"2014-01-13T01:26:01.000-05:00","bumped":true,"bumped_at":"2014-01-13T01:25:12.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":108,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5351},{"extras":null,"description":"Most Posts","user_id":471},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":6134,"title":"Unread topic is stuck as unread after insertion of staff message","fancy_title":"Unread topic is stuck as unread after insertion of staff message","slug":"unread-topic-is-stuck-as-unread-after-insertion-of-staff-message","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s=40&r=pg&d=identicon","created_at":"2013-04-24T13:37:32.000-04:00","last_posted_at":"2014-01-13T01:22:49.000-05:00","bumped":true,"bumped_at":"2014-01-13T01:22:42.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":169,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":5351},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11914,"title":"Google analytics is not registering page views","fancy_title":"Google analytics is not registering page views","slug":"google-analytics-is-not-registering-page-views","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-13T00:32:45.000-05:00","last_posted_at":"2014-01-13T00:32:46.000-05:00","bumped":true,"bumped_at":"2014-01-13T00:32:46.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":37,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":1}]}]}}, +"/c/feature/l/latest.json": {"users":[{"id":1,"username":"sam","avatar_template":"/images/avatar.png"},{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"},{"id":8021,"username":"Abhishek_Gupta","avatar_template":"/images/avatar.png"},{"id":6695,"username":"illspirit","avatar_template":"/images/avatar.png"},{"id":2,"username":"neil","avatar_template":"/images/avatar.png"},{"id":3124,"username":"sipp11","avatar_template":"/images/avatar.png"},{"id":7513,"username":"digit","avatar_template":"/images/avatar.png"},{"id":19,"username":"eviltrout","avatar_template":"/images/avatar.png"},{"id":3,"username":"supermathie","avatar_template":"/images/avatar.png"},{"id":7073,"username":"5an1ty","avatar_template":"/images/avatar.png"},{"id":4996,"username":"wmertens","avatar_template":"/images/avatar.png"},{"id":6377,"username":"zh99998","avatar_template":"/images/avatar.png"},{"id":1496,"username":"cfstras","avatar_template":"/images/avatar.png"},{"id":7995,"username":"Hunter","avatar_template":"/images/avatar.png"},{"id":6626,"username":"riking","avatar_template":"/images/avatar.png"},{"id":1995,"username":"zogstrip","avatar_template":"/images/avatar.png"},{"id":5048,"username":"SneakySly","avatar_template":"/images/avatar.png"},{"id":7731,"username":"YOU","avatar_template":"/images/avatar.png"},{"id":7985,"username":"onlinedev","avatar_template":"/images/avatar.png"},{"id":3415,"username":"radq","avatar_template":"/images/avatar.png"},{"id":5351,"username":"erlend_sh","avatar_template":"/images/avatar.png"},{"id":471,"username":"BhaelOchon","avatar_template":"/images/avatar.png"},{"id":7,"username":"pekka","avatar_template":"/images/avatar.png"},{"id":4780,"username":"HugoAlmeida","avatar_template":"/images/avatar.png"},{"id":5053,"username":"Blue","avatar_template":"/images/avatar.png"},{"id":212,"username":"alxndr","avatar_template":"/images/avatar.png"},{"id":6118,"username":"lukelarris","avatar_template":"/images/avatar.png"},{"id":7076,"username":"philnelson","avatar_template":"/images/avatar.png"},{"id":4851,"username":"jab","avatar_template":"/images/avatar.png"},{"id":4457,"username":"Lee_Ars","avatar_template":"/images/avatar.png"},{"id":6280,"username":"mx2000","avatar_template":"/images/avatar.png"},{"id":3681,"username":"Ajarn","avatar_template":"/images/avatar.png"},{"id":1621,"username":"bnb","avatar_template":"/images/avatar.png"},{"id":6266,"username":"bragi","avatar_template":"/images/avatar.png"},{"id":5335,"username":"masda70","avatar_template":"/images/avatar.png"},{"id":6314,"username":"rafaelfranca","avatar_template":"/images/avatar.png"}],"topic_list":{"can_create_topic":false,"more_topics_url":"/latest.json?category=2&page=1","draft":null,"draft_key":"new_topic","draft_sequence":null,"topics":[{"id":2,"title":"Category definition for feature","fancy_title":"Category definition for feature","slug":"category-definition-for-feature","posts_count":2,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-01-31T23:56:34.000-05:00","last_posted_at":"2013-03-07T22:42:27.000-05:00","bumped":true,"bumped_at":"2013-02-26T18:52:56.000-05:00","unseen":false,"pinned":true,"excerpt":"Features on Discourse.","visible":true,"closed":false,"archived":false,"views":469,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11994,"title":"Cross domain rules, followed?","fancy_title":"Cross domain rules, followed?","slug":"cross-domain-rules-followed","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"/plugins/emoji/images/smile.png","created_at":"2014-01-16T09:59:15.000-05:00","last_posted_at":"2014-01-16T09:59:15.000-05:00","bumped":true,"bumped_at":"2014-01-16T11:04:32.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":15,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"Abhishek_Gupta","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":8021}]},{"id":11888,"title":"Uncategorized topics not allowed, still seeing tag places","fancy_title":"Uncategorized topics not allowed, still seeing tag places","slug":"uncategorized-topics-not-allowed-still-seeing-tag-places","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2014-01-10T19:23:37.000-05:00","last_posted_at":"2014-01-15T22:41:25.000-05:00","bumped":true,"bumped_at":"2014-01-15T22:41:25.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":50,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"illspirit","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6695},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2}]},{"id":9151,"title":"Apple touch icon doesn't show if there is no sub domain","fancy_title":"Apple touch icon doesn’t show if there is no sub domain","slug":"apple-touch-icon-doesnt-show-if-there-is-no-sub-domain","posts_count":7,"reply_count":4,"highest_post_number":7,"image_url":null,"created_at":"2013-08-16T18:16:53.000-04:00","last_posted_at":"2014-01-15T17:10:18.000-05:00","bumped":true,"bumped_at":"2014-01-15T13:19:22.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":188,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":3124},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":10911,"title":"/users/activate-account pulling blank logo instead of defaulting to h2","fancy_title":"/users/activate-account pulling blank logo instead of defaulting to h2","slug":"users-activate-account-pulling-blank-logo-instead-of-defaulting-to-h2","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-11-12T14:49:04.000-05:00","last_posted_at":"2014-01-15T10:21:37.000-05:00","bumped":true,"bumped_at":"2014-01-15T10:21:37.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":121,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":7513},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":11937,"title":"Smiley parser is busted","fancy_title":"Smiley parser is busted","slug":"smiley-parser-is-busted","posts_count":4,"reply_count":4,"highest_post_number":7,"image_url":"/plugins/emoji/images/smile.png","created_at":"2014-01-13T15:42:00.000-05:00","last_posted_at":"2014-01-15T05:51:16.000-05:00","bumped":true,"bumped_at":"2014-01-15T05:51:16.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":66,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":3},{"extras":null,"description":"Most Posts","user_id":7073},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":6625,"title":"Error 500 on PUT of site config","fancy_title":"Error 500 on PUT of site config","slug":"error-500-on-put-of-site-config","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2013-05-14T18:13:56.000-04:00","last_posted_at":"2014-01-16T04:55:50.000-05:00","bumped":true,"bumped_at":"2014-01-15T04:43:23.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":132,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":4996},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":11225,"title":"Forum acts weirdly after client side updates","fancy_title":"Forum acts weirdly after client side updates","slug":"forum-acts-weirdly-after-client-side-updates","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2013-12-02T18:32:10.000-05:00","last_posted_at":"2014-01-15T04:04:55.000-05:00","bumped":true,"bumped_at":"2014-01-15T02:55:18.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":117,"like_count":7,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":11903,"title":"Error after update to 0.9.8.1","fancy_title":"Error after update to 0.9.8.1","slug":"error-after-update-to-0-9-8-1","posts_count":14,"reply_count":6,"highest_post_number":17,"image_url":null,"created_at":"2014-01-12T06:55:45.000-05:00","last_posted_at":"2014-01-15T01:48:58.000-05:00","bumped":true,"bumped_at":"2014-01-15T01:48:58.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":121,"like_count":6,"has_summary":false,"archetype":"regular","last_poster_username":"zh99998","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6377},{"extras":null,"description":"Most Posts","user_id":1496},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":19}]},{"id":11969,"title":"Qunit error and possibly related ember.js problem","fancy_title":"Qunit error and possibly related ember.js problem","slug":"qunit-error-and-possibly-related-ember-js-problem","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-14T22:51:32.000-05:00","last_posted_at":"2014-01-14T22:51:32.000-05:00","bumped":false,"bumped_at":"2014-01-14T22:51:32.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":32,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"Hunter","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":7995}]},{"id":11945,"title":"Stuff disappears on the groups page","fancy_title":"Stuff disappears on the groups page","slug":"stuff-disappears-on-the-groups-page","posts_count":7,"reply_count":2,"highest_post_number":7,"image_url":null,"created_at":"2014-01-13T23:03:53.000-05:00","last_posted_at":"2014-01-15T01:26:07.000-05:00","bumped":true,"bumped_at":"2014-01-14T21:09:01.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":54,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6695},{"extras":null,"description":"Most Posts","user_id":6626},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1995}]},{"id":11520,"title":"Discourse WordPress Plugin: Emoji's do not properly display","fancy_title":"Discourse WordPress Plugin: Emoji’s do not properly display","slug":"discourse-wordpress-plugin-emojis-do-not-properly-display","posts_count":9,"reply_count":4,"highest_post_number":9,"image_url":"/uploads/default/_optimized/638/4db/eff43a45b8_690x420.png","created_at":"2013-12-19T23:32:03.000-05:00","last_posted_at":"2014-01-15T04:32:19.000-05:00","bumped":true,"bumped_at":"2014-01-14T17:53:34.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":168,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":5048},{"extras":null,"description":"Frequent Poster","user_id":7731},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":11597,"title":"All categories drop down does not close after clicking on first menu \"all categories\"","fancy_title":"All categories drop down does not close after clicking on first menu “all categories”","slug":"all-categories-drop-down-does-not-close-after-clicking-on-first-menu-all-categories","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":"/uploads/default/2495/f9efe463ae67632d.png","created_at":"2013-12-25T15:09:27.000-05:00","last_posted_at":"2014-01-14T17:46:41.000-05:00","bumped":true,"bumped_at":"2014-01-14T17:46:41.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":73,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"radq","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":7985},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":3415}]},{"id":11962,"title":"Editor When Clicking on Wrench Issue","fancy_title":"Editor When Clicking on Wrench Issue","slug":"editor-when-clicking-on-wrench-issue","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":"/uploads/default/_optimized/ca4/f70/ac7278b8f6_690x176.png","created_at":"2014-01-14T17:23:20.000-05:00","last_posted_at":"2014-01-14T17:24:02.000-05:00","bumped":true,"bumped_at":"2014-01-14T17:24:02.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":30,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":7073},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11831,"title":"Broken links, possibly related to HTTPS","fancy_title":"Broken links, possibly related to HTTPS","slug":"broken-links-possibly-related-to-https","posts_count":17,"reply_count":13,"highest_post_number":18,"image_url":null,"created_at":"2014-01-08T17:40:45.000-05:00","last_posted_at":"2014-01-14T16:03:07.000-05:00","bumped":true,"bumped_at":"2014-01-14T16:03:07.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":102,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":5351},{"extras":null,"description":"Most Posts","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":471},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":11916,"title":"Unable to save user preferences","fancy_title":"Unable to save user preferences","slug":"unable-to-save-user-preferences","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2014-01-13T02:29:26.000-05:00","last_posted_at":"2014-01-14T14:39:32.000-05:00","bumped":true,"bumped_at":"2014-01-14T14:39:29.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":34,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":1995}]},{"id":10425,"title":"Editing category permissions: select value doesn't change","fancy_title":"Editing category permissions: select value doesn’t change","slug":"editing-category-permissions-select-value-doesnt-change","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"/uploads/meta_discourse/1956/d55fba29dbd7e1fe.png","created_at":"2013-10-17T18:20:20.000-04:00","last_posted_at":"2013-10-17T18:20:21.000-04:00","bumped":true,"bumped_at":"2014-01-14T13:35:37.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":92,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"pekka","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":7}]},{"id":6557,"title":"Middle clicking a link twice does not work as expected","fancy_title":"Middle clicking a link twice does not work as expected","slug":"middle-clicking-a-link-twice-does-not-work-as-expected","posts_count":10,"reply_count":7,"highest_post_number":10,"image_url":null,"created_at":"2013-05-11T13:56:02.000-04:00","last_posted_at":"2014-01-14T13:13:04.000-05:00","bumped":true,"bumped_at":"2014-01-14T13:13:04.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":401,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"neil","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":4780},{"extras":null,"description":"Most Posts","user_id":5053},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":2}]},{"id":11944,"title":"Regression: Cannot sort topic list","fancy_title":"Regression: Cannot sort topic list","slug":"regression-cannot-sort-topic-list","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":null,"created_at":"2014-01-13T20:14:06.000-05:00","last_posted_at":"2014-01-14T19:31:28.000-05:00","bumped":true,"bumped_at":"2014-01-14T07:31:19.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":true,"views":37,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":1995}]},{"id":10462,"title":"Rebake error when posts contain deleted YouTube video","fancy_title":"Rebake error when posts contain deleted YouTube video","slug":"rebake-error-when-posts-contain-deleted-youtube-video","posts_count":7,"reply_count":1,"highest_post_number":7,"image_url":null,"created_at":"2013-10-19T00:01:21.000-04:00","last_posted_at":"2014-01-14T02:24:19.000-05:00","bumped":true,"bumped_at":"2014-01-14T02:24:12.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":178,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6695},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11932,"title":"Use of blockquote tag causes text outside a paragraph","fancy_title":"Use of blockquote tag causes text outside a paragraph","slug":"use-of-blockquote-tag-causes-text-outside-a-paragraph","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2014-01-13T13:38:15.000-05:00","last_posted_at":"2014-01-13T19:30:37.000-05:00","bumped":true,"bumped_at":"2014-01-14T02:22:58.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":54,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":10357,"title":"Displaced Wrench Icon Chrome","fancy_title":"Displaced Wrench Icon Chrome","slug":"displaced-wrench-icon-chrome","posts_count":12,"reply_count":4,"highest_post_number":12,"image_url":"/uploads/default/_optimized/9f3/f35/c5379beffe_690x300.jpg","created_at":"2013-10-14T05:48:21.000-04:00","last_posted_at":"2014-01-14T03:21:32.000-05:00","bumped":true,"bumped_at":"2014-01-13T19:03:33.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":206,"like_count":10,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":7073},{"extras":null,"description":"Frequent Poster","user_id":212},{"extras":null,"description":"Frequent Poster","user_id":6118},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":10114,"title":"Invitation expiry workflow is wonky","fancy_title":"Invitation expiry workflow is wonky","slug":"invitation-expiry-workflow-is-wonky","posts_count":14,"reply_count":7,"highest_post_number":14,"image_url":null,"created_at":"2013-09-30T00:59:36.000-04:00","last_posted_at":"2014-01-13T18:51:26.000-05:00","bumped":true,"bumped_at":"2014-01-13T18:51:26.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":176,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Most Posts","user_id":7076},{"extras":null,"description":"Frequent Poster","user_id":2},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":6330,"title":"Reply not disabled if topic closed while viewing","fancy_title":"Reply not disabled if topic closed while viewing","slug":"reply-not-disabled-if-topic-closed-while-viewing","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s=40&r=pg&d=identicon","created_at":"2013-05-02T06:02:06.000-04:00","last_posted_at":"2014-01-13T11:54:22.000-05:00","bumped":true,"bumped_at":"2014-01-13T11:54:22.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":164,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":4851},{"extras":null,"description":"Most Posts","user_id":2},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8367,"title":"Very fast scrolling fails to mark all posts read in a thread","fancy_title":"Very fast scrolling fails to mark all posts read in a thread","slug":"very-fast-scrolling-fails-to-mark-all-posts-read-in-a-thread","posts_count":11,"reply_count":7,"highest_post_number":13,"image_url":null,"created_at":"2013-07-14T12:37:02.000-04:00","last_posted_at":"2014-01-13T11:16:56.000-05:00","bumped":true,"bumped_at":"2014-01-13T11:16:33.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":288,"like_count":5,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":4457},{"extras":null,"description":"Most Posts","user_id":6280},{"extras":null,"description":"Frequent Poster","user_id":3681},{"extras":null,"description":"Frequent Poster","user_id":1621},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8815,"title":"Cache headers confuse proxies","fancy_title":"Cache headers confuse proxies","slug":"cache-headers-confuse-proxies","posts_count":9,"reply_count":3,"highest_post_number":9,"image_url":null,"created_at":"2013-08-02T05:45:26.000-04:00","last_posted_at":"2014-01-13T11:12:09.000-05:00","bumped":true,"bumped_at":"2014-01-13T10:41:44.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":314,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6266},{"extras":null,"description":"Most Posts","user_id":19},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4457},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":32}]},{"id":11371,"title":"Search not working for Staff users","fancy_title":"Search not working for Staff users","slug":"search-not-working-for-staff-users","posts_count":15,"reply_count":10,"highest_post_number":15,"image_url":null,"created_at":"2013-12-11T13:22:56.000-05:00","last_posted_at":"2014-01-13T01:41:50.000-05:00","bumped":true,"bumped_at":"2014-01-13T01:41:46.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":217,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":5335},{"extras":null,"description":"Most Posts","user_id":19},{"extras":null,"description":"Frequent Poster","user_id":6314},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":9908,"title":"Draft bar overrides pagination widget","fancy_title":"Draft bar overrides pagination widget","slug":"draft-bar-overrides-pagination-widget","posts_count":4,"reply_count":0,"highest_post_number":4,"image_url":null,"created_at":"2013-09-19T17:19:52.000-04:00","last_posted_at":"2014-01-13T01:26:01.000-05:00","bumped":true,"bumped_at":"2014-01-13T01:25:12.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":108,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":5351},{"extras":null,"description":"Most Posts","user_id":471},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":6134,"title":"Unread topic is stuck as unread after insertion of staff message","fancy_title":"Unread topic is stuck as unread after insertion of staff message","slug":"unread-topic-is-stuck-as-unread-after-insertion-of-staff-message","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s=40&r=pg&d=identicon","created_at":"2013-04-24T13:37:32.000-04:00","last_posted_at":"2014-01-13T01:22:49.000-05:00","bumped":true,"bumped_at":"2014-01-13T01:22:42.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":169,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":5351},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11914,"title":"Google analytics is not registering page views","fancy_title":"Google analytics is not registering page views","slug":"google-analytics-is-not-registering-page-views","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-13T00:32:45.000-05:00","last_posted_at":"2014-01-13T00:32:46.000-05:00","bumped":true,"bumped_at":"2014-01-13T00:32:46.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":37,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":1}]}]}}, +"/c/dev/l/latest.json": {"users":[{"id":1,"username":"sam","avatar_template":"/images/avatar.png"},{"id":32,"username":"codinghorror","avatar_template":"/images/avatar.png"},{"id":8021,"username":"Abhishek_Gupta","avatar_template":"/images/avatar.png"},{"id":6695,"username":"illspirit","avatar_template":"/images/avatar.png"},{"id":2,"username":"neil","avatar_template":"/images/avatar.png"},{"id":3124,"username":"sipp11","avatar_template":"/images/avatar.png"},{"id":7513,"username":"digit","avatar_template":"/images/avatar.png"},{"id":19,"username":"eviltrout","avatar_template":"/images/avatar.png"},{"id":3,"username":"supermathie","avatar_template":"/images/avatar.png"},{"id":7073,"username":"5an1ty","avatar_template":"/images/avatar.png"},{"id":4996,"username":"wmertens","avatar_template":"/images/avatar.png"},{"id":6377,"username":"zh99998","avatar_template":"/images/avatar.png"},{"id":1496,"username":"cfstras","avatar_template":"/images/avatar.png"},{"id":7995,"username":"Hunter","avatar_template":"/images/avatar.png"},{"id":6626,"username":"riking","avatar_template":"/images/avatar.png"},{"id":1995,"username":"zogstrip","avatar_template":"/images/avatar.png"},{"id":5048,"username":"SneakySly","avatar_template":"/images/avatar.png"},{"id":7731,"username":"YOU","avatar_template":"/images/avatar.png"},{"id":7985,"username":"onlinedev","avatar_template":"/images/avatar.png"},{"id":3415,"username":"radq","avatar_template":"/images/avatar.png"},{"id":5351,"username":"erlend_sh","avatar_template":"/images/avatar.png"},{"id":471,"username":"BhaelOchon","avatar_template":"/images/avatar.png"},{"id":7,"username":"pekka","avatar_template":"/images/avatar.png"},{"id":4780,"username":"HugoAlmeida","avatar_template":"/images/avatar.png"},{"id":5053,"username":"Blue","avatar_template":"/images/avatar.png"},{"id":212,"username":"alxndr","avatar_template":"/images/avatar.png"},{"id":6118,"username":"lukelarris","avatar_template":"/images/avatar.png"},{"id":7076,"username":"philnelson","avatar_template":"/images/avatar.png"},{"id":4851,"username":"jab","avatar_template":"/images/avatar.png"},{"id":4457,"username":"Lee_Ars","avatar_template":"/images/avatar.png"},{"id":6280,"username":"mx2000","avatar_template":"/images/avatar.png"},{"id":3681,"username":"Ajarn","avatar_template":"/images/avatar.png"},{"id":1621,"username":"bnb","avatar_template":"/images/avatar.png"},{"id":6266,"username":"bragi","avatar_template":"/images/avatar.png"},{"id":5335,"username":"masda70","avatar_template":"/images/avatar.png"},{"id":6314,"username":"rafaelfranca","avatar_template":"/images/avatar.png"}],"topic_list":{"can_create_topic":false,"more_topics_url":"/latest.json?category=2&page=1","draft":null,"draft_key":"new_topic","draft_sequence":null,"topics":[{"id":2,"title":"Category definition for dev","fancy_title":"Category definition for dev","slug":"category-definition-for-dev","posts_count":2,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-01-31T23:56:34.000-05:00","last_posted_at":"2013-03-07T22:42:27.000-05:00","bumped":true,"bumped_at":"2013-02-26T18:52:56.000-05:00","unseen":false,"pinned":true,"excerpt":"Development of Discourse.","visible":true,"closed":false,"archived":false,"views":469,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11994,"title":"Cross domain rules, followed?","fancy_title":"Cross domain rules, followed?","slug":"cross-domain-rules-followed","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"/plugins/emoji/images/smile.png","created_at":"2014-01-16T09:59:15.000-05:00","last_posted_at":"2014-01-16T09:59:15.000-05:00","bumped":true,"bumped_at":"2014-01-16T11:04:32.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":15,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"Abhishek_Gupta","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":8021}]},{"id":11888,"title":"Uncategorized topics not allowed, still seeing tag places","fancy_title":"Uncategorized topics not allowed, still seeing tag places","slug":"uncategorized-topics-not-allowed-still-seeing-tag-places","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2014-01-10T19:23:37.000-05:00","last_posted_at":"2014-01-15T22:41:25.000-05:00","bumped":true,"bumped_at":"2014-01-15T22:41:25.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":50,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"illspirit","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6695},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2}]},{"id":9151,"title":"Apple touch icon doesn't show if there is no sub domain","fancy_title":"Apple touch icon doesn’t show if there is no sub domain","slug":"apple-touch-icon-doesnt-show-if-there-is-no-sub-domain","posts_count":7,"reply_count":4,"highest_post_number":7,"image_url":null,"created_at":"2013-08-16T18:16:53.000-04:00","last_posted_at":"2014-01-15T17:10:18.000-05:00","bumped":true,"bumped_at":"2014-01-15T13:19:22.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":188,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":3124},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":10911,"title":"/users/activate-account pulling blank logo instead of defaulting to h2","fancy_title":"/users/activate-account pulling blank logo instead of defaulting to h2","slug":"users-activate-account-pulling-blank-logo-instead-of-defaulting-to-h2","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-11-12T14:49:04.000-05:00","last_posted_at":"2014-01-15T10:21:37.000-05:00","bumped":true,"bumped_at":"2014-01-15T10:21:37.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":121,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":7513},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":11937,"title":"Smiley parser is busted","fancy_title":"Smiley parser is busted","slug":"smiley-parser-is-busted","posts_count":4,"reply_count":4,"highest_post_number":7,"image_url":"/plugins/emoji/images/smile.png","created_at":"2014-01-13T15:42:00.000-05:00","last_posted_at":"2014-01-15T05:51:16.000-05:00","bumped":true,"bumped_at":"2014-01-15T05:51:16.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":66,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":3},{"extras":null,"description":"Most Posts","user_id":7073},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":6625,"title":"Error 500 on PUT of site config","fancy_title":"Error 500 on PUT of site config","slug":"error-500-on-put-of-site-config","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2013-05-14T18:13:56.000-04:00","last_posted_at":"2014-01-16T04:55:50.000-05:00","bumped":true,"bumped_at":"2014-01-15T04:43:23.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":132,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":4996},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":11225,"title":"Forum acts weirdly after client side updates","fancy_title":"Forum acts weirdly after client side updates","slug":"forum-acts-weirdly-after-client-side-updates","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2013-12-02T18:32:10.000-05:00","last_posted_at":"2014-01-15T04:04:55.000-05:00","bumped":true,"bumped_at":"2014-01-15T02:55:18.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":117,"like_count":7,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":11903,"title":"Error after update to 0.9.8.1","fancy_title":"Error after update to 0.9.8.1","slug":"error-after-update-to-0-9-8-1","posts_count":14,"reply_count":6,"highest_post_number":17,"image_url":null,"created_at":"2014-01-12T06:55:45.000-05:00","last_posted_at":"2014-01-15T01:48:58.000-05:00","bumped":true,"bumped_at":"2014-01-15T01:48:58.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":121,"like_count":6,"has_summary":false,"archetype":"regular","last_poster_username":"zh99998","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6377},{"extras":null,"description":"Most Posts","user_id":1496},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":19}]},{"id":11969,"title":"Qunit error and possibly related ember.js problem","fancy_title":"Qunit error and possibly related ember.js problem","slug":"qunit-error-and-possibly-related-ember-js-problem","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-14T22:51:32.000-05:00","last_posted_at":"2014-01-14T22:51:32.000-05:00","bumped":false,"bumped_at":"2014-01-14T22:51:32.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":32,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"Hunter","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":7995}]},{"id":11945,"title":"Stuff disappears on the groups page","fancy_title":"Stuff disappears on the groups page","slug":"stuff-disappears-on-the-groups-page","posts_count":7,"reply_count":2,"highest_post_number":7,"image_url":null,"created_at":"2014-01-13T23:03:53.000-05:00","last_posted_at":"2014-01-15T01:26:07.000-05:00","bumped":true,"bumped_at":"2014-01-14T21:09:01.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":54,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":6695},{"extras":null,"description":"Most Posts","user_id":6626},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1995}]},{"id":11520,"title":"Discourse WordPress Plugin: Emoji's do not properly display","fancy_title":"Discourse WordPress Plugin: Emoji’s do not properly display","slug":"discourse-wordpress-plugin-emojis-do-not-properly-display","posts_count":9,"reply_count":4,"highest_post_number":9,"image_url":"/uploads/default/_optimized/638/4db/eff43a45b8_690x420.png","created_at":"2013-12-19T23:32:03.000-05:00","last_posted_at":"2014-01-15T04:32:19.000-05:00","bumped":true,"bumped_at":"2014-01-14T17:53:34.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":168,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":5048},{"extras":null,"description":"Frequent Poster","user_id":7731},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":11597,"title":"All categories drop down does not close after clicking on first menu \"all categories\"","fancy_title":"All categories drop down does not close after clicking on first menu “all categories”","slug":"all-categories-drop-down-does-not-close-after-clicking-on-first-menu-all-categories","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":"/uploads/default/2495/f9efe463ae67632d.png","created_at":"2013-12-25T15:09:27.000-05:00","last_posted_at":"2014-01-14T17:46:41.000-05:00","bumped":true,"bumped_at":"2014-01-14T17:46:41.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":73,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"radq","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":7985},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":3415}]},{"id":11962,"title":"Editor When Clicking on Wrench Issue","fancy_title":"Editor When Clicking on Wrench Issue","slug":"editor-when-clicking-on-wrench-issue","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":"/uploads/default/_optimized/ca4/f70/ac7278b8f6_690x176.png","created_at":"2014-01-14T17:23:20.000-05:00","last_posted_at":"2014-01-14T17:24:02.000-05:00","bumped":true,"bumped_at":"2014-01-14T17:24:02.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":30,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":7073},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11831,"title":"Broken links, possibly related to HTTPS","fancy_title":"Broken links, possibly related to HTTPS","slug":"broken-links-possibly-related-to-https","posts_count":17,"reply_count":13,"highest_post_number":18,"image_url":null,"created_at":"2014-01-08T17:40:45.000-05:00","last_posted_at":"2014-01-14T16:03:07.000-05:00","bumped":true,"bumped_at":"2014-01-14T16:03:07.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":102,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":5351},{"extras":null,"description":"Most Posts","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":471},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":11916,"title":"Unable to save user preferences","fancy_title":"Unable to save user preferences","slug":"unable-to-save-user-preferences","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2014-01-13T02:29:26.000-05:00","last_posted_at":"2014-01-14T14:39:32.000-05:00","bumped":true,"bumped_at":"2014-01-14T14:39:29.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":34,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":1995}]},{"id":10425,"title":"Editing category permissions: select value doesn't change","fancy_title":"Editing category permissions: select value doesn’t change","slug":"editing-category-permissions-select-value-doesnt-change","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"/uploads/meta_discourse/1956/d55fba29dbd7e1fe.png","created_at":"2013-10-17T18:20:20.000-04:00","last_posted_at":"2013-10-17T18:20:21.000-04:00","bumped":true,"bumped_at":"2014-01-14T13:35:37.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":92,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"pekka","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":7}]},{"id":6557,"title":"Middle clicking a link twice does not work as expected","fancy_title":"Middle clicking a link twice does not work as expected","slug":"middle-clicking-a-link-twice-does-not-work-as-expected","posts_count":10,"reply_count":7,"highest_post_number":10,"image_url":null,"created_at":"2013-05-11T13:56:02.000-04:00","last_posted_at":"2014-01-14T13:13:04.000-05:00","bumped":true,"bumped_at":"2014-01-14T13:13:04.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":401,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"neil","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":4780},{"extras":null,"description":"Most Posts","user_id":5053},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":2}]},{"id":11944,"title":"Regression: Cannot sort topic list","fancy_title":"Regression: Cannot sort topic list","slug":"regression-cannot-sort-topic-list","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":null,"created_at":"2014-01-13T20:14:06.000-05:00","last_posted_at":"2014-01-14T19:31:28.000-05:00","bumped":true,"bumped_at":"2014-01-14T07:31:19.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":true,"views":37,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":1995}]},{"id":10462,"title":"Rebake error when posts contain deleted YouTube video","fancy_title":"Rebake error when posts contain deleted YouTube video","slug":"rebake-error-when-posts-contain-deleted-youtube-video","posts_count":7,"reply_count":1,"highest_post_number":7,"image_url":null,"created_at":"2013-10-19T00:01:21.000-04:00","last_posted_at":"2014-01-14T02:24:19.000-05:00","bumped":true,"bumped_at":"2014-01-14T02:24:12.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":178,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":6695},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11932,"title":"Use of blockquote tag causes text outside a paragraph","fancy_title":"Use of blockquote tag causes text outside a paragraph","slug":"use-of-blockquote-tag-causes-text-outside-a-paragraph","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2014-01-13T13:38:15.000-05:00","last_posted_at":"2014-01-13T19:30:37.000-05:00","bumped":true,"bumped_at":"2014-01-14T02:22:58.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":54,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":10357,"title":"Displaced Wrench Icon Chrome","fancy_title":"Displaced Wrench Icon Chrome","slug":"displaced-wrench-icon-chrome","posts_count":12,"reply_count":4,"highest_post_number":12,"image_url":"/uploads/default/_optimized/9f3/f35/c5379beffe_690x300.jpg","created_at":"2013-10-14T05:48:21.000-04:00","last_posted_at":"2014-01-14T03:21:32.000-05:00","bumped":true,"bumped_at":"2014-01-13T19:03:33.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":206,"like_count":10,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":7073},{"extras":null,"description":"Frequent Poster","user_id":212},{"extras":null,"description":"Frequent Poster","user_id":6118},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":10114,"title":"Invitation expiry workflow is wonky","fancy_title":"Invitation expiry workflow is wonky","slug":"invitation-expiry-workflow-is-wonky","posts_count":14,"reply_count":7,"highest_post_number":14,"image_url":null,"created_at":"2013-09-30T00:59:36.000-04:00","last_posted_at":"2014-01-13T18:51:26.000-05:00","bumped":true,"bumped_at":"2014-01-13T18:51:26.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":176,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Most Posts","user_id":7076},{"extras":null,"description":"Frequent Poster","user_id":2},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":6330,"title":"Reply not disabled if topic closed while viewing","fancy_title":"Reply not disabled if topic closed while viewing","slug":"reply-not-disabled-if-topic-closed-while-viewing","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s=40&r=pg&d=identicon","created_at":"2013-05-02T06:02:06.000-04:00","last_posted_at":"2014-01-13T11:54:22.000-05:00","bumped":true,"bumped_at":"2014-01-13T11:54:22.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":164,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":4851},{"extras":null,"description":"Most Posts","user_id":2},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8367,"title":"Very fast scrolling fails to mark all posts read in a thread","fancy_title":"Very fast scrolling fails to mark all posts read in a thread","slug":"very-fast-scrolling-fails-to-mark-all-posts-read-in-a-thread","posts_count":11,"reply_count":7,"highest_post_number":13,"image_url":null,"created_at":"2013-07-14T12:37:02.000-04:00","last_posted_at":"2014-01-13T11:16:56.000-05:00","bumped":true,"bumped_at":"2014-01-13T11:16:33.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":288,"like_count":5,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":4457},{"extras":null,"description":"Most Posts","user_id":6280},{"extras":null,"description":"Frequent Poster","user_id":3681},{"extras":null,"description":"Frequent Poster","user_id":1621},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8815,"title":"Cache headers confuse proxies","fancy_title":"Cache headers confuse proxies","slug":"cache-headers-confuse-proxies","posts_count":9,"reply_count":3,"highest_post_number":9,"image_url":null,"created_at":"2013-08-02T05:45:26.000-04:00","last_posted_at":"2014-01-13T11:12:09.000-05:00","bumped":true,"bumped_at":"2014-01-13T10:41:44.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":314,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":6266},{"extras":null,"description":"Most Posts","user_id":19},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4457},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":32}]},{"id":11371,"title":"Search not working for Staff users","fancy_title":"Search not working for Staff users","slug":"search-not-working-for-staff-users","posts_count":15,"reply_count":10,"highest_post_number":15,"image_url":null,"created_at":"2013-12-11T13:22:56.000-05:00","last_posted_at":"2014-01-13T01:41:50.000-05:00","bumped":true,"bumped_at":"2014-01-13T01:41:46.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":217,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":5335},{"extras":null,"description":"Most Posts","user_id":19},{"extras":null,"description":"Frequent Poster","user_id":6314},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":9908,"title":"Draft bar overrides pagination widget","fancy_title":"Draft bar overrides pagination widget","slug":"draft-bar-overrides-pagination-widget","posts_count":4,"reply_count":0,"highest_post_number":4,"image_url":null,"created_at":"2013-09-19T17:19:52.000-04:00","last_posted_at":"2014-01-13T01:26:01.000-05:00","bumped":true,"bumped_at":"2014-01-13T01:25:12.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":108,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":5351},{"extras":null,"description":"Most Posts","user_id":471},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":6134,"title":"Unread topic is stuck as unread after insertion of staff message","fancy_title":"Unread topic is stuck as unread after insertion of staff message","slug":"unread-topic-is-stuck-as-unread-after-insertion-of-staff-message","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s=40&r=pg&d=identicon","created_at":"2013-04-24T13:37:32.000-04:00","last_posted_at":"2014-01-13T01:22:49.000-05:00","bumped":true,"bumped_at":"2014-01-13T01:22:42.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":169,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":5351},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":11914,"title":"Google analytics is not registering page views","fancy_title":"Google analytics is not registering page views","slug":"google-analytics-is-not-registering-page-views","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2014-01-13T00:32:45.000-05:00","last_posted_at":"2014-01-13T00:32:46.000-05:00","bumped":true,"bumped_at":"2014-01-13T00:32:46.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":37,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":1}]}]}}, "/categories_and_latest.json": {"category_list":{"can_create_category":false,"can_create_topic":false,"draft":null,"draft_key":"new_topic","draft_sequence":null,"categories":[{"id":1,"name":"Uncategorized","color":"AB9364","text_color":"FFFFFF","slug":"uncategorized","topic_count":1,"post_count":0,"position":0,"description":"Topics that don't need a category, or don't fit into any other existing category.","description_text":"","topic_url":null,"logo_url":null,"background_url":null,"read_restricted":false,"permission":null,"notification_level":null,"topic_template":null,"has_children":false,"topics_day":0,"topics_week":0,"topics_month":0,"topics_year":0,"topics_all_time":1,"description_excerpt":"Topics that don't need a category, or don't fit into any other existing category.","is_uncategorized":true},{"id":3,"name":"Site Feedback","color":"808281","text_color":"FFFFFF","slug":"site-feedback","topic_count":0,"post_count":0,"position":1,"description":"Discussion about this site, its organization, how it works, and how we can improve it.","description_text":"Discussion about this site, its organization, how it works, and how we can improve it.","topic_url":"/t/about-the-site-feedback-category/2","logo_url":null,"background_url":null,"read_restricted":false,"permission":null,"notification_level":null,"topic_template":null,"has_children":false,"topics_day":0,"topics_week":0,"topics_month":0,"topics_year":0,"topics_all_time":0,"description_excerpt":"Discussion about this site, its organization, how it works, and how we can improve it."}]},"topic_list":{"can_create_topic":false,"draft":null,"draft_key":"new_topic","draft_sequence":null,"per_page":30,"topics":[{"id":8,"title":"Welcome to Discourse","fancy_title":"Welcome to Discourse","slug":"welcome-to-discourse","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2016-08-29T20:38:19.359Z","last_posted_at":"2016-08-29T20:38:19.402Z","bumped":true,"bumped_at":"2016-08-29T20:38:19.402Z","unseen":false,"pinned":true,"unpinned":null,"excerpt":"The first paragraph of this pinned topic will be visible as a welcome message to all new visitors on your homepage. It's important! \n\nEdit this into a brief description of your community: \n\n\nWho is it for?\nWhat can they …","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":0,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"system","category_id":1,"pinned_globally":true,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":-1}]}]}} }; diff --git a/test/javascripts/fixtures/site-fixtures.js.es6 b/test/javascripts/fixtures/site-fixtures.js.es6 index 81ce4b8697..cefd86f071 100644 --- a/test/javascripts/fixtures/site-fixtures.js.es6 +++ b/test/javascripts/fixtures/site-fixtures.js.es6 @@ -92,7 +92,9 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":10, @@ -108,7 +110,9 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":26, @@ -141,7 +145,10 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":true, + "default_view":"latest", + "subcategory_list_style":"boxes_with_featured_topics" }, { "id":6, @@ -157,7 +164,9 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":24, @@ -224,7 +233,9 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":14, @@ -240,7 +251,9 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":12, @@ -256,7 +269,9 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":13, @@ -272,7 +287,9 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":5, @@ -288,7 +305,9 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":11, @@ -304,7 +323,9 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":22, @@ -338,7 +359,9 @@ export default { "notification_level":null, "logo_url":null, "background_url":null, - "can_edit":true + "can_edit":true, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":17, @@ -354,7 +377,9 @@ export default { "permission":1, "notification_level":null, "logo_url":"", - "background_url":"" + "background_url":"", + "show_subcategory_list":false, + "default_view":"latest" }, { "id":21, @@ -387,7 +412,9 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":9, @@ -403,7 +430,9 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":false, + "default_view":"latest" }, { "id":2, @@ -419,7 +448,10 @@ export default { "permission":1, "notification_level":null, "logo_url":null, - "background_url":null + "background_url":null, + "show_subcategory_list":true, + "default_view":"latest", + "subcategory_list_style":"boxes" } ], "post_action_types":[ diff --git a/test/javascripts/lib/click-track-test.js.es6 b/test/javascripts/lib/click-track-test.js.es6 index bebe653d6f..dfe4f83c3a 100644 --- a/test/javascripts/lib/click-track-test.js.es6 +++ b/test/javascripts/lib/click-track-test.js.es6 @@ -19,14 +19,14 @@ module("lib:click-track", { `
    google.com - google.com - google.com1 - google.com1 + google.fr + google.de1 + google.es1 - google.com + google.com.br forum log.txt #hashtag diff --git a/test/javascripts/models/user-test.js.es6 b/test/javascripts/models/user-test.js.es6 index 0414ef44e3..ea845d582f 100644 --- a/test/javascripts/models/user-test.js.es6 +++ b/test/javascripts/models/user-test.js.es6 @@ -1,7 +1,10 @@ -module("Discourse.User"); +import User from 'discourse/models/user'; +import Group from 'discourse/models/group'; + +module("model:user"); test('staff', function(){ - var user = Discourse.User.create({id: 1, username: 'eviltrout'}); + var user = User.create({id: 1, username: 'eviltrout'}); ok(!user.get('staff'), "user is not staff"); @@ -13,15 +16,31 @@ test('staff', function(){ }); test('searchContext', function() { - var user = Discourse.User.create({id: 1, username: 'EvilTrout'}); + var user = User.create({id: 1, username: 'EvilTrout'}); deepEqual(user.get('searchContext'), {type: 'user', id: 'eviltrout', user: user}, "has a search context"); }); test("isAllowedToUploadAFile", function() { - var user = Discourse.User.create({ trust_level: 0, admin: true }); + var user = User.create({ trust_level: 0, admin: true }); ok(user.isAllowedToUploadAFile("image"), "admin can always upload a file"); user.setProperties({ admin: false, moderator: true }); ok(user.isAllowedToUploadAFile("image"), "moderator can always upload a file"); }); + +test('canMangeGroup', function() { + let user = User.create({ admin: true }); + let group = Group.create({ automatic: true }); + + equal(user.canManageGroup(group), false, "automatic groups cannot be managed."); + + group.set("automatic", false); + + equal(user.canManageGroup(group), true, "an admin should be able to manage the group"); + + user.set('admin', false); + group.setProperties({ is_group_owner: true }); + + equal(user.canManageGroup(group), true, "a group owner should be able to manage the group"); +});