diff --git a/Gemfile.lock b/Gemfile.lock index 6557c6915a..8142f566d5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -248,7 +248,7 @@ GEM omniauth-twitter (1.2.1) json (~> 1.3) omniauth-oauth (~> 1.1) - onebox (1.5.26) + onebox (1.5.27) moneta (~> 0.8) multi_json (~> 1.11) mustache diff --git a/app/assets/javascripts/admin/components/embedding-setting.js.es6 b/app/assets/javascripts/admin/components/embedding-setting.js.es6 index 039e5d5dc3..f1d31fcf68 100644 --- a/app/assets/javascripts/admin/components/embedding-setting.js.es6 +++ b/app/assets/javascripts/admin/components/embedding-setting.js.es6 @@ -6,11 +6,6 @@ export default Ember.Component.extend({ @computed('field') inputId(field) { return field.dasherize(); }, - @computed('placeholder') - placeholderValue(placeholder) { - return placeholder ? I18n.t(placeholder) : null; - }, - @computed('field') translationKey(field) { return `admin.embedding.${field}`; }, @@ -21,7 +16,7 @@ export default Ember.Component.extend({ checked: { get(value) { return !!value; }, set(value) { - this.set('value', value); + this.set('value', value); return value; } } diff --git a/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 index 96547435d8..46f4548ebd 100644 --- a/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 @@ -68,7 +68,8 @@ export default Ember.Controller.extend(BufferedContent, { model = this.get('model'); this.get('model').save(data).then(function() { if (newBadge) { - self.get('controllers.admin-badges').pushObject(model); + var adminBadgesController = self.get('controllers.admin-badges'); + if (!adminBadgesController.contains(model)) adminBadgesController.pushObject(model); self.transitionToRoute('adminBadges.show', model.get('id')); } else { self.commitBuffer(); diff --git a/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 index f259acba84..8a3fd0b960 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 @@ -5,7 +5,7 @@ export default Ember.Controller.extend({ const model = this.get('model'); this.set('loading', true); - Discourse.EmailPreview.findDigest(this.get('lastSeen')).then(email => { + Discourse.EmailPreview.findDigest(this.get('lastSeen'), this.get('username')).then(email => { model.setProperties(email.getProperties('html_content', 'text_content')); this.set('loading', false); }); diff --git a/app/assets/javascripts/admin/controllers/admin-groups-bulk.js.es6 b/app/assets/javascripts/admin/controllers/admin-groups-bulk.js.es6 new file mode 100644 index 0000000000..6628a6fa72 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-groups-bulk.js.es6 @@ -0,0 +1,34 @@ +import computed from 'ember-addons/ember-computed-decorators'; +import { popupAjaxError } from 'discourse/lib/ajax-error'; + +export default Ember.Controller.extend({ + users: null, + groupId: null, + saving: false, + + @computed('saving', 'users', 'groupId') + buttonDisabled(saving, users, groupId) { + return saving || !groupId || !users || !users.length; + }, + + actions: { + addToGroup() { + if (this.get('saving')) { return; } + + const users = this.get('users').split("\n") + .uniq() + .reject(x => x.length === 0); + + this.set('saving', true); + Discourse.ajax('/admin/groups/bulk', { + data: { users, group_id: this.get('groupId') }, + method: 'PUT' + }).then(() => { + this.transitionToRoute('adminGroups.bulkComplete'); + }).catch(popupAjaxError).finally(() => { + this.set('saving', false); + }); + + } + } +}); diff --git a/app/assets/javascripts/admin/models/admin-user.js.es6 b/app/assets/javascripts/admin/models/admin-user.js.es6 index 1e83de6206..20a9579bd6 100644 --- a/app/assets/javascripts/admin/models/admin-user.js.es6 +++ b/app/assets/javascripts/admin/models/admin-user.js.es6 @@ -288,10 +288,7 @@ const AdminUser = Discourse.User.extend({ data: { username: this.get('username') } }).then(function() { bootbox.alert( I18n.t('admin.user.activation_email_sent') ); - }).catch(function(e) { - var error = I18n.t('admin.user.send_activation_email_failed', { error: "http: " + e.status + " - " + e.body }); - bootbox.alert(error); - }); + }).catch(popupAjaxError); }, anonymizeForbidden: Em.computed.not("can_be_anonymized"), diff --git a/app/assets/javascripts/admin/models/email_preview.js b/app/assets/javascripts/admin/models/email_preview.js index b754095812..8ae9bdfcd4 100644 --- a/app/assets/javascripts/admin/models/email_preview.js +++ b/app/assets/javascripts/admin/models/email_preview.js @@ -9,18 +9,20 @@ Discourse.EmailPreview = Discourse.Model.extend({}); Discourse.EmailPreview.reopenClass({ - findDigest: function(lastSeenAt) { + findDigest: function(lastSeenAt, username) { if (Em.isEmpty(lastSeenAt)) { lastSeenAt = moment().subtract(7, 'days').format('YYYY-MM-DD'); } + if (Em.isEmpty(username)) { + username = Discourse.User.current().username; + } + return Discourse.ajax("/admin/email/preview-digest.json", { - data: {last_seen_at: lastSeenAt} + data: { last_seen_at: lastSeenAt, username: username } }).then(function (result) { return Discourse.EmailPreview.create(result); }); } }); - - diff --git a/app/assets/javascripts/admin/routes/admin-groups-bulk.js.es6 b/app/assets/javascripts/admin/routes/admin-groups-bulk.js.es6 new file mode 100644 index 0000000000..8d9554556f --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-groups-bulk.js.es6 @@ -0,0 +1,13 @@ +import Group from 'discourse/models/group'; + +export default Ember.Route.extend({ + model() { + return Group.findAll().then(groups => { + return groups.filter(g => !g.get('automatic')); + }); + }, + + setupController(controller, groups) { + controller.setProperties({ groups, groupId: null, users: null }); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-route-map.js.es6 b/app/assets/javascripts/admin/routes/admin-route-map.js.es6 index e01d0f8f0d..dd758556c6 100644 --- a/app/assets/javascripts/admin/routes/admin-route-map.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-route-map.js.es6 @@ -49,6 +49,8 @@ export default { }); this.resource('adminGroups', { path: '/groups' }, function() { + this.route('bulk'); + this.route('bulkComplete', { path: 'bulk-complete' }); this.resource('adminGroupsType', { path: '/:type' }, function() { this.resource('adminGroup', { path: '/:name' }); }); diff --git a/app/assets/javascripts/admin/templates/components/embedding-setting.hbs b/app/assets/javascripts/admin/templates/components/embedding-setting.hbs index e3a99c3202..eb63c40af9 100644 --- a/app/assets/javascripts/admin/templates/components/embedding-setting.hbs +++ b/app/assets/javascripts/admin/templates/components/embedding-setting.hbs @@ -5,7 +5,7 @@ {{else}} - {{input value=value id=inputId placeholder=placeholderValue}} + {{input value=value id=inputId placeholder=placeholder}} {{/if}}
diff --git a/app/assets/javascripts/admin/templates/dashboard.hbs b/app/assets/javascripts/admin/templates/dashboard.hbs index 87d9cb699d..ed98e21fcb 100644 --- a/app/assets/javascripts/admin/templates/dashboard.hbs +++ b/app/assets/javascripts/admin/templates/dashboard.hbs @@ -1,3 +1,5 @@ +{{plugin-outlet "admin-dashboard-top"}} +
{{#if showVersionChecks}} {{partial 'admin/templates/version-checks'}} diff --git a/app/assets/javascripts/admin/templates/email_preview_digest.hbs b/app/assets/javascripts/admin/templates/email_preview_digest.hbs index 83d99db35f..630260f131 100644 --- a/app/assets/javascripts/admin/templates/email_preview_digest.hbs +++ b/app/assets/javascripts/admin/templates/email_preview_digest.hbs @@ -4,6 +4,8 @@
{{input type="date" value=lastSeen id="last-seen"}} + + {{user-selector single="true" usernames=username}}
diff --git a/app/assets/javascripts/admin/templates/embedding.hbs b/app/assets/javascripts/admin/templates/embedding.hbs index d41970fb84..30f279105d 100644 --- a/app/assets/javascripts/admin/templates/embedding.hbs +++ b/app/assets/javascripts/admin/templates/embedding.hbs @@ -48,11 +48,11 @@ {{embedding-setting field="embed_whitelist_selector" value=embedding.embed_whitelist_selector - placeholder="admin.embedding.whitelist_example"}} + placeholder="article, #story, .post"}} {{embedding-setting field="embed_blacklist_selector" value=embedding.embed_blacklist_selector - placeholder="admin.embedding.blacklist_example"}} + placeholder=".ad-unit, header"}}
diff --git a/app/assets/javascripts/admin/templates/groups-bulk-complete.hbs b/app/assets/javascripts/admin/templates/groups-bulk-complete.hbs new file mode 100644 index 0000000000..51eb3e4394 --- /dev/null +++ b/app/assets/javascripts/admin/templates/groups-bulk-complete.hbs @@ -0,0 +1 @@ +

{{i18n "admin.groups.bulk_complete"}}

diff --git a/app/assets/javascripts/admin/templates/groups-bulk.hbs b/app/assets/javascripts/admin/templates/groups-bulk.hbs new file mode 100644 index 0000000000..baf3a63cda --- /dev/null +++ b/app/assets/javascripts/admin/templates/groups-bulk.hbs @@ -0,0 +1,19 @@ +
+

{{i18n "admin.groups.bulk_paste"}}

+ +
+ {{textarea value=users class="paste-users"}} +
+ +
+ {{combo-box content=groups valueAttribute="id" value=groupId none="admin.groups.bulk_select"}} +
+ +
+ {{d-button disabled=buttonDisabled + class="btn-primary" + action="addToGroup" + icon="plus" + label="admin.groups.bulk"}} +
+
diff --git a/app/assets/javascripts/admin/templates/groups.hbs b/app/assets/javascripts/admin/templates/groups.hbs index 2d767c3844..aa7d9213ca 100644 --- a/app/assets/javascripts/admin/templates/groups.hbs +++ b/app/assets/javascripts/admin/templates/groups.hbs @@ -1,6 +1,7 @@ {{#admin-nav}} {{nav-item route='adminGroupsType' routeParam='custom' label='admin.groups.custom'}} {{nav-item route='adminGroupsType' routeParam='automatic' label='admin.groups.automatic'}} + {{nav-item route='adminGroups.bulk' label='admin.groups.bulk'}} {{/admin-nav}}
diff --git a/app/assets/javascripts/admin/views/admin-customize.js.es6 b/app/assets/javascripts/admin/views/admin-customize.js.es6 index faca47026f..240ed0ac73 100644 --- a/app/assets/javascripts/admin/views/admin-customize.js.es6 +++ b/app/assets/javascripts/admin/views/admin-customize.js.es6 @@ -1,18 +1,3 @@ -/*global Mousetrap:true */ - export default Ember.View.extend({ - classNames: ['customize'], - - _init: function() { - var controller = this.get('controller'); - Mousetrap.bindGlobal('mod+s', function() { - controller.send("save"); - return false; - }); - }.on("didInsertElement"), - - _cleanUp: function() { - Mousetrap.unbindGlobal('mod+s'); - }.on("willDestroyElement") - + classNames: ['customize'] }); diff --git a/app/assets/javascripts/discourse.js b/app/assets/javascripts/discourse.js index 9c790e3fe4..96f4c90c6d 100644 --- a/app/assets/javascripts/discourse.js +++ b/app/assets/javascripts/discourse.js @@ -14,7 +14,7 @@ window.Discourse = Ember.Application.createWithMixins(Discourse.Ajax, { if (!url) return url; // if it's a non relative URL, return it. - if (!/^\/[^\/]/.test(url)) return url; + if (url !== '/' && !/^\/[^\/]/.test(url)) return url; var u = Discourse.BaseUri === undefined ? "/" : Discourse.BaseUri; diff --git a/app/assets/javascripts/discourse/components/d-editor-modal.js.es6 b/app/assets/javascripts/discourse/components/d-editor-modal.js.es6 index 0b6f6920a6..049914fe2c 100644 --- a/app/assets/javascripts/discourse/components/d-editor-modal.js.es6 +++ b/app/assets/javascripts/discourse/components/d-editor-modal.js.es6 @@ -34,7 +34,7 @@ export default Ember.Component.extend({ }); }, - @on('willDestoryElement') + @on('willDestroyElement') _stopListening() { this.$().off('keydown.d-modal'); }, diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6 index 4d8061c6e6..4d26eb3e43 100644 --- a/app/assets/javascripts/discourse/components/d-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/d-editor.js.es6 @@ -1,3 +1,4 @@ +/*global Mousetrap:true */ import loadScript from 'discourse/lib/load-script'; import { default as property, on } from 'ember-addons/ember-computed-decorators'; import { showSelector } from "discourse/lib/emoji/emoji-toolbar"; @@ -12,6 +13,130 @@ function getHead(head, prev) { } } +const _createCallbacks = []; + +function Toolbar() { + this.shortcuts = {}; + + this.groups = [ + {group: 'fontStyles', buttons: []}, + {group: 'insertions', buttons: []}, + {group: 'extras', buttons: [], lastGroup: true} + ]; + + this.addButton({ + id: 'bold', + group: 'fontStyles', + shortcut: 'B', + perform: e => e.applySurround('**', '**', 'bold_text') + }); + + this.addButton({ + id: 'italic', + group: 'fontStyles', + shortcut: 'I', + perform: e => e.applySurround('*', '*', 'italic_text') + }); + + this.addButton({id: 'link', group: 'insertions', shortcut: 'K', action: 'showLinkModal'}); + + this.addButton({ + id: 'quote', + group: 'insertions', + icon: 'quote-right', + shortcut: 'Shift+9', + perform: e => e.applySurround('> ', '', 'code_text') + }); + + this.addButton({ + id: 'code', + group: 'insertions', + shortcut: 'Shift+C', + perform(e) { + if (e.selected.value.indexOf("\n") !== -1) { + e.applySurround(' ', '', 'code_text'); + } else { + e.applySurround('`', '`', 'code_text'); + } + }, + }); + + this.addButton({ + id: 'bullet', + group: 'extras', + icon: 'list-ul', + shortcut: 'Shift+8', + title: 'composer.ulist_title', + perform: e => e.applyList('* ', 'list_item') + }); + + this.addButton({ + id: 'list', + group: 'extras', + icon: 'list-ol', + shortcut: 'Shift+7', + title: 'composer.olist_title', + perform: e => e.applyList(i => !i ? "1. " : `${parseInt(i) + 1}. `, 'list_item') + }); + + this.addButton({ + id: 'heading', + group: 'extras', + icon: 'font', + shortcut: 'Alt+1', + perform: e => e.applyList('## ', 'heading_text') + }); + + this.addButton({ + id: 'rule', + group: 'extras', + icon: 'minus', + shortcut: 'Alt+R', + title: 'composer.hr_title', + perform: e => e.addText("\n\n----------\n") + }); +}; + +Toolbar.prototype.addButton = function(button) { + const g = this.groups.findProperty('group', button.group); + if (!g) { + throw `Couldn't find toolbar group ${button.group}`; + } + + const createdButton = { + id: button.id, + className: button.className || button.id, + icon: button.icon || button.id, + action: button.action || 'toolbarButton', + perform: button.perform || Ember.K + }; + + const title = I18n.t(button.title || `composer.${button.id}_title`); + if (button.shortcut) { + const mac = /Mac|iPod|iPhone|iPad/.test(navigator.platform); + const mod = mac ? 'Meta' : 'Ctrl'; + createdButton.title = `${title} (${mod}+${button.shortcut})`; + + // Mac users are used to glyphs for shortcut keys + if (mac) { + createdButton.title = createdButton.title.replace('Shift', "\u21E7") + .replace('Meta', "\u2318") + .replace('Alt', "\u2325") + .replace(/\+/g, ''); + } + + this.shortcuts[`${mod}+${button.shortcut}`.toLowerCase()] = createdButton; + } else { + createdButton.title = title; + } + + g.buttons.push(createdButton); +}; + +export function onToolbarCreate(func) { + _createCallbacks.push(func); +}; + export default Ember.Component.extend({ classNames: ['d-editor'], ready: false, @@ -20,16 +145,38 @@ export default Ember.Component.extend({ lastSel: null, @on('didInsertElement') - _loadSanitizer() { + _startUp() { this._applyEmojiAutocomplete(); loadScript('defer/html-sanitizer-bundle').then(() => this.set('ready', true)); + + const shortcuts = this.get('toolbar.shortcuts'); + Ember.keys(shortcuts).forEach(sc => { + const button = shortcuts[sc]; + Mousetrap(this.$('.d-editor-input')[0]).bind(sc, () => { + this.send(button.action, button); + }); + }); + }, + + @on('willDestroyElement') + _shutDown() { + Ember.keys(this.get('toolbar.shortcuts')).forEach(sc => { + Mousetrap(this.$('.d-editor-input')[0]).unbind(sc); + }); + }, + + @property + toolbar() { + const toolbar = new Toolbar(); + _createCallbacks.forEach(cb => cb(toolbar)); + return toolbar; }, @property('ready', 'value') preview(ready, value) { if (!ready) { return; } - const text = Discourse.Dialect.cook(value || "", {}); + const text = Discourse.Dialect.cook(value || "", {sanitize: true}); return text ? text : ""; }, @@ -51,7 +198,7 @@ export default Ember.Component.extend({ showSelector({ appendTo: self.$(), container, - onSelect: title => self._addText(`${title}:`) + onSelect: title => self._addText(this._getSelected(), `${title}:`) }); return ""; } @@ -112,8 +259,7 @@ export default Ember.Component.extend({ }); }, - _applySurround(head, tail, exampleKey) { - const sel = this._getSelected(); + _applySurround(sel, head, tail, exampleKey) { const pre = sel.pre; const post = sel.post; @@ -162,10 +308,9 @@ export default Ember.Component.extend({ } }, - _applyList(head, exampleKey) { - const sel = this._getSelected(); + _applyList(sel, head, exampleKey) { if (sel.value.indexOf("\n") !== -1) { - this._applySurround(head, '', exampleKey); + this._applySurround(sel, head, '', exampleKey); } else { const [hval, hlen] = getHead(head); @@ -185,20 +330,21 @@ export default Ember.Component.extend({ } }, - _addText(text, sel) { - sel = sel || this._getSelected(); + _addText(sel, text) { const insert = `${sel.pre}${text}`; this.set('value', `${insert}${sel.post}`); this._selectText(insert.length, 0); }, actions: { - bold() { - this._applySurround('**', '**', 'bold_text'); - }, - - italic() { - this._applySurround('*', '*', 'italic_text'); + toolbarButton(button) { + const selected = this._getSelected(); + button.perform({ + selected, + applySurround: (head, tail, exampleKey) => this._applySurround(selected, head, tail, exampleKey), + applyList: (head, exampleKey) => this._applyList(selected, head, exampleKey), + addText: text => this._addText(selected, text) + }); }, showLinkModal() { @@ -214,48 +360,19 @@ export default Ember.Component.extend({ if (m && m.length === 2) { const description = m[1]; const remaining = link.replace(m[0], ''); - this._addText(`[${description}](${remaining})`, this._lastSel); + this._addText(this._lastSel, `[${description}](${remaining})`); } else { - this._addText(`[${link}](${link})`, this._lastSel); + this._addText(this._lastSel, `[${link}](${link})`); } this.set('link', ''); }, - code() { - const sel = this._getSelected(); - if (sel.value.indexOf("\n") !== -1) { - this._applySurround(' ', '', 'code_text'); - } else { - this._applySurround('`', '`', 'code_text'); - } - }, - - quote() { - this._applySurround('> ', "", 'code_text'); - }, - - bullet() { - this._applyList('* ', 'list_item'); - }, - - list() { - this._applyList(i => !i ? "1. " : `${parseInt(i) + 1}. `, 'list_item'); - }, - - heading() { - this._applyList('## ', 'heading_text'); - }, - - rule() { - this._addText("\n\n----------\n"); - }, - emoji() { showSelector({ appendTo: this.$(), container: this.container, - onSelect: title => this._addText(`:${title}:`) + onSelect: title => this._addText(this._getSelected(), `:${title}:`) }); } } diff --git a/app/assets/javascripts/discourse/components/hamburger-menu.js.es6 b/app/assets/javascripts/discourse/components/hamburger-menu.js.es6 index 910b8d661a..e10c01c84d 100644 --- a/app/assets/javascripts/discourse/components/hamburger-menu.js.es6 +++ b/app/assets/javascripts/discourse/components/hamburger-menu.js.es6 @@ -56,6 +56,13 @@ export default Ember.Component.extend({ }); }, + @computed() + showUserDirectoryLink() { + if (!this.siteSettings.enable_user_directory) return false; + if (this.siteSettings.hide_user_profiles_from_public && !this.currentUser) return false; + return true; + }, + actions: { keyboardShortcuts() { this.sendAction('showKeyboardAction'); diff --git a/app/assets/javascripts/discourse/components/header-dropdown.js.es6 b/app/assets/javascripts/discourse/components/header-dropdown.js.es6 index 447184410c..387f7ae8f1 100644 --- a/app/assets/javascripts/discourse/components/header-dropdown.js.es6 +++ b/app/assets/javascripts/discourse/components/header-dropdown.js.es6 @@ -4,9 +4,9 @@ export default Ember.Component.extend({ tagName: 'li', classNameBindings: [':header-dropdown-toggle', 'active'], - @computed('showUser') - href(showUser) { - return showUser ? this.currentUser.get('path') : ''; + @computed('showUser', 'path') + href(showUser, path) { + return showUser ? this.currentUser.get('path') : Discourse.getURL(path); }, active: Ember.computed.alias('toggleVisible'), diff --git a/app/assets/javascripts/discourse/components/private-message-map.js.es6 b/app/assets/javascripts/discourse/components/private-message-map.js.es6 index f8d402ba76..0d01910c72 100644 --- a/app/assets/javascripts/discourse/components/private-message-map.js.es6 +++ b/app/assets/javascripts/discourse/components/private-message-map.js.es6 @@ -9,7 +9,7 @@ export default Ember.Component.extend({ var self = this; bootbox.dialog(I18n.t("private_message_info.remove_allowed_user", {name: user.get('username')}), [ {label: I18n.t("no_value"), - 'class': 'btn-danger rightg'}, + 'class': 'btn-danger right'}, {label: I18n.t("yes_value"), 'class': 'btn-primary', callback: function() { diff --git a/app/assets/javascripts/discourse/components/signup-cta.js.es6 b/app/assets/javascripts/discourse/components/signup-cta.js.es6 index b1224306e8..b3567ac15b 100644 --- a/app/assets/javascripts/discourse/components/signup-cta.js.es6 +++ b/app/assets/javascripts/discourse/components/signup-cta.js.es6 @@ -18,36 +18,6 @@ export default Ember.Component.extend({ } }, - signupMethodsTranslated: function() { - const methods = Ember.get('Discourse.LoginMethod.all'); - const loginWithEmail = this.siteSettings.enable_local_logins; - if (this.siteSettings.enable_sso) { - return I18n.t('signup_cta.methods.sso'); - } else if (methods.length === 0) { - if (loginWithEmail) { - return I18n.t('signup_cta.methods.only_email'); - } else { - return I18n.t('signup_cta.methods.unknown'); - } - } else if (methods.length === 1) { - let providerName = methods[0].name.capitalize(); - if (providerName === "Google_oauth2") { - providerName = "Google"; - } - if (loginWithEmail) { - return I18n.t('signup_cta.methods.one_and_email', {provider: providerName}); - } else { - return I18n.t('signup_cta.methods.only_other', {provider: providerName}); - } - } else { - if (loginWithEmail) { - return I18n.t('signup_cta.methods.multiple', {count: methods.length}); - } else { - return I18n.t('signup_cta.methods.multiple_no_email', {count: methods.length}); - } - } - }.property(), - _turnOffIfHidden: function() { if (this.session.get('hideSignupCta')) { this.session.set('showSignupCta', false); diff --git a/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6 b/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6 index 32aa7b514d..6a34f559b0 100644 --- a/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6 +++ b/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6 @@ -21,8 +21,8 @@ export default Ember.Controller.extend(ModalFunctionality, { }, @computed() - allowImageUpload() { - return Discourse.Utilities.allowsImages(); + allowAvatarUpload() { + return this.siteSettings.allow_uploaded_avatars && Discourse.Utilities.allowsImages(); }, actions: { diff --git a/app/assets/javascripts/discourse/controllers/create-account.js.es6 b/app/assets/javascripts/discourse/controllers/create-account.js.es6 index b93363cb3b..b98a3285ac 100644 --- a/app/assets/javascripts/discourse/controllers/create-account.js.es6 +++ b/app/assets/javascripts/discourse/controllers/create-account.js.es6 @@ -1,6 +1,7 @@ import debounce from 'discourse/lib/debounce'; import ModalFunctionality from 'discourse/mixins/modal-functionality'; import { setting } from 'discourse/lib/computed'; +import { on } from 'ember-addons/ember-computed-decorators'; export default Ember.Controller.extend(ModalFunctionality, { needs: ['login'], @@ -78,10 +79,6 @@ export default Ember.Controller.extend(ModalFunctionality, { // Validate the name. nameValidation: function() { - if (this.get('accountPasswordConfirm') === 0) { - this.fetchConfirmationValue(); - } - if (Discourse.SiteSettings.full_name_required && Ember.isEmpty(this.get('accountName'))) { return Discourse.InputValidation.create({ failed: true }); } @@ -335,11 +332,11 @@ export default Ember.Controller.extend(ModalFunctionality, { }); }.property('accountPassword', 'rejectedPasswords.@each', 'accountUsername', 'accountEmail'), + @on('init') fetchConfirmationValue() { - const createAccountController = this; - return Discourse.ajax('/users/hp.json').then(function (json) { - createAccountController.set('accountPasswordConfirm', json.value); - createAccountController.set('accountChallenge', json.challenge.split("").reverse().join("")); + return Discourse.ajax('/users/hp.json').then(json => { + this.set('accountPasswordConfirm', json.value); + this.set('accountChallenge', json.challenge.split("").reverse().join("")); }); }, diff --git a/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6 b/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6 index 0a2b046237..6426f75524 100644 --- a/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6 +++ b/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6 @@ -2,6 +2,7 @@ import DiscoveryController from 'discourse/controllers/discovery'; import { queryParams } from 'discourse/controllers/discovery-sortable'; import BulkTopicSelection from 'discourse/mixins/bulk-topic-selection'; import { endWith } from 'discourse/lib/computed'; +import showModal from 'discourse/lib/show-modal'; const controllerOpts = { needs: ['discovery'], @@ -66,10 +67,13 @@ const controllerOpts = { }); }, - resetNew() { this.topicTrackingState.resetNew(); Discourse.Topic.resetNew().then(() => this.send('refresh')); + }, + + dismissReadPosts() { + showModal('dismiss-read', { title: 'topics.bulk.dismiss_read' }); } }, diff --git a/app/assets/javascripts/discourse/controllers/group/members.js.es6 b/app/assets/javascripts/discourse/controllers/group/members.js.es6 index 794b5856a7..a22c82705a 100644 --- a/app/assets/javascripts/discourse/controllers/group/members.js.es6 +++ b/app/assets/javascripts/discourse/controllers/group/members.js.es6 @@ -11,7 +11,7 @@ export default Ember.Controller.extend({ this.set("loading", true); - Discourse.Group.loadMembers(this.get("name"), this.get("model.members.length"), this.get("limit")).then(result => { + Discourse.Group.loadMembers(this.get("model.name"), this.get("model.members.length"), this.get("limit")).then(result => { this.get("model.members").addObjects(result.members.map(member => Discourse.User.create(member))); this.setProperties({ loading: false, diff --git a/app/assets/javascripts/discourse/controllers/invite.js.es6 b/app/assets/javascripts/discourse/controllers/invite.js.es6 index 7befba51c2..ffaaab94d1 100644 --- a/app/assets/javascripts/discourse/controllers/invite.js.es6 +++ b/app/assets/javascripts/discourse/controllers/invite.js.es6 @@ -68,12 +68,12 @@ export default Ember.Controller.extend(ModalFunctionality, { // Show Groups? (add invited user to private group) showGroups: function() { - return this.get('isAdmin') && (Discourse.Utilities.emailValid(this.get('emailOrUsername')) || this.get('isPrivateTopic') || !this.get('invitingToTopic')) && !Discourse.SiteSettings.enable_sso && !this.get('isMessage'); + return this.get('isAdmin') && (Discourse.Utilities.emailValid(this.get('emailOrUsername')) || this.get('isPrivateTopic') || !this.get('invitingToTopic')) && !Discourse.SiteSettings.enable_sso && Discourse.SiteSettings.enable_local_logins && !this.get('isMessage'); }.property('isAdmin', 'emailOrUsername', 'isPrivateTopic', 'isMessage', 'invitingToTopic'), // Instructional text for the modal. inviteInstructions: function() { - if (Discourse.SiteSettings.enable_sso) { + if (Discourse.SiteSettings.enable_sso || !Discourse.SiteSettings.enable_local_logins) { // inviting existing user when SSO enabled return I18n.t('topic.invite_reply.sso_enabled'); } else if (this.get('isMessage')) { @@ -128,7 +128,7 @@ export default Ember.Controller.extend(ModalFunctionality, { }.property('isMessage'), placeholderKey: function() { - return Discourse.SiteSettings.enable_sso ? + return (Discourse.SiteSettings.enable_sso || !Discourse.SiteSettings.enable_local_logins) ? 'topic.invite_reply.username_placeholder' : 'topic.invite_private.email_or_username_placeholder'; }.property(), diff --git a/app/assets/javascripts/discourse/controllers/login.js.es6 b/app/assets/javascripts/discourse/controllers/login.js.es6 index 50abf282d7..157bbaf841 100644 --- a/app/assets/javascripts/discourse/controllers/login.js.es6 +++ b/app/assets/javascripts/discourse/controllers/login.js.es6 @@ -78,9 +78,15 @@ export default Ember.Controller.extend(ModalFunctionality, { const $hidden_login_form = $('#hidden-login-form'); const destinationUrl = $.cookie('destination_url'); const shouldRedirectToUrl = self.session.get("shouldRedirectToUrl"); + const ssoDestinationUrl = $.cookie('sso_destination_url'); $hidden_login_form.find('input[name=username]').val(self.get('loginName')); $hidden_login_form.find('input[name=password]').val(self.get('loginPassword')); - if (destinationUrl) { + + if (ssoDestinationUrl) { + $.cookie('sso_destination_url', null); + window.location.assign(ssoDestinationUrl); + return; + } else if (destinationUrl) { // redirect client to the original URL $.cookie('destination_url', null); $hidden_login_form.find('input[name=redirect]').val(destinationUrl); diff --git a/app/assets/javascripts/discourse/controllers/preferences.js.es6 b/app/assets/javascripts/discourse/controllers/preferences.js.es6 index a7aa333fbc..f23f342e08 100644 --- a/app/assets/javascripts/discourse/controllers/preferences.js.es6 +++ b/app/assets/javascripts/discourse/controllers/preferences.js.es6 @@ -5,12 +5,6 @@ import computed from "ember-addons/ember-computed-decorators"; export default Ember.Controller.extend(CanCheckEmails, { - allowAvatarUpload: setting('allow_uploaded_avatars'), - allowUserLocale: setting('allow_user_locale'), - ssoOverridesAvatar: setting('sso_overrides_avatar'), - allowBackgrounds: setting('allow_profile_backgrounds'), - editHistoryVisible: setting('edit_history_visible_to_public'), - @computed("model.watchedCategories", "model.trackedCategories", "model.mutedCategories") selectedCategories(watched, tracked, muted) { return [].concat(watched, tracked, muted); @@ -45,7 +39,7 @@ export default Ember.Controller.extend(CanCheckEmails, { @computed() nameInstructions() { - return I18n.t(Discourse.SiteSettings.full_name_required ? 'user.name.instructions_required' : 'user.name.instructions'); + return I18n.t(this.siteSettings.full_name_required ? 'user.name.instructions_required' : 'user.name.instructions'); }, @computed("model.has_title_badges") diff --git a/app/assets/javascripts/discourse/controllers/quote-button.js.es6 b/app/assets/javascripts/discourse/controllers/quote-button.js.es6 index bd50004977..620decb81d 100644 --- a/app/assets/javascripts/discourse/controllers/quote-button.js.es6 +++ b/app/assets/javascripts/discourse/controllers/quote-button.js.es6 @@ -101,8 +101,10 @@ export default Ember.Controller.extend({ // defer load if needed, if in an expanded replies section if (!post) { const postStream = this.get('controllers.topic.model.postStream'); - postStream.loadPost(postId).then(() => this.quoteText()); - return; + return postStream.loadPost(postId).then(p => { + this.set('post', p); + return this.quoteText(); + }); } // If we can't create a post, delegate to reply as new topic diff --git a/app/assets/javascripts/discourse/controllers/topic-bulk-actions.js.es6 b/app/assets/javascripts/discourse/controllers/topic-bulk-actions.js.es6 index b5e8bcbb4b..2dd79219e5 100644 --- a/app/assets/javascripts/discourse/controllers/topic-bulk-actions.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic-bulk-actions.js.es6 @@ -13,12 +13,13 @@ addBulkButton('closeTopics', 'close_topics'); addBulkButton('archiveTopics', 'archive_topics'); addBulkButton('showNotificationLevel', 'notification_level'); addBulkButton('resetRead', 'reset_read'); +addBulkButton('unlistTopics', 'unlist_topics'); // Modal for performing bulk actions on topics export default Ember.ArrayController.extend(ModalFunctionality, { buttonRows: null, - onShow: function() { + onShow() { this.set('controllers.modal.modalClass', 'topic-bulk-actions-modal small'); const buttonRows = []; @@ -36,87 +37,80 @@ export default Ember.ArrayController.extend(ModalFunctionality, { this.send('changeBulkTemplate', 'modal/bulk_actions_buttons'); }, - perform: function(operation) { + perform(operation) { this.set('loading', true); - var self = this, - topics = this.get('model'); - return Discourse.Topic.bulkOperation(this.get('model'), operation).then(function(result) { - self.set('loading', false); + const topics = this.get('model'); + return Discourse.Topic.bulkOperation(this.get('model'), operation).then(result => { + this.set('loading', false); if (result && result.topic_ids) { - return result.topic_ids.map(function (t) { - return topics.findBy('id', t); - }); + return result.topic_ids.map(t => topics.findBy('id', t)); } return result; - }).catch(function() { + }).catch(() => { bootbox.alert(I18n.t('generic_error')); - self.set('loading', false); + this.set('loading', false); }); }, - forEachPerformed: function(operation, cb) { - var self = this; - this.perform(operation).then(function (topics) { + forEachPerformed(operation, cb) { + this.perform(operation).then(topics => { if (topics) { topics.forEach(cb); - const refreshTarget = self.get('refreshTarget'); + const refreshTarget = this.get('refreshTarget'); if (refreshTarget) { refreshTarget.send('refresh'); } - self.send('closeModal'); + this.send('closeModal'); } }); }, - performAndRefresh: function(operation) { - const self = this; - return this.perform(operation).then(function() { - const refreshTarget = self.get('refreshTarget'); + performAndRefresh(operation) { + return this.perform(operation).then(() => { + const refreshTarget = this.get('refreshTarget'); if (refreshTarget) { refreshTarget.send('refresh'); } - self.send('closeModal'); + this.send('closeModal'); }); }, actions: { - showChangeCategory: function() { + showChangeCategory() { this.send('changeBulkTemplate', 'modal/bulk_change_category'); this.set('controllers.modal.modalClass', 'topic-bulk-actions-modal full'); }, - showNotificationLevel: function() { + showNotificationLevel() { this.send('changeBulkTemplate', 'modal/bulk_notification_level'); }, - deleteTopics: function() { + deleteTopics() { this.performAndRefresh({type: 'delete'}); }, - closeTopics: function() { - this.forEachPerformed({type: 'close'}, function(t) { - t.set('closed', true); - }); + closeTopics() { + this.forEachPerformed({type: 'close'}, t => t.set('closed', true)); }, - archiveTopics: function() { - this.forEachPerformed({type: 'archive'}, function(t) { - t.set('archived', true); - }); + archiveTopics() { + this.forEachPerformed({type: 'archive'}, t => t.set('archived', true)); }, - changeCategory: function() { - var categoryId = parseInt(this.get('newCategoryId'), 10) || 0, - category = Discourse.Category.findById(categoryId), - self = this; - this.perform({type: 'change_category', category_id: categoryId}).then(function(topics) { - topics.forEach(function(t) { - t.set('category', category); - }); - const refreshTarget = self.get('refreshTarget'); + unlistTopics() { + this.forEachPerformed({type: 'unlist'}, t => t.set('visible', false)); + }, + + changeCategory() { + const categoryId = parseInt(this.get('newCategoryId'), 10) || 0; + const category = Discourse.Category.findById(categoryId); + + this.perform({type: 'change_category', category_id: categoryId}).then(topics => { + topics.forEach(t => t.set('category', category)); + const refreshTarget = this.get('refreshTarget'); if (refreshTarget) { refreshTarget.send('refresh'); } - self.send('closeModal'); + this.send('closeModal'); }); }, - resetRead: function() { + resetRead() { this.performAndRefresh({ type: 'reset_read' }); } } diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index 968cd4e68d..e0e480953f 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -153,7 +153,7 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { if (user.get('staff') && replyCount > 0) { bootbox.dialog(I18n.t("post.controls.delete_replies.confirm", {count: replyCount}), [ {label: I18n.t("cancel"), - 'class': 'btn-danger rightg'}, + 'class': 'btn-danger right'}, {label: I18n.t("post.controls.delete_replies.no_value"), callback() { post.destroy(user); @@ -374,10 +374,11 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { togglePinnedForUser() { if (this.get('model.pinned_at')) { - if (this.get('pinned')) { - this.get('content').clearPin(); + const topic = this.get('content'); + if (topic.get('pinned')) { + topic.clearPin(); } else { - this.get('content').rePin(); + topic.rePin(); } } }, diff --git a/app/assets/javascripts/discourse/controllers/user-card.js.es6 b/app/assets/javascripts/discourse/controllers/user-card.js.es6 index ce2e065a89..c67125cdb2 100644 --- a/app/assets/javascripts/discourse/controllers/user-card.js.es6 +++ b/app/assets/javascripts/discourse/controllers/user-card.js.es6 @@ -39,6 +39,11 @@ export default Ember.Controller.extend({ // XSS protection (should be encapsulated) username = username.toString().replace(/[^A-Za-z0-9_\.\-]/g, ""); + // No user card for anon + if (this.siteSettings.hide_user_profiles_from_public && !this.currentUser) { + return; + } + // Don't show on mobile if (Discourse.Mobile.mobileView) { const url = "/users/" + username; diff --git a/app/assets/javascripts/discourse/initializers/enable-emoji.js.es6 b/app/assets/javascripts/discourse/initializers/enable-emoji.js.es6 index 3d2bd23b5f..5f23126b77 100644 --- a/app/assets/javascripts/discourse/initializers/enable-emoji.js.es6 +++ b/app/assets/javascripts/discourse/initializers/enable-emoji.js.es6 @@ -1,4 +1,5 @@ import { showSelector } from "discourse/lib/emoji/emoji-toolbar"; +import { onToolbarCreate } from 'discourse/components/d-editor'; export default { name: 'enable-emoji', @@ -6,6 +7,18 @@ export default { initialize(container) { const siteSettings = container.lookup('site-settings:main'); if (siteSettings.enable_emoji) { + + onToolbarCreate(toolbar => { + toolbar.addButton({ + id: 'emoji', + group: 'extras', + icon: 'smile-o', + action: 'emoji', + shortcut: 'Alt+E', + title: 'composer.emoji' + }); + }); + window.PagedownCustom.appendButtons.push({ id: 'wmd-emoji-button', description: I18n.t("composer.emoji"), diff --git a/app/assets/javascripts/discourse/lib/emoji/emoji-toolbar.js.es6 b/app/assets/javascripts/discourse/lib/emoji/emoji-toolbar.js.es6 index ffd54875ce..5219e39faa 100644 --- a/app/assets/javascripts/discourse/lib/emoji/emoji-toolbar.js.es6 +++ b/app/assets/javascripts/discourse/lib/emoji/emoji-toolbar.js.es6 @@ -4,7 +4,9 @@ import KeyValueStore from "discourse/lib/key-value-store"; const keyValueStore = new KeyValueStore("discourse_emojis_"); const EMOJI_USAGE = "emojiUsage"; -const PER_ROW = 12, PER_PAGE = 60; +let PER_ROW = 12; +const PER_PAGE = 60; + let ungroupedIcons, recentlyUsedIcons; if (!keyValueStore.getObject(EMOJI_USAGE)) { @@ -159,6 +161,7 @@ function showSelector(options) { options.appendTo.append('
'); $('.emoji-modal-wrapper').click(() => closeSelector()); + if (Discourse.Mobile.mobileView) PER_ROW = 9; const page = keyValueStore.getInt("emojiPage", 0); const offset = keyValueStore.getInt("emojiOffset", 0); diff --git a/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb b/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb index 8a8fceb252..eff6b85e8e 100644 --- a/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb +++ b/app/assets/javascripts/discourse/lib/emoji/emoji.js.erb @@ -12,6 +12,11 @@ Discourse.Dialect.registerEmoji = function(code, url) { extendedEmoji[code] = url; }; +// This method is used by PrettyText to reset custom emojis in multisites +Discourse.Dialect.resetEmoji = function() { + extendedEmoji = {}; +}; + Discourse.Emoji.list = function(){ var list = emoji.slice(0); _.each(extendedEmoji, function(v,k){ list.push(k); }); diff --git a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 index 6d8f6ab285..6a507050f0 100644 --- a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 +++ b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 @@ -99,7 +99,7 @@ export default { $('.topic-post.selected button.create').click(); // lazy but should work for now setTimeout(function() { - $('#wmd-quote-post').click(); + $('.wmd-quote-post').click(); }, 500); }, @@ -358,8 +358,8 @@ export default { }, _changeSection(direction) { - const $sections = $('#navigation-bar li'), - active = $('#navigation-bar li.active'), + const $sections = $('.nav.nav-pills li'), + active = $('.nav.nav-pills li.active'), index = $sections.index(active) + direction; if (index >= 0 && index < $sections.length) { diff --git a/app/assets/javascripts/discourse/mixins/bulk-topic-selection.js.es6 b/app/assets/javascripts/discourse/mixins/bulk-topic-selection.js.es6 index c0e7650d8b..705f281a35 100644 --- a/app/assets/javascripts/discourse/mixins/bulk-topic-selection.js.es6 +++ b/app/assets/javascripts/discourse/mixins/bulk-topic-selection.js.es6 @@ -42,6 +42,7 @@ export default Ember.Mixin.create({ }); tracker.incrementMessageCount(); } + self.send('closeModal'); self.send('refresh'); }); } diff --git a/app/assets/javascripts/discourse/models/composer.js.es6 b/app/assets/javascripts/discourse/models/composer.js.es6 index 366a55e73e..f566ef943a 100644 --- a/app/assets/javascripts/discourse/models/composer.js.es6 +++ b/app/assets/javascripts/discourse/models/composer.js.es6 @@ -201,7 +201,7 @@ const Composer = RestModel.extend({ return this.get('canCategorize') && !this.siteSettings.allow_uncategorized_topics && !this.get('categoryId') && - !this.user.get('staff'); + !this.user.get('admin'); } }.property('loading', 'canEditTitle', 'titleLength', 'targetUsernames', 'replyLength', 'categoryId', 'missingReplyCharacters'), diff --git a/app/assets/javascripts/discourse/models/post-stream.js.es6 b/app/assets/javascripts/discourse/models/post-stream.js.es6 index 010330451b..4ea6646f03 100644 --- a/app/assets/javascripts/discourse/models/post-stream.js.es6 +++ b/app/assets/javascripts/discourse/models/post-stream.js.es6 @@ -445,8 +445,7 @@ const PostStream = RestModel.extend({ const url = "/posts/" + postId; const store = this.store; - return Discourse.ajax(url).then((p) => - this.storePost(store.createRecord('post', p))); + return Discourse.ajax(url).then(p => this.storePost(store.createRecord('post', p))); }, /** diff --git a/app/assets/javascripts/discourse/models/topic.js.es6 b/app/assets/javascripts/discourse/models/topic.js.es6 index 3b63069ed7..9fc50d38df 100644 --- a/app/assets/javascripts/discourse/models/topic.js.es6 +++ b/app/assets/javascripts/discourse/models/topic.js.es6 @@ -8,6 +8,21 @@ const Topic = RestModel.extend({ message: null, errorLoading: false, + @computed('posters.firstObject') + creator(poster){ + return poster && poster.user; + }, + + @computed('posters.@each') + lastPoster(posters) { + if (posters && posters.length > 0) { + const latest = posters.filter(p => p.extras && p.extras.indexOf("latest") >= 0)[0]; + return latest.user; + } else { + return this.get("creator"); + } + }, + @computed('fancy_title') fancyTitle(title) { title = title || ""; diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6 index 87278959ef..3fc570c3a4 100644 --- a/app/assets/javascripts/discourse/models/user.js.es6 +++ b/app/assets/javascripts/discourse/models/user.js.es6 @@ -68,6 +68,8 @@ const User = RestModel.extend({ adminPath: url('username_lower', "/admin/users/%@"), + mutedTopicsPath: url('/latest?state=muted'), + @computed("username") username_lower(username) { return username.toLowerCase(); diff --git a/app/assets/javascripts/discourse/routes/build-category-route.js.es6 b/app/assets/javascripts/discourse/routes/build-category-route.js.es6 index b1d75980d1..8456eaf4fa 100644 --- a/app/assets/javascripts/discourse/routes/build-category-route.js.es6 +++ b/app/assets/javascripts/discourse/routes/build-category-route.js.es6 @@ -7,7 +7,7 @@ export default (filter, params) => { queryParams, model(modelParams) { - return Discourse.Category.findBySlug(modelParams.slug, modelParams.parentSlug); + return { category: Discourse.Category.findBySlug(modelParams.slug, modelParams.parentSlug) }; }, afterModel(model, transition) { @@ -16,27 +16,27 @@ export default (filter, params) => { return; } - this._setupNavigation(model); - return Em.RSVP.all([this._createSubcategoryList(model), - this._retrieveTopicList(model, transition)]); + this._setupNavigation(model.category); + return Em.RSVP.all([this._createSubcategoryList(model.category), + this._retrieveTopicList(model.category, transition)]); }, - _setupNavigation(model) { + _setupNavigation(category) { const noSubcategories = params && !!params.no_subcategories, - filterMode = `c/${Discourse.Category.slugFor(model)}${noSubcategories ? "/none" : ""}/l/${filter}`; + filterMode = `c/${Discourse.Category.slugFor(category)}${noSubcategories ? "/none" : ""}/l/${filter}`; this.controllerFor('navigation/category').setProperties({ - category: model, + category, filterMode: filterMode, noSubcategories: params && params.no_subcategories, - canEditCategory: model.get('can_edit') + canEditCategory: category.get('can_edit') }); }, - _createSubcategoryList(model) { + _createSubcategoryList(category) { this._categoryList = null; - if (Em.isNone(model.get('parentCategory')) && Discourse.SiteSettings.show_subcategory_list) { - return Discourse.CategoryList.listForParent(this.store, model) + if (Em.isNone(category.get('parentCategory')) && Discourse.SiteSettings.show_subcategory_list) { + return Discourse.CategoryList.listForParent(this.store, category) .then(list => this._categoryList = list); } @@ -44,28 +44,30 @@ export default (filter, params) => { return Em.RSVP.resolve(); }, - _retrieveTopicList(model, transition) { - const listFilter = `c/${Discourse.Category.slugFor(model)}/l/${filter}`, + _retrieveTopicList(category, transition) { + const listFilter = `c/${Discourse.Category.slugFor(category)}/l/${filter}`, findOpts = filterQueryParams(transition.queryParams, params), extras = { cached: this.isPoppedState(transition) }; return findTopicList(this.store, this.topicTrackingState, listFilter, findOpts, extras).then(list => { - Discourse.TopicList.hideUniformCategory(list, model); + Discourse.TopicList.hideUniformCategory(list, category); this.set('topics', list); + return list; }); }, titleToken() { const filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', { count: 0 }), - model = this.currentModel; + category = this.currentModel.category; - return I18n.t('filters.with_category', { filter: filterText, category: model.get('name') }); + return I18n.t('filters.with_category', { filter: filterText, category: category.get('name') }); }, setupController(controller, model) { const topics = this.get('topics'), + category = model.category, canCreateTopic = topics.get('can_create_topic'), - canCreateTopicOnCategory = model.get('permission') === Discourse.PermissionType.FULL; + canCreateTopicOnCategory = category.get('permission') === Discourse.PermissionType.FULL; this.controllerFor('navigation/category').setProperties({ canCreateTopicOnCategory: canCreateTopicOnCategory, @@ -75,7 +77,7 @@ export default (filter, params) => { var topicOpts = { model: topics, - category: model, + category, period: topics.get('for_period') || (filter.indexOf('/') > 0 ? filter.split('/')[1] : ''), selected: [], noSubcategories: params && !!params.no_subcategories, @@ -84,7 +86,7 @@ export default (filter, params) => { canCreateTopicOnCategory: canCreateTopicOnCategory }; - const p = model.get('params'); + const p = category.get('params'); if (p && Object.keys(p).length) { if (p.order !== undefined) { topicOpts.order = p.order; @@ -95,7 +97,7 @@ export default (filter, params) => { } this.controllerFor('discovery/topics').setProperties(topicOpts); - this.searchService.set('searchContext', model.get('searchContext')); + this.searchService.set('searchContext', category.get('searchContext')); this.set('topics', null); this.openTopicDraft(topics); diff --git a/app/assets/javascripts/discourse/routes/discovery.js.es6 b/app/assets/javascripts/discourse/routes/discovery.js.es6 index 83b5b4186b..400d1df1ee 100644 --- a/app/assets/javascripts/discourse/routes/discovery.js.es6 +++ b/app/assets/javascripts/discourse/routes/discovery.js.es6 @@ -5,7 +5,7 @@ import OpenComposer from "discourse/mixins/open-composer"; import { scrollTop } from "discourse/mixins/scroll-top"; -const DiscoveryRoute = Discourse.Route.extend(OpenComposer, { +export default Discourse.Route.extend(OpenComposer, { redirect() { return this.redirectIfLoginRequired(); }, @@ -46,9 +46,16 @@ const DiscoveryRoute = Discourse.Route.extend(OpenComposer, { createTopic() { this.openComposer(this.controllerFor("discovery/topics")); + }, + + dismissReadTopics(dismissTopics) { + var operationType = dismissTopics ? "topics" : "posts"; + this.controllerFor("discovery/topics").send('dismissRead', operationType); + }, + + dismissRead(operationType) { + this.controllerFor("discovery/topics").send('dismissRead', operationType); } } }); - -export default DiscoveryRoute; diff --git a/app/assets/javascripts/discourse/routes/topic.js.es6 b/app/assets/javascripts/discourse/routes/topic.js.es6 index 8bfdf13d5b..976de12166 100644 --- a/app/assets/javascripts/discourse/routes/topic.js.es6 +++ b/app/assets/javascripts/discourse/routes/topic.js.es6 @@ -43,7 +43,7 @@ const TopicRoute = Discourse.Route.extend({ showFlags(model) { showModal('flag', { model }); - this.controllerFor('flag').setProperties({ selected: null }); + this.controllerFor('flag').setProperties({ selected: null, flagTopic: false }); }, showFlagTopic(model) { diff --git a/app/assets/javascripts/discourse/routes/user.js.es6 b/app/assets/javascripts/discourse/routes/user.js.es6 index 7fb8fffe6f..040f949b5a 100644 --- a/app/assets/javascripts/discourse/routes/user.js.es6 +++ b/app/assets/javascripts/discourse/routes/user.js.es6 @@ -33,6 +33,12 @@ export default Discourse.Route.extend({ } }, + beforeModel() { + if (this.siteSettings.hide_user_profiles_from_public && !this.currentUser) { + this.replaceWith("discovery"); + } + }, + model(params) { // If we're viewing the currently logged in user, return that object instead const currentUser = this.currentUser; diff --git a/app/assets/javascripts/discourse/routes/users.js.es6 b/app/assets/javascripts/discourse/routes/users.js.es6 index beb25276fc..ab3cbe3206 100644 --- a/app/assets/javascripts/discourse/routes/users.js.es6 +++ b/app/assets/javascripts/discourse/routes/users.js.es6 @@ -23,6 +23,12 @@ export default Discourse.Route.extend({ } }, + beforeModel() { + if (this.siteSettings.hide_user_profiles_from_public && !this.currentUser) { + this.replaceWith("discovery"); + } + }, + model(params) { // If we refresh via `refreshModel` set the old model to loading this._params = params; diff --git a/app/assets/javascripts/discourse/templates/components/d-editor.hbs b/app/assets/javascripts/discourse/templates/components/d-editor.hbs index 8921294cbe..5375d94c18 100644 --- a/app/assets/javascripts/discourse/templates/components/d-editor.hbs +++ b/app/assets/javascripts/discourse/templates/components/d-editor.hbs @@ -8,20 +8,14 @@
- {{d-button action="bold" icon="bold" class="bold"}} - {{d-button action="italic" icon="italic" class="italic"}} -
- {{d-button action="showLinkModal" icon="link" class="link"}} - {{d-button action="quote" icon="quote-right" class="quote"}} - {{d-button action="code" icon="code" class="code"}} -
- {{d-button action="bullet" icon="list-ul" class="bullet"}} - {{d-button action="list" icon="list-ol" class="list"}} - {{d-button action="heading" icon="font" class="heading"}} - {{d-button action="rule" icon="minus" class="rule"}} - {{#if siteSettings.enable_emoji}} - {{d-button action="emoji" icon="smile-o" class="emoji"}} - {{/if}} + {{#each toolbar.groups as |group|}} + {{#each group.buttons as |b|}} + {{d-button action=b.action actionParam=b translatedTitle=b.title icon=b.icon class=b.className}} + {{/each}} + {{#unless group.lastGroup}} +
+ {{/unless}} + {{/each}}
{{textarea value=value class="d-editor-input"}} diff --git a/app/assets/javascripts/discourse/templates/components/hamburger-menu.hbs b/app/assets/javascripts/discourse/templates/components/hamburger-menu.hbs index 0deea8e1a7..3d875eb606 100644 --- a/app/assets/javascripts/discourse/templates/components/hamburger-menu.hbs +++ b/app/assets/javascripts/discourse/templates/components/hamburger-menu.hbs @@ -57,7 +57,7 @@
  • {{d-link route="badges" class="badge-link" label="badges.title"}}
  • {{/if}} - {{#if siteSettings.enable_user_directory}} + {{#if showUserDirectoryLink}}
  • {{d-link route="users" class="user-directory-link" label="directory.title"}}
  • {{/if}} diff --git a/app/assets/javascripts/discourse/templates/components/home-logo.hbs b/app/assets/javascripts/discourse/templates/components/home-logo.hbs index 976aefd88f..b2b8f9e6db 100644 --- a/app/assets/javascripts/discourse/templates/components/home-logo.hbs +++ b/app/assets/javascripts/discourse/templates/components/home-logo.hbs @@ -1,18 +1,15 @@ {{#if showSmallLogo}} {{#if smallLogoUrl}} - {{else}} {{/if}} {{else}} {{#if showMobileLogo}} - {{else}} {{#if bigLogoUrl}} - {{else}} diff --git a/app/assets/javascripts/discourse/templates/components/signup-cta.hbs b/app/assets/javascripts/discourse/templates/components/signup-cta.hbs index 721c38158e..e4a4ff28d2 100644 --- a/app/assets/javascripts/discourse/templates/components/signup-cta.hbs +++ b/app/assets/javascripts/discourse/templates/components/signup-cta.hbs @@ -7,7 +7,6 @@ {{else}}

    {{replace-emoji (i18n "signup_cta.intro")}}

    {{replace-emoji (i18n "signup_cta.value_prop")}}

    -

    {{signupMethodsTranslated}}

    {{d-button action="showCreateAccount" label="signup_cta.sign_up" icon="check" class="btn-primary"}} diff --git a/app/assets/javascripts/discourse/templates/discovery/topics.hbs b/app/assets/javascripts/discourse/templates/discovery/topics.hbs index b57679afc7..9b55d626ae 100644 --- a/app/assets/javascripts/discourse/templates/discovery/topics.hbs +++ b/app/assets/javascripts/discourse/templates/discovery/topics.hbs @@ -5,8 +5,7 @@ {{#if showDismissAtTop}}
    {{#if showDismissRead}} - - + {{/if}} {{#if showResetNew}} @@ -55,8 +54,7 @@ {{conditional-loading-spinner condition=model.loadingMore}} {{#if allLoaded}} {{#if showDismissRead}} - - + {{/if}} {{#if showResetNew}} diff --git a/app/assets/javascripts/discourse/templates/header.hbs b/app/assets/javascripts/discourse/templates/header.hbs index 9624352a34..28da2d800c 100644 --- a/app/assets/javascripts/discourse/templates/header.hbs +++ b/app/assets/javascripts/discourse/templates/header.hbs @@ -22,7 +22,7 @@ mobileAction="fullPageSearch" loginAction="showLogin" title="search.title" - href="search"}} + path="/search"}} {{/header-dropdown}} {{#header-dropdown iconId="toggle-hamburger-menu" diff --git a/app/assets/javascripts/discourse/templates/mobile/discovery/topics.hbs b/app/assets/javascripts/discourse/templates/mobile/discovery/topics.hbs index ae964b46e3..3355aef462 100644 --- a/app/assets/javascripts/discourse/templates/mobile/discovery/topics.hbs +++ b/app/assets/javascripts/discourse/templates/mobile/discovery/topics.hbs @@ -25,8 +25,7 @@ {{conditional-loading-spinner condition=model.loadingMore}} {{#if allLoaded}} {{#if showDismissRead}} - - + {{/if}} {{#if showResetNew}} diff --git a/app/assets/javascripts/discourse/templates/mobile/list/topic_list_item.raw.hbs b/app/assets/javascripts/discourse/templates/mobile/list/topic_list_item.raw.hbs index aa4370c966..7e61ac9561 100644 --- a/app/assets/javascripts/discourse/templates/mobile/list/topic_list_item.raw.hbs +++ b/app/assets/javascripts/discourse/templates/mobile/list/topic_list_item.raw.hbs @@ -1,28 +1,38 @@ - -
    - {{raw "list/post-count-or-badges" topic=content postBadgesEnabled=controller.showTopicPostBadges}} -
    -
    - -
    - {{#unless controller.hideCategory}} -
    - {{category-link content.category}} + {{~#unless content.hasExcerpt}} + +
    + {{else}} +
    + {{/unless~}} + - {{/unless}} - {{plugin-outlet "topic-list-tags"}} -
    -
    - {{raw "list/activity-column" topic=content tagName="span" class="age"}} - {{content.last_poster_username}} +
    + {{raw "list/post-count-or-badges" topic=content postBadgesEnabled=controller.showTopicPostBadges}} +
    + +
    + {{#unless controller.hideCategory}} +
    + {{category-link content.category}} +
    + {{/unless}} + + {{plugin-outlet "topic-list-tags"}} + + + +
    -
    -
    diff --git a/app/assets/javascripts/discourse/templates/modal/avatar_selector.hbs b/app/assets/javascripts/discourse/templates/modal/avatar_selector.hbs index e7d070d814..760ab1a580 100644 --- a/app/assets/javascripts/discourse/templates/modal/avatar_selector.hbs +++ b/app/assets/javascripts/discourse/templates/modal/avatar_selector.hbs @@ -9,7 +9,7 @@ {{d-button action="refreshGravatar" title="user.change_avatar.refresh_gravatar_title" disabled=gravatarRefreshDisabled icon="refresh"}}
    - {{#if allowImageUpload}} + {{#if allowAvatarUpload}}
    - {{#if allowBackgrounds}} + {{#if siteSettings.allow_profile_backgrounds}}
    @@ -122,7 +118,7 @@
    {{/if}} - {{#if allowUserLocale}} + {{#if siteSettings.allow_user_locale}}
    @@ -144,6 +140,7 @@ {{#each uf in userFields}} {{user-field field=uf.field value=uf.value}} {{/each}} +
    @@ -212,7 +209,7 @@ {{preference-checkbox labelKey="user.enable_quoting" checked=model.enable_quoting}} {{preference-checkbox labelKey="user.dynamic_favicon" checked=model.dynamic_favicon}} {{preference-checkbox labelKey="user.disable_jump_reply" checked=model.disable_jump_reply}} - {{#unless editHistoryVisible}} + {{#unless siteSettings.edit_history_visible_to_public}} {{preference-checkbox labelKey="user.edit_history_public" checked=model.edit_history_public}} {{/unless}} @@ -238,6 +235,13 @@
    {{i18n 'user.muted_categories_instructions'}}
    +
    + + +
    +
    diff --git a/app/assets/javascripts/discourse/templates/user/user.hbs b/app/assets/javascripts/discourse/templates/user/user.hbs index a1f74c5dda..1f61a722de 100644 --- a/app/assets/javascripts/discourse/templates/user/user.hbs +++ b/app/assets/javascripts/discourse/templates/user/user.hbs @@ -34,27 +34,27 @@ @@ -122,9 +122,9 @@ {{/if}}
    {{i18n 'views'}}
    {{model.profile_view_count}}
    {{#if model.invited_by}} -
    {{i18n 'user.invited_by'}}
    {{#link-to 'user' model.invited_by}}{{model.invited_by.username}}{{/link-to}}
    +
    {{i18n 'user.invited_by'}}
    {{#link-to 'user' model.invited_by}}{{model.invited_by.username}}{{/link-to}}
    {{/if}} -
    {{i18n 'user.trust_level'}}
    {{model.trustLevel.name}}
    +
    {{i18n 'user.trust_level'}}
    {{model.trustLevel.name}}
    {{#if canCheckEmails}}
    {{i18n 'user.email.title'}}
    diff --git a/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 b/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 index 8ee4409353..8ba5288553 100644 --- a/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 +++ b/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 @@ -26,5 +26,6 @@ export default ContainerView.extend({ if (this.get('topic.details.can_create_post')) { this.attachViewClass('reply-button'); } + this.trigger('additionalButtons', this); } }); diff --git a/app/assets/javascripts/discourse/views/topic.js.es6 b/app/assets/javascripts/discourse/views/topic.js.es6 index 8a18282362..993f756dff 100644 --- a/app/assets/javascripts/discourse/views/topic.js.es6 +++ b/app/assets/javascripts/discourse/views/topic.js.es6 @@ -4,6 +4,7 @@ import ClickTrack from 'discourse/lib/click-track'; import { listenForViewEvent } from 'discourse/lib/app-events'; import { categoryBadgeHTML } from 'discourse/helpers/category-link'; import Scrolling from 'discourse/mixins/scrolling'; +import isElementInViewport from "discourse/lib/is-element-in-viewport"; const TopicView = Ember.View.extend(AddCategoryClass, AddArchetypeClass, Scrolling, { templateName: 'topic', @@ -117,6 +118,14 @@ const TopicView = Ember.View.extend(AddCategoryClass, AddArchetypeClass, Scrolli headerController.set('showExtraInfo', topic.get('postStream.firstPostNotLoaded')); } + // automatically unpin topics when the user reaches the bottom + if (topic.get("pinned")) { + const $topicFooterButtons = $("#topic-footer-buttons"); + if ($topicFooterButtons.length > 0 && isElementInViewport($topicFooterButtons)) { + Em.run.next(() => topic.clearPin()); + } + } + // Trigger a scrolled event this.appEvents.trigger('topic:scrolled', offset); }, diff --git a/app/assets/javascripts/discourse/views/upload-selector.js.es6 b/app/assets/javascripts/discourse/views/upload-selector.js.es6 index e8967b8b2b..4bf80f2aad 100644 --- a/app/assets/javascripts/discourse/views/upload-selector.js.es6 +++ b/app/assets/javascripts/discourse/views/upload-selector.js.es6 @@ -27,9 +27,9 @@ export default ModalBodyView.extend({ }, tip: function() { - const source = this.get("controller.local") ? "local" : "remote", - opts = { authorized_extensions: Discourse.Utilities.authorizedExtensions() }; - return uploadTranslate(source + "_tip", opts); + const source = this.get("controller.local") ? "local" : "remote"; + const authorized_extensions = Discourse.Utilities.authorizesAllExtensions() ? "" : `(${Discourse.Utilities.authorizedExtensions()})`; + return uploadTranslate(source + "_tip", { authorized_extensions }); }.property("controller.local"), hint: function() { diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss index 60396122e8..9046e2505a 100644 --- a/app/assets/stylesheets/common/admin/admin_base.scss +++ b/app/assets/stylesheets/common/admin/admin_base.scss @@ -213,6 +213,19 @@ td.flaggers td { display: inline-block; margin-right: 5px; } + #last-seen { + float: none; + } + .ac-wrap { + display: inline-block; + vertical-align: middle; + padding: 0; + } +} + +.paste-users { + width: 400px; + height: 150px; } .groups, .badges { @@ -1015,6 +1028,11 @@ table.api-keys { } } +.groups-bulk { + .control { + margin-bottom: 1em; + } +} .commits-widget { border: solid 1px dark-light-diff($primary, $secondary, 90%, -60%); diff --git a/app/assets/stylesheets/common/base/emoji.scss b/app/assets/stylesheets/common/base/emoji.scss index 264416f1b6..107fbd11af 100644 --- a/app/assets/stylesheets/common/base/emoji.scss +++ b/app/assets/stylesheets/common/base/emoji.scss @@ -9,11 +9,14 @@ body img.emoji { } .emoji-modal { - @include transform(translate(-50%, -50%)); z-index: 10000; position: fixed; left: 50%; top: 50%; + width: 445px; + height: 264px; + margin-top: -132px; + margin-left: -222px; background-color: dark-light-choose(#dadada, blend-primary-secondary(5%)); } diff --git a/app/assets/stylesheets/common/base/header.scss b/app/assets/stylesheets/common/base/header.scss index bc20cefeaa..51d5835c2b 100644 --- a/app/assets/stylesheets/common/base/header.scss +++ b/app/assets/stylesheets/common/base/header.scss @@ -19,12 +19,6 @@ float: left; } - .valign-helper { - display: inline-block; - height: 100%; - vertical-align: middle; - } - #site-logo { max-height: 40px; } diff --git a/app/assets/stylesheets/common/base/onebox.scss b/app/assets/stylesheets/common/base/onebox.scss index b8b2acde7e..6b00a166e0 100644 --- a/app/assets/stylesheets/common/base/onebox.scss +++ b/app/assets/stylesheets/common/base/onebox.scss @@ -260,3 +260,40 @@ aside.onebox.twitterstatus .onebox-body { padding-top: 5px; } } + +// Onebox - Imgur - Album +.onebox.imgur-album { + .outer-box { + position: absolute; + z-index: 935; + width: 100%; + height: 30px; + overflow: hidden; + font-size: 12px; + color: #fff; + background-color: rgba(0, 0, 0, 0.6); + + .inner-box { + padding-left: 10px; + padding-right: 10px; + overflow: hidden; + text-overflow: ellipsis; + word-wrap: normal; + white-space: nowrap; + + .album-title { + width: 100%; + font-size: 13px; + line-height: 30px; + color: #ccc; + text-decoration: none; + } + } + } +} + +// resize stackexchange onebox image +aside.onebox.stackexchange .onebox-body img { + max-height: 60%; + max-width: 10%; +} diff --git a/app/assets/stylesheets/common/base/upload.scss b/app/assets/stylesheets/common/base/upload.scss index 9777fd3204..84e29bb14a 100644 --- a/app/assets/stylesheets/common/base/upload.scss +++ b/app/assets/stylesheets/common/base/upload.scss @@ -1,6 +1,6 @@ .uploaded-image-preview { + background: $primary center; background-size: cover; - background: $primary center center; } .image-uploader.no-repeat { diff --git a/app/assets/stylesheets/desktop/discourse.scss b/app/assets/stylesheets/desktop/discourse.scss index 17baebbc1c..543521bccf 100644 --- a/app/assets/stylesheets/desktop/discourse.scss +++ b/app/assets/stylesheets/desktop/discourse.scss @@ -84,7 +84,7 @@ body { margin: 0; i { font-size: 1.071em; - } + } } i.fa-envelope { diff --git a/app/assets/stylesheets/desktop/topic-list.scss b/app/assets/stylesheets/desktop/topic-list.scss index b0432b2fc2..c62ce07318 100644 --- a/app/assets/stylesheets/desktop/topic-list.scss +++ b/app/assets/stylesheets/desktop/topic-list.scss @@ -298,6 +298,7 @@ button.dismiss-read { @media all and (max-width : 850px) { + // slightly smaller font, tighten spacing on nav pills .nav-pills { > li > a { font-size: 1em; @@ -305,60 +306,32 @@ and (max-width : 850px) { } } - .list-controls { - - .btn { - font-size: 1em - } - - .category-dropdown-menu { - min-width: 139px; - } - - a.badge-category { - font-size: 1em; - } - - } - .topic-list { - .categories td.category { - padding-left: 10px; - } + + // tighter table header spacing th:first-of-type { padding: 12px 5px; } - th { - .btn .fa { - margin-right: 2px; - } - } + // smaller table cell font and cell spacing th, td { padding: 12px 2px; font-size: 0.929em; } - .star { - padding: 12px 5px; - width: auto; - } .main-link { font-size: 1.071em; - padding: 12px 8px 12px 0px; - } - - .likes { - width: auto; } .category { min-width: 0; padding: 0; } - .topic-excerpt { - padding-right: 20px; - } - th.posters { - text-align: center; - } + // suppress views column + th.views { + display: none; + } + td.views { + display: none; + } + // show only the first poster .posters { min-width: 0; width: 50px; @@ -368,6 +341,6 @@ and (max-width : 850px) { a.latest { padding: 0 8px; } - } + } } } diff --git a/app/assets/stylesheets/desktop/upload.scss b/app/assets/stylesheets/desktop/upload.scss index 5dc9fe66e4..0d37a0919a 100644 --- a/app/assets/stylesheets/desktop/upload.scss +++ b/app/assets/stylesheets/desktop/upload.scss @@ -37,6 +37,6 @@ .image-upload-controls { padding: 10px; label.btn { - padding: 7px 10px 5px 10px; + padding: 6px 10px; } } diff --git a/app/assets/stylesheets/mobile/alert.scss b/app/assets/stylesheets/mobile/alert.scss index dbd1770bec..b7ff758af0 100644 --- a/app/assets/stylesheets/mobile/alert.scss +++ b/app/assets/stylesheets/mobile/alert.scss @@ -5,6 +5,8 @@ // there are (n) new or updated topics, click to show .alert.alert-info { margin: 0; + margin-bottom: -3px; + margin-top: -5px; padding: 15px; font-size: 1.1em; } diff --git a/app/assets/stylesheets/mobile/banner.scss b/app/assets/stylesheets/mobile/banner.scss index bc82f05204..8740699c6b 100644 --- a/app/assets/stylesheets/mobile/banner.scss +++ b/app/assets/stylesheets/mobile/banner.scss @@ -3,7 +3,9 @@ // -------------------------------------------------- #banner { - margin: 10px; + // go full width on mobile, by extending into the 10px wrap + // borders on left and right + margin: 0 -10px; @media all and (max-height: 499px) { max-height: 100px; diff --git a/app/assets/stylesheets/mobile/discourse.scss b/app/assets/stylesheets/mobile/discourse.scss index d88232804a..a023c2e7ef 100644 --- a/app/assets/stylesheets/mobile/discourse.scss +++ b/app/assets/stylesheets/mobile/discourse.scss @@ -65,7 +65,6 @@ blockquote { .topic-statuses { display: inline-block; - vertical-align: middle; .topic-status { i { color: dark-light-diff($secondary, $primary, 40%, -20%); diff --git a/app/assets/stylesheets/mobile/header.scss b/app/assets/stylesheets/mobile/header.scss index 25fd40d141..3b8e8e15f4 100644 --- a/app/assets/stylesheets/mobile/header.scss +++ b/app/assets/stylesheets/mobile/header.scss @@ -5,12 +5,12 @@ .d-header { #site-logo { - max-width: 155px; + max-width: 130px; } // some protection for text-only site titles .title { - max-width: 160px; + max-width: 130px; height: 39px; overflow: hidden; padding: 0; diff --git a/app/assets/stylesheets/mobile/topic-list.scss b/app/assets/stylesheets/mobile/topic-list.scss index 043fe85f6d..c7340dcdc7 100644 --- a/app/assets/stylesheets/mobile/topic-list.scss +++ b/app/assets/stylesheets/mobile/topic-list.scss @@ -63,6 +63,10 @@ .topic-list { + .right { + margin-left: 55px; + } + > tbody > tr { &.highlighted { background-color: dark-light-choose(scale-color($tertiary, $lightness: 85%), scale-color($tertiary, $lightness: -55%)); @@ -112,15 +116,13 @@ } } - .num.posts { - font-weight: bold; - text-align: right; - } .age { white-space: nowrap; a { - padding: 15px 10px 15px 5px; + // let's make all ages dim on mobile so we're not + // overwhelming people with info about each topic + color: dark-light-choose(scale-color($primary, $lightness: 70%), scale-color($secondary, $lightness: 30%)) !important; } } } @@ -140,6 +142,7 @@ .posts { width: 10%; + vertical-align: top; } .age { @@ -236,10 +239,15 @@ tr.category-topic-link { font-size: 110%; } - .category-topic-link .num { - white-space: nowrap; - .number { - font-size: 1.071em; + .category-topic-link { + .num { + white-space: nowrap; + .number { + font-size: 1.071em; + } + } + .topic-excerpt { + width: 110%; } } @@ -400,8 +408,12 @@ td .main-link { } .topic-list { .posts-map { - display: inline; - font-size: 1.071em; - padding-top: 2px; + font-size: 1.15em; + } + // so the topic excerpt is full width + // as the containing div is 80% + .topic-excerpt { + padding-right: 0; + width: 120%; } } diff --git a/app/assets/stylesheets/mobile/user.scss b/app/assets/stylesheets/mobile/user.scss index b4acd17022..58e9ed8f0b 100644 --- a/app/assets/stylesheets/mobile/user.scss +++ b/app/assets/stylesheets/mobile/user.scss @@ -256,8 +256,9 @@ } .details { - padding: 15px 15px 4px 15px; + padding: 15px 10px 4px 10px; background-color: dark-light-choose(rgba($primary, .9), rgba($secondary, .9)); + opacity: 0.8; h1 { font-size: 2.143em; @@ -291,7 +292,6 @@ img.avatar { float: left; - margin-right: 15px; } .suspended { diff --git a/app/controllers/admin/email_controller.rb b/app/controllers/admin/email_controller.rb index 8a6615f721..5ae6a32056 100644 --- a/app/controllers/admin/email_controller.rb +++ b/app/controllers/admin/email_controller.rb @@ -34,7 +34,9 @@ class Admin::EmailController < Admin::AdminController def preview_digest params.require(:last_seen_at) - renderer = Email::Renderer.new(UserNotifications.digest(current_user, since: params[:last_seen_at])) + params.require(:username) + user = User.find_by_username(params[:username]) + renderer = Email::Renderer.new(UserNotifications.digest(user, since: params[:last_seen_at])) render json: MultiJson.dump(html_content: renderer.html, text_content: renderer.text) end diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 767657f1e1..67e8d86966 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -19,6 +19,42 @@ class Admin::GroupsController < Admin::AdminController render nothing: true end + def bulk + render nothing: true + end + + def bulk_perform + group = Group.find(params[:group_id].to_i) + if group.present? + users = (params[:users] || []).map {|u| u.downcase} + user_ids = User.where("username_lower in (:users) OR email IN (:users)", users: users).pluck(:id) + + if user_ids.present? + Group.exec_sql("INSERT INTO group_users + (group_id, user_id, created_at, updated_at) + SELECT #{group.id}, + u.id, + CURRENT_TIMESTAMP, + CURRENT_TIMESTAMP + FROM users AS u + WHERE u.id IN (#{user_ids.join(', ')}) + AND NOT EXISTS(SELECT 1 FROM group_users AS gu + WHERE gu.user_id = u.id AND + gu.group_id = #{group.id})") + + if group.primary_group? + User.where(id: user_ids).update_all(primary_group_id: group.id) + end + + if group.title.present? + User.where(id: user_ids).update_all(title: group.title) + end + end + end + + render json: success_json + end + def create group = Group.new diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index c096cf078f..ee03ac7058 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -121,7 +121,10 @@ class Admin::UsersController < Admin::AdminController def add_group group = Group.find(params[:group_id].to_i) return render_json_error group unless group && !group.automatic - group.users << @user + + # We don't care about duplicate group assignment + group.users << @user rescue ActiveRecord::RecordNotUnique + render nothing: true end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e8376b6a28..db2812b528 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -86,13 +86,11 @@ class ApplicationController < ActionController::Base rescue_from Discourse::NotLoggedIn do |e| raise e if Rails.env.test? - if (request.format && request.format.json?) || request.xhr? || !request.get? rescue_discourse_actions(:not_logged_in, 403, true) else - redirect_to path("/") + rescue_discourse_actions(:not_found, 404) end - end rescue_from Discourse::NotFound do @@ -243,7 +241,7 @@ class ApplicationController < ActionController::Base end def can_cache_content? - !current_user.present? + current_user.blank? && flash[:authentication_data].blank? end # Our custom cache method diff --git a/app/controllers/session_controller.rb b/app/controllers/session_controller.rb index a2a771a354..60765e0cd8 100644 --- a/app/controllers/session_controller.rb +++ b/app/controllers/session_controller.rb @@ -37,7 +37,11 @@ class SessionController < ApplicationController sso.external_id = current_user.id.to_s sso.admin = current_user.admin? sso.moderator = current_user.moderator? - redirect_to sso.to_url(sso.return_sso_url) + if request.xhr? + cookies[:sso_destination_url] = sso.to_url(sso.return_sso_url) + else + redirect_to sso.to_url(sso.return_sso_url) + end else session[:sso_payload] = request.query_string redirect_to path('/login') @@ -266,9 +270,8 @@ class SessionController < ApplicationController if payload = session.delete(:sso_payload) sso_provider(payload) - else - render_serialized(user, UserSerializer) end + render_serialized(user, UserSerializer) end end diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 39209b417f..a7fc7aaf49 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -57,6 +57,7 @@ class Users::OmniauthCallbacksController < ApplicationController complete_response_data if provider && provider.full_screen_login + cookies['_bypass_cache'] = true flash[:authentication_data] = @auth_result.to_client_hash.to_json redirect_to @origin else diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index eb28b8cb18..1c2be6d1ba 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -29,6 +29,8 @@ class UsersController < ApplicationController end def show + raise Discourse::InvalidAccess if SiteSetting.hide_user_profiles_from_public && !current_user + @user = fetch_user_from_params user_serializer = UserSerializer.new(@user, scope: guardian, root: 'user') if params[:stats].to_s == "false" @@ -162,7 +164,6 @@ class UsersController < ApplicationController end def my_redirect - raise Discourse::NotFound if params[:path] !~ /^[a-z\-\/]+$/ if current_user.blank? @@ -498,8 +499,10 @@ class UsersController < ApplicationController end def send_activation_email - RateLimiter.new(nil, "activate-hr-#{request.remote_ip}", 30, 1.hour).performed! - RateLimiter.new(nil, "activate-min-#{request.remote_ip}", 6, 1.minute).performed! + if current_user.blank? || !current_user.staff? + RateLimiter.new(nil, "activate-hr-#{request.remote_ip}", 30, 1.hour).performed! + RateLimiter.new(nil, "activate-min-#{request.remote_ip}", 6, 1.minute).performed! + end @user = User.find_by_username_or_email(params[:username].to_s) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5b1a863f22..022141a73a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -129,6 +129,8 @@ module ApplicationHelper if opts[:image].present? && opts[:image].start_with?("//") uri = URI(Discourse.base_url) opts[:image] = "#{uri.scheme}:#{opts[:image]}" + elsif opts[:image].present? && opts[:image].start_with?("/uploads/") + opts[:image] = "#{Discourse.base_url}#{opts[:image]}" end # Add opengraph tags diff --git a/app/jobs/regular/export_csv_file.rb b/app/jobs/regular/export_csv_file.rb index d3d2d3da89..236c3a4bd9 100644 --- a/app/jobs/regular/export_csv_file.rb +++ b/app/jobs/regular/export_csv_file.rb @@ -51,14 +51,66 @@ module Jobs end def user_list_export - query = ::AdminUserIndexQuery.new - user_data = query.find_users_query.to_a - user_data.map do |user| - group_names = get_group_names(user).join(';') - user_array = get_user_list_fields(user) - user_array.push(group_names) if group_names != '' - user_array + user_array = [] + user_field_ids = UserField.pluck(:id) + + if SiteSetting.enable_sso + # SSO enabled + User.includes(:user_stat, :single_sign_on_record, :groups).find_each do |user| + user_info_string = "#{user.id},#{user.name},#{user.username},#{user.email},#{user.title},#{user.created_at},#{user.last_seen_at},#{user.last_posted_at},#{user.last_emailed_at},#{user.trust_level},#{user.approved},#{user.suspended_at},#{user.suspended_till},#{user.blocked},#{user.active},#{user.admin},#{user.moderator},#{user.ip_address},#{user.user_stat.topics_entered},#{user.user_stat.posts_read_count},#{user.user_stat.time_read},#{user.user_stat.topic_count},#{user.user_stat.post_count},#{user.user_stat.likes_given},#{user.user_stat.likes_received}" + + # sso + if user.single_sign_on_record + user_info_string << ",#{user.single_sign_on_record.external_id},#{user.single_sign_on_record.external_email},#{user.single_sign_on_record.external_username},#{user.single_sign_on_record.external_name},#{user.single_sign_on_record.external_avatar_url}" + else + user_info_string << ",nil,nil,nil,nil,nil" + end + + # custom fields + if user_field_ids.present? + user.user_fields.each do |custom_field| + user_info_string << ",#{custom_field[1]}" + end + end + + # group names + group_names = "" + user.groups.each do |group| + group_names << "#{group.name};" + end + user_info_string << ",#{group_names[0..-2]}" unless group_names.blank? + group_names = nil + + user_array.push(user_info_string.split(",")) + user_info_string = nil + end + else + # SSO disabled + User.includes(:user_stat, :groups).find_each do |user| + user_info_string = "#{user.id},#{user.name},#{user.username},#{user.email},#{user.title},#{user.created_at},#{user.last_seen_at},#{user.last_posted_at},#{user.last_emailed_at},#{user.trust_level},#{user.approved},#{user.suspended_at},#{user.suspended_till},#{user.blocked},#{user.active},#{user.admin},#{user.moderator},#{user.ip_address},#{user.user_stat.topics_entered},#{user.user_stat.posts_read_count},#{user.user_stat.time_read},#{user.user_stat.topic_count},#{user.user_stat.post_count},#{user.user_stat.likes_given},#{user.user_stat.likes_received}" + + # custom fields + if user_field_ids.present? + user.user_fields.each do |custom_field| + user_info_string << ",#{custom_field[1]}" + end + end + + # group names + group_names = "" + user.groups.each do |group| + group_names << "#{group.name};" + end + user_info_string << ",#{group_names[0..-2]}" unless group_names.blank? + group_names = nil + + user_array.push(user_info_string.split(",")) + user_info_string = nil + end end + + user_field_ids = nil + user_array end def staff_action_export @@ -129,15 +181,6 @@ module Jobs private - def get_group_names(user) - group_names = [] - groups = user.groups - groups.each do |group| - group_names.push(group.name) - end - return group_names - end - def get_user_archive_fields(user_archive) user_archive_array = [] topic_data = user_archive.topic @@ -170,34 +213,6 @@ module Jobs user_archive_array end - def get_user_list_fields(user) - user_array = [] - - HEADER_ATTRS_FOR['user_list'].each do |attr| - user_array.push(user.attributes[attr]) - end - - HEADER_ATTRS_FOR['user_stats'].each do |stat| - user_array.push(user.user_stat.attributes[stat]) - end - - if SiteSetting.enable_sso - sso = user.single_sign_on_record - HEADER_ATTRS_FOR['user_sso'].each do |stat| - field = sso.attributes[stat] if sso - user_array.push(field) - end - end - - if user.user_fields.present? - user.user_fields.each do |custom_field| - user_array.push(custom_field[1]) - end - end - - user_array - end - def get_staff_action_fields(staff_action) staff_action_array = [] diff --git a/app/jobs/regular/post_alert.rb b/app/jobs/regular/post_alert.rb index 36785df4e4..30cef2534b 100644 --- a/app/jobs/regular/post_alert.rb +++ b/app/jobs/regular/post_alert.rb @@ -3,10 +3,8 @@ module Jobs def execute(args) # maybe it was removed by the time we are making the post - if post = Post.find(args[:post_id]) - # maybe the topic was deleted, so skip in that case as well - PostAlerter.post_created(post) if post.topic - end + post = Post.where(id: args[:post_id]).first + PostAlerter.post_created(post) if post && post.topic end end diff --git a/app/jobs/regular/pull_hotlinked_images.rb b/app/jobs/regular/pull_hotlinked_images.rb index efe7457e5c..8c5ece783d 100644 --- a/app/jobs/regular/pull_hotlinked_images.rb +++ b/app/jobs/regular/pull_hotlinked_images.rb @@ -76,12 +76,7 @@ module Jobs end post.reload - if start_raw != post.raw - # post was edited - start over (after 10 minutes) - backoff = args.fetch(:backoff, 1) + 1 - delay = SiteSetting.ninja_edit_window * args[:backoff] - Jobs.enqueue_in(delay.seconds.to_i, :pull_hotlinked_images, args.merge!(backoff: backoff)) - elsif raw != post.raw + if start_raw == post.raw && raw != post.raw changes = { raw: raw, edit_reason: I18n.t("upload.edit_reason") } # we never want that job to bump the topic options = { bypass_bump: true } diff --git a/app/jobs/regular/resize_emoji.rb b/app/jobs/regular/resize_emoji.rb index e46879f8e0..fa30e629e7 100644 --- a/app/jobs/regular/resize_emoji.rb +++ b/app/jobs/regular/resize_emoji.rb @@ -11,7 +11,7 @@ module Jobs force_aspect_ratio: SiteSetting.enforce_square_emoji } # make sure emoji aren't too big - OptimizedImage.downsize(path, path, 100, 100, opts) + OptimizedImage.downsize(path, path, "100x100", opts) end end diff --git a/app/mailers/user_notifications.rb b/app/mailers/user_notifications.rb index a5b73f5db7..030c5caa7a 100644 --- a/app/mailers/user_notifications.rb +++ b/app/mailers/user_notifications.rb @@ -42,7 +42,12 @@ class UserNotifications < ActionMailer::Base end def short_date(dt) - I18n.l(dt, format: :short) + current = Time.now + if dt.year == current.year + dt.strftime("%B #{dt.day.ordinalize}") + else + dt.strftime("%B #{dt.day.ordinalize}, %Y") + end end def digest(user, opts={}) diff --git a/app/models/optimized_image.rb b/app/models/optimized_image.rb index c7ba61b10b..482585e8ea 100644 --- a/app/models/optimized_image.rb +++ b/app/models/optimized_image.rb @@ -142,10 +142,6 @@ class OptimizedImage < ActiveRecord::Base optimize("resize", from, to, "#{width}x#{height}", opts) end - def self.downsize(from, to, max_width, max_height, opts={}) - optimize("downsize", from, to, "#{max_width}x#{max_height}", opts) - end - def self.downsize(from, to, dimensions, opts={}) optimize("downsize", from, to, dimensions, opts) end diff --git a/app/models/topic.rb b/app/models/topic.rb index 37f9ebb331..d3fbb268dd 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -253,11 +253,8 @@ class Topic < ActiveRecord::Base # all users (in groups or directly targetted) that are going to get the pm def all_allowed_users - # TODO we should probably change this to 1 query - allowed_user_ids = allowed_users.select('users.id').to_a - allowed_group_user_ids = allowed_group_users.select('users.id').to_a - allowed_staff_ids = private_message? && has_flags? ? User.where(moderator: true).pluck(:id).to_a : [] - User.where('id IN (?)', allowed_user_ids + allowed_group_user_ids + allowed_staff_ids) + moderators_sql = " UNION #{User.moderators.to_sql}" if private_message? && has_flags? + User.from("(#{allowed_users.to_sql} UNION #{allowed_group_users.to_sql}#{moderators_sql}) as users") end # Additional rate limits on topics: per day and private messages per day @@ -585,7 +582,7 @@ class Topic < ActiveRecord::Base end end - if username_or_email =~ /^.+@.+$/ && !SiteSetting.enable_sso + if username_or_email =~ /^.+@.+$/ && !SiteSetting.enable_sso && SiteSetting.enable_local_logins # rate limit topic invite RateLimiter.new(invited_by, "topic-invitations-per-day", SiteSetting.max_topic_invitations_per_day, 1.day.to_i).performed! diff --git a/app/services/post_timestamp_changer.rb b/app/services/post_timestamp_changer.rb index 65b056128f..2364c12472 100644 --- a/app/services/post_timestamp_changer.rb +++ b/app/services/post_timestamp_changer.rb @@ -8,15 +8,19 @@ class PostTimestampChanger def change! ActiveRecord::Base.transaction do - update_topic + last_posted_at = @timestamp @posts.each do |post| if post.is_first_post? update_post(post, @timestamp) else - update_post(post, Time.at(post.created_at.to_f + @time_difference)) + new_created_at = Time.at(post.created_at.to_f + @time_difference) + last_posted_at = new_created_at if new_created_at > last_posted_at + update_post(post, new_created_at) end end + + update_topic(last_posted_at) end # Burst the cache for stats @@ -29,11 +33,12 @@ class PostTimestampChanger @timestamp - @topic.created_at end - def update_topic + def update_topic(last_posted_at) @topic.update_attributes( created_at: @timestamp, updated_at: @timestamp, - bumped_at: @timestamp + bumped_at: @timestamp, + last_posted_at: last_posted_at ) end diff --git a/bin/docker/boot_dev b/bin/docker/boot_dev new file mode 100755 index 0000000000..0b3ed1eca2 --- /dev/null +++ b/bin/docker/boot_dev @@ -0,0 +1,14 @@ +#!/bin/bash + +pushd `dirname $0` > /dev/null +SCRIPTPATH=`pwd -P` +popd > /dev/null + + +SOURCE_DIR=`(cd $SCRIPTPATH && cd ../../ && pwd)` +DATA_DIR=$SOURCE_DIR/tmp/postgres + +echo $SOURCE_DIR +echo $DATA_DIR + +docker run -d -p 3000:3000 -v $DATA_DIR:/shared/postgres_data -v $SOURCE_DIR:/src --hostname=discourse_dev --name=discourse_dev --restart=always discourse/dev /sbin/boot diff --git a/bin/docker/bundle b/bin/docker/bundle new file mode 100755 index 0000000000..d304ab4712 --- /dev/null +++ b/bin/docker/bundle @@ -0,0 +1,5 @@ +#!/bin/bash + +PARAMS="$@" +CMD="cd /src && HOME=/home/discourse chpst -u discourse:discourse bundle $PARAMS" +docker exec -it discourse_dev /bin/bash -c "$CMD" diff --git a/bin/docker/psql b/bin/docker/psql new file mode 100755 index 0000000000..6336af07b1 --- /dev/null +++ b/bin/docker/psql @@ -0,0 +1,5 @@ +#!/bin/bash + +PARAMS="$@" +CMD="chpst -u postgres psql $PARAMS" +docker exec -it discourse_dev /bin/bash -c "$CMD" diff --git a/bin/docker/rails b/bin/docker/rails new file mode 100755 index 0000000000..afbda65802 --- /dev/null +++ b/bin/docker/rails @@ -0,0 +1,9 @@ +#!/bin/bash + +PARAMS="$@" +if [[ $# = 1 ]] && [[ "$1" =~ "s" ]]; +then + PARAMS="$PARAMS -b 0.0.0.0" +fi +CMD="cd /src && HOME=/home/discourse RAILS_ENV=${RAILS_ENV:=development} chpst -u discourse:discourse rails $PARAMS" +docker exec -it discourse_dev /bin/bash -c "$CMD" diff --git a/bin/docker/rake b/bin/docker/rake new file mode 100755 index 0000000000..2ecac1b25e --- /dev/null +++ b/bin/docker/rake @@ -0,0 +1,5 @@ +#!/bin/bash + +PARAMS="$@" +CMD="cd /src && HOME=/home/discourse RAILS_ENV=${RAILS_ENV:=development} chpst -u discourse:discourse rake $PARAMS" +docker exec -it discourse_dev /bin/bash -c "$CMD" diff --git a/bin/docker/reset_db b/bin/docker/reset_db new file mode 100755 index 0000000000..2d1ae28c06 --- /dev/null +++ b/bin/docker/reset_db @@ -0,0 +1,12 @@ +#!/bin/bash + +pushd `dirname $0` > /dev/null +SCRIPTPATH=`pwd -P` +popd > /dev/null + + +SOURCE_DIR=`(cd $SCRIPTPATH && cd ../../ && pwd)` +DATA_DIR=$SOURCE_DIR/tmp/postgres + + +docker run -it -v $DATA_DIR:/shared/postgres_data samsaffron/discourse_dev:1.0.13 /bin/bash -c "rm -fr /shared/postgres_data/*" diff --git a/bin/docker/shutdown_dev b/bin/docker/shutdown_dev new file mode 100755 index 0000000000..557ccfe9df --- /dev/null +++ b/bin/docker/shutdown_dev @@ -0,0 +1,3 @@ +#!/bin/bash + +docker rm -f discourse_dev diff --git a/config/locales/client.ar.yml b/config/locales/client.ar.yml index 5205a07c28..b8399797e9 100644 --- a/config/locales/client.ar.yml +++ b/config/locales/client.ar.yml @@ -538,7 +538,7 @@ ar: tracked_categories: "Tracked" tracked_categories_instructions: "ستتبع بشكل تلقائي جميع المواضيع الجديدة في هذه التصنيفات. عدد المشاركات الجديدة سيظهر بجانب الموضوع." muted_categories: "كتم" - muted_categories_instructions: "تلقائيا ستقوم بمتابعة جميع المواضيع في هذا التصنيف , وسيتم اشعارك لجميع المشاركات والمواضيع وكذلك عداد الغيرمقروء والمشاركات الجديدة" + muted_categories_instructions: "لن يتم إشعارك بأي جديد عن المواضيع الجديدة في هذه التصنيفات، ولن تظهر مواضيع هذه التصنيفات في قائمة المواضيع المنشورة مؤخراً." delete_account: "حذف الحساب" delete_account_confirm: "هل انت متاكد من انك تريد حذف هذا المستخدم؟ هذا الإجراء دائماً!" deleted_yourself: "حسابك تم حذفه بنجاح" @@ -677,6 +677,13 @@ ar: user: "المستخدمين المدعويين" sent: "تم الإرسال" none: "لا توجد دعوات معلقة لعرضها." + truncated: + zero: "لا يوجد دعوات لعرضها." + one: "عرض الدعوة الأولى." + two: "عرض الدعوتان الأولتان." + few: "عرض الدعوات الأولية." + many: "عرض الدعوات {{count}} الأولى." + other: "عرض الدعوات {{count}} الأولى." redeemed: "دعوات مستخدمة" redeemed_tab: "محررة" redeemed_tab_with_count: "({{count}}) محررة" @@ -850,6 +857,9 @@ ar: admin_not_allowed_from_ip_address: "لا يمكنك تسجيل الدخول كمدير من خلال هذا العنوان الرقمي - IP." resend_activation_email: "اضغط هنا لإرسال رسالة إلكترونية أخرى لتفعيل الحساب." sent_activation_email_again: "لقد سبق وأن تم إرسال رسالة إلكترونية إلى {{currentEmail}} لتفعيل حسابك. تأكد من مجلد السبام في بريدك." + to_continue: "الرجاء تسجيل الدخول..." + preferences: "يتوجب عليك تسجيل الدخول لتغيير إعداداتك الشخصية." + forgot: "لا أذكر معلومات حسابي" google: title: "مع جوجل" message: "التحقق من خلال حساب جوجل ( الرجاء التأكد من عدم تشغيل مانع الاعلانات المنبثقة في المتصفح)" @@ -874,6 +884,7 @@ ar: emoji_one: "تعبيرات" composer: emoji: "تعبيرات: ابتسامة" + more_emoji: "أكثر..." options: "خيارات" whisper: "همس" add_warning: "هذا تحذير رسمي" @@ -906,7 +917,7 @@ ar: show_edit_reason: "(اضف سبب التعديل)" reply_placeholder: "أكتب هنا. استخدم Markdown, BBCode, أو HTML للتشكيل. اسحب أو الصق الصور." view_new_post: "الاطلاع على أحدث مشاركاتك" - saving: "يتم الحفظ..." + saving: "جارِ الحفظ" saved: "تم الحفظ" saved_draft: "جاري إضافة المسودة. اضغط للاستئناف" uploading: "يتم الرفع..." @@ -921,6 +932,7 @@ ar: link_description: "ادخل وصف الرابط هنا " link_dialog_title: "اضف الرابط" link_optional_text: "عنوان اختياري" + link_placeholder: "http://example.com \"نص إختياري\"" quote_title: "حظر الاقتباس" quote_text: "حظر الاقتباس" code_title: "الاطلاع على التنسيق" @@ -933,10 +945,10 @@ ar: heading_title: "اخفاء" heading_text: "اخفاء" hr_title: "Horizontal Rule" - undo_title: "تراجع" - redo_title: "تقدم" help: "مساعدة في الـ Maekdown" toggler: "اخف او اظهر معلومات الكاتب" + modal_ok: "موافق" + modal_cancel: "إلغاء" admin_options_title: "اختياري اضافة اعدادات الموضوع" auto_close: label: "اغلاق تلقائي لوقت الموضع" @@ -992,9 +1004,7 @@ ar: 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: "يتم الرفع" @@ -1035,10 +1045,10 @@ ar: bulk: reset_read: "تصفير القراءات" delete: "المواضيع المحذوفة" - dismiss_posts: "إخفاء المشاركات" - dismiss_posts_tooltip: "تصفير عدادا المواضيع الغير مقروءة مع الاستمرار في إظهارها في قائمة المواضيع الغير مقروءة عند إضافة مشاركات جديدة" + dismiss: "إخفاء" + dismiss_body: "هل تريد إخفاء المشاركات الجديدة فقط في هذه المواضيع؟ أم تريد إخفاء المواضيع بشكل كامل؟" + dismiss_posts: "إخفاء المشاركات الجديدة فقط" dismiss_topics: "إخفاء المواضيع" - dismiss_topics_tooltip: "توقف عن إظهار هذه المواضيع ضمن قائمة الغير مقروءة عند إضافة مشاركات جديدة لها" dismiss_new: "إخفاء الجديد" toggle: "إيقاف/تشغيل الاختيار المتعدد للمواضيع" actions: "عمليات تنفذ دفعة واحدة" @@ -1210,7 +1220,7 @@ ar: description: "لن يتم إشعارك بأي جديد يخص هذه الرسالة الخاصة." muted: title: "مكتوم" - description: "لن يتم إشعارك بأي جديد يخص هذا الموضوع ولن يظهرهذا الموضوع في تبويب المواضيع الغير مقروءة." + description: "لن يتم إشعارك بأي جديد يخص هذا الموضوع ولن يظهرهذا الموضوع في قائمة المواضيع المنشورة مؤخراً." actions: recover: "استرجاع الموضوع" delete: "حذف الموضوع" @@ -1471,6 +1481,7 @@ ar: revert_to_regular: "حذف اللون الوظيفي" rebake: "إعادة بناء HTML" unhide: "إظهار" + change_owner: "تغيير الملكية" actions: flag: 'التبليغات' defer_flags: @@ -1727,7 +1738,7 @@ ar: description: "سوف تُنبه اذا قام أحد بالاشارة لاسمك \"@name\" أو الرد عليك." muted: title: "كتم" - description: "لن يتم اعلامك باي مواضيع جديدة في هذه الفئة، ولن تظهر في صفحتك الخاصة بالمواضيع الغير مقروءه" + description: "لن يتم إشعارك بأي مشاركات جديدة في هذه التصنيفات ولن يتم عرضها في قائمة المواضيع المنشورة مؤخراً." flagging: title: 'شكرا لمساعدتك في إبقاء مجتمعنا نظيفاً.' private_reminder: 'التبليغات ذات خصوصية، تظهر فقط للمشرفين' @@ -1784,7 +1795,6 @@ ar: help: "هذا الموضوع غير مثبت بالنسبة لك, سيتم عرضه بالترتيب العادي" pinned_globally: title: "تثبيت عام" - help: "هذا الموضوع مثبت بشكل عام, سوف يظهر في المقدمة في جميع القوائم" pinned: title: "مثبت" help: "هذا الموضوع مثبت لك, سوف يتم عرضه في اول القسم" @@ -2731,9 +2741,7 @@ ar: embed_username_key_from_feed: "مفتاح لسحب اسم عضو discourse من المغذي" embed_truncate: "بتر المشاركات المضمنة" embed_whitelist_selector: "منتقي CSS للعناصر التي تسمح في التضمينات." - whitelist_example: "مقالة، #قصة، .مشاركة" embed_blacklist_selector: "منتقي CSS للعناصر التي حذفت من التضمينات." - blacklist_example: ".وحدة إعلان، رأس الصفحة" feed_polling_enabled: "استورد المشاركات عبر RSS/ATOM" feed_polling_url: "URL مغذي RSS/ATOM يتقدم ببطء." save: "أحفظ الإعدادات المضمنة" diff --git a/config/locales/client.bs_BA.yml b/config/locales/client.bs_BA.yml index 4946ca9e4f..f5bf93dddb 100644 --- a/config/locales/client.bs_BA.yml +++ b/config/locales/client.bs_BA.yml @@ -338,7 +338,6 @@ bs_BA: watched_categories: "Watched" tracked_categories: "Tracked" muted_categories: "Muted" - muted_categories_instructions: "You will not be notified of anything about new topics in these categories, and they will not appear on your unread tab." delete_account: "Delete My Account" delete_account_confirm: "Are you sure you want to permanently delete your account? This action cannot be undone!" deleted_yourself: "Your account has been deleted successfully." @@ -620,7 +619,6 @@ bs_BA: edit_reason_placeholder: "zašto pravite izmjenu?" show_edit_reason: "(dodaj razlog izmjene)" view_new_post: "Pogledaj svoj novi post." - saving: "Čuvam..." saved: "Sačuvano!" saved_draft: "Imate sačuvan post. Kliknite ovdje da nastavite sa izmjenama" uploading: "Uplodujem..." @@ -647,8 +645,6 @@ bs_BA: heading_title: "Naslov" heading_text: "Naslov" hr_title: "Horizontalna Crta" - undo_title: "Poništi" - redo_title: "Povrati" help: "Markdown Editing Help" toggler: "sakrij ili pokaži komposer" admin_options_title: "Optional staff settings for this topic" @@ -684,7 +680,6 @@ bs_BA: from_my_computer: "Sa mog uređaja" from_the_web: "Sa neta" remote_tip: "link do slike http://primjer.com/slika.jpg" - remote_tip_with_attachments: "link to image or file http://primjer.com/file.ext (allowed extensions: {{authorized_extensions}})." hint: "(možete i mišom prenijeti vaše slike direktno iz vašeg foldera ovdje)" uploading: "Uplodujem" image_link: "link do vaše slike će pokazivati" @@ -704,10 +699,7 @@ bs_BA: bulk: reset_read: "Reset Read" delete: "Delete Topics" - dismiss_posts: "Dismiss Posts" - dismiss_posts_tooltip: "Clear unread counts on these topics but continue to show them on my unread list when new posts are made" dismiss_topics: "Dismiss Topics" - dismiss_topics_tooltip: "Stop showing these topics in my unread list when new posts are made" dismiss_new: "Dismiss New" toggle: "toggle bulk selection of topics" actions: "Bulk Actions" @@ -817,7 +809,6 @@ bs_BA: description: "You will never be notified of anything about this private message." muted: title: "Mutirano" - description: "Obaviještenja za ovu temu su isključena i sistem vam neće prikazivati nove postove za ovu temu." actions: recover: "Un-Delete Topic" delete: "Delete Topic" @@ -1105,7 +1096,6 @@ bs_BA: help: "This topic is unpinned; it will display in default order" pinned_globally: title: "Zakačena Globalno" - help: "Ova tema je zakačena globalno; biće na vrhu svih listi" pinned: title: "Zakačena" help: "Ova tema je zakačena; biće na vrhu svoje kategorije" diff --git a/config/locales/client.cs.yml b/config/locales/client.cs.yml index 3d43f32535..bb5066b5ee 100644 --- a/config/locales/client.cs.yml +++ b/config/locales/client.cs.yml @@ -399,7 +399,6 @@ cs: tracked_categories: "Sledované" tracked_categories_instructions: "Všechna nová témata v této kategorii budou automaticky hlídaná. Počet nových příspěvků se zobrazí vedle tématu." muted_categories: "Ztišené" - muted_categories_instructions: "Nebudete upozorněni na žádná nová témata v těchto kategoriích a ani se nebudou zobrazovat jako nepřečtené." delete_account: "Smazat můj účet" delete_account_confirm: "Jste si jisti, že chcete trvale odstranit svůj účet? Tuto akci nelze vrátit zpět!" deleted_yourself: "Váš účet byl úspěšně odstraněn." @@ -721,7 +720,6 @@ cs: edit_reason_placeholder: "proč byla nutná úprava?" show_edit_reason: "(přidat důvod úpravy)" view_new_post: "Zobrazit váš nový příspěvek." - saving: "Ukládám..." saved: "Uloženo!" saved_draft: "Máte rozepsaný příspěvek. Klikněte pro obnovení." uploading: "Nahrávám..." @@ -748,8 +746,6 @@ cs: heading_title: "Nadpis" heading_text: "Nadpis" hr_title: "Horizontální oddělovač" - undo_title: "Zpět" - redo_title: "Opakovat" help: "Nápověda pro Markdown" toggler: "zobrazit nebo skrýt editor příspěvku" admin_options_title: "Volitelné administrační nastavení tématu" @@ -793,7 +789,6 @@ cs: from_my_computer: "Z mého zařízení" from_the_web: "Z webu" remote_tip: "odkaz na obrázek" - remote_tip_with_attachments: "odkaz na obrázek nebo osubor ({{authorized_extensions}})" hint: "(můžete také rovnou soubor do editoru přetáhnout)" uploading: "Nahrávám" select_file: "Vyberte soubor" @@ -815,10 +810,7 @@ cs: bulk: reset_read: "reset přečteného" delete: "Smazat témata" - dismiss_posts: "Odbýt příspěvky" - dismiss_posts_tooltip: "Smazat počet nepřečtených příspěvků v tématu ale na seznamu je dál zobrazovat jako nepřečtené" dismiss_topics: "Odbýt témata" - dismiss_topics_tooltip: "Nezobrazovat tato témata jako nepřečtená při novém příspěvku" dismiss_new: "Odbýt nová" toggle: "hromadný výběr témat" actions: "Hromadné akce" @@ -963,7 +955,6 @@ cs: description: "Nikdy nedostanete oznámení týkající se čehokoliv v této zprávě." muted: title: "Ztišené" - description: "nebudete dostávat žádná oznámení k tomuto tématu a ani se nebude zobrazovat v seznamu nepřečtených témat." actions: recover: "Vrátit téma" delete: "Odstranit téma" @@ -1423,7 +1414,6 @@ cs: help: "Pro vás toto téma není připnuté; bude se zobrazovat v běžném pořadí" pinned_globally: title: "Připnuté globálně" - help: "Toto téma je připnuto globálně, zobrazí se na vršku všech seznamů" pinned: title: "Připnuto" help: "Pro vás je toto téma připnuté; bude se zobrazovat na vrcholu seznamu ve své kategorii" diff --git a/config/locales/client.da.yml b/config/locales/client.da.yml index ae7e90996a..c5525e3a4b 100644 --- a/config/locales/client.da.yml +++ b/config/locales/client.da.yml @@ -189,7 +189,7 @@ da: user_count: "Nye brugere" active_user_count: "Aktive brugere" contact: "Kontakt os" - contact_info: "I tilfælde af kritiske situationer eller vigtige spørgsmål angående denne side, kontakt os venligst på %{contact_emal}." + contact_info: "I tilfælde af kritiske situationer eller vigtige spørgsmål angående denne side, kontakt os venligst på %{contact_info}." bookmarked: title: "Bogmærke" clear_bookmarks: "Ryd Bogmærker" @@ -278,8 +278,8 @@ da: title: "Brugere" likes_given: "Givet" likes_received: "Modtaget" - topics_entered: "Indtastet" - topics_entered_long: "Emner indtastet" + topics_entered: "Besøgte" + topics_entered_long: "Emner besøgt" time_read: "Læsetid" topic_count: "Emner" topic_count_long: "Emner oprettet" @@ -363,7 +363,7 @@ da: username: "brugernavn" trust_level: "TL" read_time: "læse tid" - topics_entered: "emner indtastet" + topics_entered: "emner besøgt" post_count: "# indlæg" confirm_delete_other_accounts: "Er du sikker på, at du vil slette disse kontoer?" user_fields: @@ -406,7 +406,7 @@ da: change: "skift" moderator: "{{user}} er moderator" admin: "{{user}} er admin" - moderator_tooltip: "Dette bruger er moderator" + moderator_tooltip: "Denne bruger er moderator" admin_tooltip: "Denne bruger er administrator" blocked_tooltip: "Brugeren er blokeret" suspended_notice: "Denne bruger er suspenderet indtil {{date}}." @@ -418,7 +418,7 @@ da: tracked_categories: "Fulgt" tracked_categories_instructions: "Du vil automatisk følge alle nye emner i disse kategorier. En optælling af nye indlæg vises ved emnet." muted_categories: "Ignoreret" - muted_categories_instructions: "Du ignorerer automatisk alle emner i disse kategorier" + muted_categories_instructions: "Du får ikke beskeder om nye emner i disse kategorier og de fremstår ikke i seneste." delete_account: "Slet min konto" delete_account_confirm: "Er du sikker på du vil slette din konto permanent? Dette kan ikke fortrydes!" deleted_yourself: "Din konto er nu slettet." @@ -557,6 +557,9 @@ da: user: "Inviteret bruger" sent: "Sendt" none: "Der er ingen afventende invitationer." + truncated: + one: "Viser den første invitation." + other: "Viser de første {{count}} invitationer." redeemed: "Brugte invitationer" redeemed_tab: "Indløst" redeemed_tab_with_count: "Indløst ({{count}})" @@ -726,6 +729,9 @@ da: admin_not_allowed_from_ip_address: "Du kan ikke logge på som administrator fra denne IP adresse." resend_activation_email: "Klik her for at sende aktiverings-e-mail’en igen." sent_activation_email_again: "Vi har sendt endnu en aktiverings-e-mail til dig på {{currentEmail}}. Det kan tage nogen få minutter før den når frem; kontrollér også din spam-mappe." + to_continue: "Log venligst ind" + preferences: "Du skal være logget ind for at ændre præferencer." + forgot: "Jeg kan ikke huske min kontos detaljer" google: title: "med Google" message: "Logger ind med Google (kontrollér at pop-op-blokering ikke er aktiv)" @@ -750,6 +756,7 @@ da: emoji_one: "Emoji One" composer: emoji: "Emoji :smile:" + more_emoji: "mere..." options: "Indstillinger" whisper: "hvisken" add_warning: "Dette er en officiel advarsel." @@ -782,7 +789,7 @@ da: show_edit_reason: "(tilføj en begrundelse for ændringen)" reply_placeholder: "Skriv her. Brug Markdown, BBCode eller HTML til at formattere. Træk eller indsæt billeder." view_new_post: "Se dit nye indlæg." - saving: "Gemmer…" + saving: "Gemmer." saved: "Gemt!" saved_draft: "Kladde i gang. Vælg for at fortsætte med den." uploading: "Uploader…" @@ -797,6 +804,7 @@ da: link_description: "skriv linkets beskrivelse her" link_dialog_title: "Indsæt link" link_optional_text: "evt. titel" + link_placeholder: "http://example.com \"valgfri tekst\"" quote_title: "Citatblok" quote_text: "Citatblok" code_title: "Præformateret tekst" @@ -809,10 +817,10 @@ da: heading_title: "Overskrift" heading_text: "Overskrift" hr_title: "Vandret streg" - undo_title: "Fortryd" - redo_title: "Gentag" help: "Hjælp til Markdown-redigering" toggler: "skjul eller vis editor-panelet" + modal_ok: "OK" + modal_cancel: "Annuller" admin_options_title: "Valgfrie staff-indstillinger for dette emne" auto_close: label: "Tidspunkt for automatisk lukning af emne:" @@ -868,9 +876,9 @@ da: from_my_computer: "Fra min computer" from_the_web: "Fra nettet" remote_tip: "link til billede" - remote_tip_with_attachments: "link til billede eller fil ({{authorized_extensions}})" + remote_tip_with_attachments: "link til billede eller fil {{authorized_extensions}}" local_tip: "vælg billeder fra din enhed" - local_tip_with_attachments: "vælg billeder eller filer fra din enhed ({{authorized_extensions}})" + local_tip_with_attachments: "vælg billeder eller filer fra din enhed {{authorized_extensions}}" hint: "(du kan også trække og slippe ind i editoren for at uploade dem)" hint_for_supported_browsers: "du kan også bruge træk-og-slip eller indsætte billeder i editoren" uploading: "Uploader billede" @@ -905,12 +913,15 @@ da: current_user: 'gå til brugerside' topics: bulk: + unlist_topics: "Fjern emner fra liste" reset_read: "Nulstil \"læst\"" delete: "Slet emner" - dismiss_posts: "Afvis indlæg" - dismiss_posts_tooltip: "Nulstil \"ulæste\" på disse emner, men fortsæt med at vise dem på min \"ulæste\" liste når der kommer nye indlæg" - dismiss_topics: "Afvist Emner" - dismiss_topics_tooltip: "Stop med at vide disse emner i min \"ulæste\" liste når der kommer nye indlæg" + dismiss: "Afvis" + dismiss_button: "Afvis..." + dismiss_tooltip: "Afvis kun nye indlæg eller stop med at følge emner" + dismiss_body: "Vil du kun afvise nye indlæg i emnerne eller afvise emnerne helt?" + dismiss_posts: "Afvis kun nye indlæg" + dismiss_topics: "Afvis emner" dismiss_new: "Afvis nye" toggle: "vælg flere emner af gangen" actions: "Handlinger på flere indlæg" @@ -1054,7 +1065,7 @@ da: description: "Du vil aldrig få notifikationer om denne besked." muted: title: "Stille!" - description: "du får ikke besked om nogen hændelser i dette emne, og det vil ikke fremgå af din liste over ulæste emner." + description: "Du vil aldrig få beskeder om noget i indlæggene og de vil ikke vises i seneste." actions: recover: "Gendan emne" delete: "Slet emne" @@ -1271,6 +1282,7 @@ da: revert_to_regular: "Fjern Personale farve" rebake: "Gendan HTML" unhide: "Vis" + change_owner: "Skift ejerskab" actions: flag: 'Flag' defer_flags: @@ -1455,7 +1467,7 @@ da: description: "Du vil modtage en notifikation, hvis nogen nævner dit @name eller svarer dig." muted: title: "Ignoreret" - description: "Du vil aldrig blive underrettet om noget som helst angående nye emner i disse categorier, og de vil ikke blive vist under \"ulæste\"." + description: "Du vil aldrig få besked om noget om nye emner i kategorierne og de vises heller ikke i seneste." flagging: title: 'Tak fordi du hjælper med at holde vores forum civiliseret!' private_reminder: 'flag er private, de er kun

    synlige for personalet' @@ -1508,7 +1520,7 @@ da: help: "Dette emne er ikke fastgjort for dig; det vil blive vist i den normale rækkefølge" pinned_globally: title: "Fastgjort globalt" - help: "Dette emne er fastgjort globalt; det vil blive vist øverst på alle lister" + help: "Dette emne er globalt fastgjort; det vises i toppen af seneste og i dets kategori" pinned: title: "Fastgjort" help: "Dette emne er fastgjort for dig; det vil blive vist i toppen af dets kategori" @@ -1762,6 +1774,10 @@ da: add: "Tilføj" add_members: "Tilføj medlemmer" custom: "Brugerdefineret" + bulk_complete: "Brugerne er tilføjet gruppen." + bulk: "Tilføj mange brugere til gruppe" + bulk_paste: "Indsæt en liste brugerne eller emails, én per linje:" + bulk_select: "(vælg en gruppe)" automatic: "Automatisk" automatic_membership_email_domains: "Brugere der registrerer med et email domæne der præcist matcher et på denne liste, vil automatisk blive tilføjet til denne gruppe:" automatic_membership_retroactive: "Brug denne email domæne regel til at tilføje brugere der allerede er registrerede brugere" @@ -2386,7 +2402,7 @@ da: category: "Opret i kategorien" add_host: "Tilføj server" settings: "Indlejrings-indstillinger" - feed_settings: "Feed-instillinger" + feed_settings: "Feed-indstillinger" feed_description: "Hvis du angiver et RSS/ATOM-feed for dit site, kan det forbedre Discourses mulighed for at importere dit indhold." crawling_settings: "Robot-indstillinger" crawling_description: "Når Discourse opretter emner for dine indlæg, og der ikke er noget RSS/ATOM-feed, vil den forsøge at parse dit indhold ud fra din HTML. Det kan nogengange være en udfordring at udtrække dit indhold, så vi giver mulighed for at specificere CSS-regler for at gøre udtræk lettere." @@ -2395,9 +2411,7 @@ da: embed_username_key_from_feed: "Nøgle til at udtrække discourse-brugernavn fra feed" embed_truncate: "Beskær de indlejrede indlæg" embed_whitelist_selector: "CSS-selektorer for elementer der er tilladte i indlejringer" - whitelist_example: "article, #story, .post" embed_blacklist_selector: "CSS-selektorer for elementer der fjernes fra indlejringer" - blacklist_example: ".ad-unit, header" feed_polling_enabled: "Importer indlæg via RSS/ATOM" feed_polling_url: "URL på RSS/ATOM feed der skal kravles" save: "Gem indlejrings-indstillinger" diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml index 87294580d9..bd056db4f0 100644 --- a/config/locales/client.de.yml +++ b/config/locales/client.de.yml @@ -416,7 +416,6 @@ de: tracked_categories: "Verfolgt" tracked_categories_instructions: "Du wirst automatisch allen neuen Themen in diesen Kategorien folgen. Die Anzahl der neuen Antworten wird bei den betroffenen Themen angezeigt." muted_categories: "Stummgeschaltet" - muted_categories_instructions: "Du erhältst keine Benachrichtigungen über neue Themen in diesen Kategorien und sie werden nicht in deiner Liste ungelesener Themen aufscheinen." delete_account: "Lösche mein Benutzerkonto" delete_account_confirm: "Möchtest du wirklich dein Benutzerkonto permanent löschen? Diese Aktion kann nicht rückgängig gemacht werden!" deleted_yourself: "Dein Benutzerkonto wurde erfolgreich gelöscht." @@ -724,6 +723,7 @@ de: admin_not_allowed_from_ip_address: "Von dieser IP-Adresse darfst du dich nicht als Administrator anmelden." resend_activation_email: "Klicke hier, um eine neue Aktivierungsmail zu schicken." sent_activation_email_again: "Wir haben dir eine weitere E-Mail zur Aktivierung an {{currentEmail}} geschickt. Es könnte ein paar Minuten dauern, bis diese ankommt; sieh auch im Spam-Ordner nach." + preferences: "Du musst eingeloggt sein, um deine Benutzereinstellungen bearbeiten zu können." google: title: "mit Google" message: "Authentifiziere mit Google (stelle sicher, dass keine Pop-up-Blocker aktiviert sind)" @@ -781,7 +781,6 @@ de: show_edit_reason: "(Bearbeitungsgrund hinzufügen)" reply_placeholder: "Schreib hier. Verwende Markdown, BBCode oder HTML zur Formatierung. Füge Bilder ein oder ziehe sie herein." view_new_post: "Sieh deinen neuen Beitrag an." - saving: "Speichere..." saved: "Gespeichert!" saved_draft: "Ein Beitrag ist in Arbeit. Zum Fortsetzen hier klicken." uploading: "Wird hochgeladen..." @@ -796,6 +795,7 @@ de: link_description: "gib hier eine Link-Beschreibung ein" link_dialog_title: "Hyperlink einfügen" link_optional_text: "Optionaler Titel" + link_placeholder: "http://example.com \"Optionaler Text\"" quote_title: "Zitat" quote_text: "Zitat" code_title: "Vorformatierter Text" @@ -808,8 +808,6 @@ de: heading_title: "Überschrift" heading_text: "Überschrift" hr_title: "Horizontale Linie" - undo_title: "Rückgängig machen" - redo_title: "Wiederholen" help: "Hilfe zur Markdown-Formatierung" toggler: "Eingabebereich aus- oder einblenden" admin_options_title: "Optionale Mitarbeiter-Einstellungen für dieses Thema" @@ -867,9 +865,7 @@ de: from_my_computer: "Von meinem Gerät" from_the_web: "Aus dem Web" remote_tip: "Link zu Bild" - remote_tip_with_attachments: "Link zu Bild oder Datei ({{authorized_extensions}})" local_tip: "wähle auf deinem Gerät gespeicherte Bilder aus" - local_tip_with_attachments: "wähle auf deinem Gerät gespeicherte Bilder oder Dateien aus ({{authorized_extensions}})" hint: "(du kannst Dateien auch in den Editor ziehen, um diese hochzuladen)" hint_for_supported_browsers: "du kannst Bilder auch in den Editor ziehen oder diese aus der Zwischenablage einfügen" uploading: "Wird hochgeladen" @@ -906,10 +902,12 @@ de: bulk: reset_read: "Gelesene zurücksetzen" delete: "Themen löschen" - dismiss_posts: "Beiträge ignorieren" - dismiss_posts_tooltip: "Neue Beiträge in diesen Themen ignorieren. Die Themen aber später wieder als ungelesen anzeigen, sobald neue Beiträge verfasst werden." + dismiss: "Ignorieren" + dismiss_button: "Ignorieren..." + dismiss_tooltip: "Nur die neuen Beiträge ignorieren oder Themen nicht mehr verfolgen" + dismiss_body: "Willst du nur die neuen Beiträge ignorieren oder sollen die Themen vollständig ignoriert werden?" + dismiss_posts: "Nur neue Beiträge ignorieren" dismiss_topics: "Themen ignorieren" - dismiss_topics_tooltip: "Diese Themen ignorieren und nicht mehr als ungelesen anzeigen, selbst wenn neue Beiträge verfasst werden." dismiss_new: "Neue Themen ignorieren" toggle: "zu Massenoperationen auf Themen umschalten" actions: "Massenoperationen" @@ -1055,7 +1053,6 @@ de: description: "Du erhältst keine Benachrichtigungen im Zusammenhang mit dieser Unterhaltung." muted: title: "Stummgeschaltet" - description: "Du erhältst keine Benachrichtigungen über dieses Thema und es wird nicht in deiner Liste ungelesener Themen aufscheinen." actions: recover: "Löschen rückgängig machen" delete: "Thema löschen" @@ -1426,6 +1423,7 @@ de: change_in_category_topic: "Beschreibung bearbeiten" already_used: 'Diese Farbe wird bereits für eine andere Kategorie verwendet' security: "Sicherheit" + special_warning: "Warnung: Diese Kategorie is eine pre-seeded Kategorie und die Sicherheitseinstellungen können nicht bearbeitet werden. Wenn du wünschst nicht diese Kategorie zu benutzen dann lösche sie anstatt sie zu wiederverwenden" images: "Bilder" auto_close_label: "Themen automatisch schließen nach:" auto_close_units: "Stunden" @@ -1455,7 +1453,6 @@ de: description: "Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder dir antwortet." muted: title: "Stummgeschaltet" - description: "Du erhältst keine Benachrichtigungen über neue Themen in diesen Kategorien und sie werden nicht in deinem \"ungelesen\"-Tab erscheinen." flagging: title: 'Danke für deine Mithilfe!' private_reminder: 'Meldungen sind vertraulich und nur für Mitarbeiter sichtbar' @@ -1508,7 +1505,6 @@ de: help: "Dieses Thema ist für dich losgelöst; es wird in der normalen Reihenfolge angezeigt" pinned_globally: title: "Global angeheftet" - help: "Dieses Thema ist global angeheftet; es wird immer am Anfang aller Listen auftauchen" pinned: title: "Angeheftet" help: "Dieses Thema ist für dich angeheftet; es wird immer am Anfang seiner Kategorie auftauchen" @@ -2372,7 +2368,9 @@ de: image: "Bild" delete_confirm: "Möchtest du wirklich das :%{name}: Emoji löschen?" embedding: + get_started: "Wenn du Discourse in einer anderen Website einbetten möchtest, beginne mit dem hinzufügen des host. " confirm_delete: "Möchtest du wirklich diesen Host löschen?" + sample: "Benutze den folgenden HTML code für deine Seite um discourse Beiträge zu erstellen und einzubetten. Ersetze ERSETZE_MICH mit der URL der Seite in die du sie einbetten möchtest." title: "Einbettung" host: "Erlaubte Hosts" edit: "bearbeiten" @@ -2386,9 +2384,7 @@ de: embed_username_key_from_feed: "Schlüssel, um Discourse-Benutzernamen aus Feed zu extrahieren." embed_truncate: "Kürze die eingebetteten Beiträge" embed_whitelist_selector: "CSS Selektor für Elemente, die in Einbettungen erlaubt sind." - whitelist_example: "article, #story, .post" embed_blacklist_selector: "CSS Selektor für Elemente, die in Einbettungen entfernt werden." - blacklist_example: ".ad-unit, header" feed_polling_enabled: "Beiträge über RSS/ATOM importieren" feed_polling_url: "URL des RSS/ATOM Feeds für den Import" save: "Einbettungseinstellungen speichern" @@ -2572,7 +2568,7 @@ de: description: Hat in einem Thema mit mehr als 100 Beiträgen jeden Beitrag gelesen popular_link: name: Beliebter Link - description: Hat einen externen Link veröffentlicht, der mindestens 50 Klicks erhalten hat. + description: Hat einen externen Link veröffentlicht, welcher mindestens 50 Klicks erhalten hat. hot_link: name: Angesagter Link description: Hat einen externen Link veröffentlicht, welcher mindestens 300 Klicks erhalten hat. diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 82363c09eb..cb03551804 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -153,7 +153,6 @@ en: sign_up: "Sign Up" log_in: "Log In" age: "Age" - last_post: "Last Post" joined: "Joined" admin_title: "Admin" flags_title: "Flags" @@ -470,6 +469,7 @@ en: users: "Users" muted_users: "Muted" muted_users_instructions: "Suppress all notifications from these users." + muted_topics_link: "Show muted topics" staff_counters: flags_given: "helpful flags" @@ -735,14 +735,6 @@ en: hidden_for_session: "OK, I'll ask you tomorrow. You can always use 'Log In' to create an account, too." intro: "Hey there! :heart_eyes: Looks like you're enjoying the discussion, but you're not signed up for an account." value_prop: "When you create an account, we remember exactly what you've read, so you always come right back where you left off. You also get notifications, here and via email, whenever new posts are made. And you can like posts to share the love. :heartbeat:" - methods: - sso: "Signing up is easy: all you need is an account on the main site." - only_email: "Signing up is easy: all you need is an email and password." - only_other: "Use your %{provider} account to sign up." - one_and_email: "Use your %{provider} account, or an email and password, to sign up." - multiple_no_email: "Signing up is easy: use any of our %{count} social logins." - multiple: "Signing up is easy: use any of our %{count} social logins, or an email and password." - unknown: "error getting supported login methods" summary: enabled_description: "You're viewing a summary of this topic: the most interesting posts as determined by the community." @@ -967,9 +959,9 @@ en: from_my_computer: "From my device" from_the_web: "From the web" remote_tip: "link to image" - remote_tip_with_attachments: "link to image or file ({{authorized_extensions}})" + remote_tip_with_attachments: "link to image or file {{authorized_extensions}}" local_tip: "select images from your device" - local_tip_with_attachments: "select images or files from your device ({{authorized_extensions}})" + local_tip_with_attachments: "select images or files from your device {{authorized_extensions}}" hint: "(you can also drag & drop into the editor to upload them)" hint_for_supported_browsers: "you can also drag and drop or paste images into the editor" uploading: "Uploading" @@ -1008,12 +1000,14 @@ en: topics: bulk: + unlist_topics: "Unlist Topics" reset_read: "Reset Read" delete: "Delete Topics" - dismiss_posts: "Dismiss Posts" - dismiss_posts_tooltip: "Clear unread counts on these topics but continue to show them on my unread list when new posts are made" - dismiss_topics: "Dismiss Topics" - dismiss_topics_tooltip: "Stop showing these topics in my unread list when new posts are made" + dismiss: "Dismiss" + dismiss_read: "Dismiss all unread" + dismiss_button: "Dismiss…" + dismiss_tooltip: "Dismiss just new posts or stop tracking topics" + also_dismiss_topics: "Stop tracking these topics? (Topics will no longer appear in the unread tab)" dismiss_new: "Dismiss New" toggle: "toggle bulk selection of topics" actions: "Bulk Actions" @@ -1947,6 +1941,10 @@ en: add: "Add" add_members: "Add members" custom: "Custom" + bulk_complete: "The users have been added to the group." + bulk: "Bulk Add to Group" + bulk_paste: "Paste a list of usernames or emails, one per line:" + bulk_select: "(select a group)" automatic: "Automatic" automatic_membership_email_domains: "Users who register with an email domain that exactly matches one in this list will be automatically added to this group:" automatic_membership_retroactive: "Apply the same email domain rule to add existing registered users" @@ -2600,9 +2598,7 @@ en: embed_username_key_from_feed: "Key to pull discourse username from feed" embed_truncate: "Truncate the embedded posts" embed_whitelist_selector: "CSS selector for elements that are allowed in embeds" - whitelist_example: "article, #story, .post" embed_blacklist_selector: "CSS selector for elements that are removed from embeds" - blacklist_example: ".ad-unit, header" feed_polling_enabled: "Import posts via RSS/ATOM" feed_polling_url: "URL of RSS/ATOM feed to crawl" save: "Save Embedding Settings" diff --git a/config/locales/client.es.yml b/config/locales/client.es.yml index bb349741bb..635ae4b0cb 100644 --- a/config/locales/client.es.yml +++ b/config/locales/client.es.yml @@ -127,7 +127,7 @@ es: disabled: 'sin destacar %{when}' visible: enabled: 'listado %{when}' - disabled: 'sin listar %{when}' + disabled: 'quitado de la lista, invisible %{when}' topic_admin_menu: "acciones de administrador para el tema" emails_are_disabled: "Todos los emails salientes han sido desactivados por un administrador. No se enviará ninguna notificación por email." edit: 'editar el título y la categoría de este tema' @@ -418,7 +418,7 @@ es: tracked_categories: "Siguiendo" tracked_categories_instructions: "Seguirás automáticamente todos los nuevos temas en estas categorías. Se añadirá un contador de posts nuevos y sin leer al lado del tema." muted_categories: "Silenciado" - muted_categories_instructions: "No será notificado de nuevos temas en estas categorías, y no aparecerán en la sección de \"no leídos\"." + muted_categories_instructions: "No serás notificado de ningún tema en estas categorías, y no aparecerán en la página de mensajes recientes." delete_account: "Borrar Mi Cuenta" delete_account_confirm: "¿Estás seguro que quieres borrar permanentemente tu cuenta? ¡Esta acción no puede ser revertida!" deleted_yourself: "Tu cuenta ha sido borrada exitosamente." @@ -557,6 +557,9 @@ es: user: "Invitar Usuario" sent: "Enviadas" none: "No hay ninguna invitación pendiente que mostrar." + truncated: + one: "Mostrando la primera invitación." + other: "Mostrando las primeras {{count}} invitaciones." redeemed: "Invitaciones aceptadas" redeemed_tab: "Usado" redeemed_tab_with_count: "Aceptadas ({{count}})" @@ -726,6 +729,9 @@ es: admin_not_allowed_from_ip_address: "No puedes iniciar sesión como admin desde esta dirección IP." resend_activation_email: "Has clic aquí para enviar el email de activación nuevamente." sent_activation_email_again: "Te hemos enviado otro e-mail de activación a {{currentemail}}. Podría tardar algunos minutos en llegar; asegúrate de revisar tu carpeta de spam." + to_continue: "Por favor, inicia sesión" + preferences: "Debes tener una sesión iniciada para cambiar tus preferencias de usuario." + forgot: "No me acuerdo de los detalles de mi cuenta." google: title: "con Google" message: "Autenticando con Google (asegúrate de desactivar cualquier bloqueador de pop ups)" @@ -750,6 +756,7 @@ es: emoji_one: "Emoji One" composer: emoji: "Emoji :smile:" + more_emoji: "más..." options: "Opciones" whisper: "susurrar" add_warning: "Ésta es una advertencia oficial." @@ -782,7 +789,7 @@ es: show_edit_reason: "(añadir motivo de edición)" reply_placeholder: "Escribe aquí. Usa Markdown, BBCode o HTML para darle formato. Arrastra o pega imágenes." view_new_post: "Ver tu nuevo post." - saving: "Guardando..." + saving: "Guardando" saved: "¡Guardado!" saved_draft: "Borrador en progreso. Selecciona para continuar." uploading: "Subiendo..." @@ -797,6 +804,7 @@ es: link_description: "introduzca descripción del enlace aquí" link_dialog_title: "Insertar Enlace" link_optional_text: "título opcional" + link_placeholder: "http://ejemplo.com \"texto opcional\"" quote_title: "Cita" quote_text: "Cita" code_title: "Texto preformateado" @@ -809,10 +817,10 @@ es: heading_title: "Encabezado" heading_text: "Encabezado" hr_title: "Linea Horizontal" - undo_title: "Deshacer" - redo_title: "Rehacer" help: "Ayuda de Edición con Markdown" toggler: "ocultar o mostrar el panel de edición" + modal_ok: "OK" + modal_cancel: "Cancelar" admin_options_title: "Opciones de moderación para este tema" auto_close: label: "Tiempo para cierre automático del tema" @@ -868,9 +876,9 @@ es: from_my_computer: "Desde mi dispositivo" from_the_web: "Desde la web" remote_tip: "enlace a la imagen" - remote_tip_with_attachments: "enlace a la imagen o al archivo ({{authorized_extensions}})" + remote_tip_with_attachments: "enlace a imagen o archivo {{authorized_extensions}}" local_tip: "selecciona las imágenes desde tu dispositivo" - local_tip_with_attachments: "selecciona imágenes o archivos desde tu dispositivo ({{authorized_extensions}})" + local_tip_with_attachments: "selecciona imágenes o archivos desde tu dispositivo {{authorized_extensions}}" hint: "(también puedes arrastrarlos al editor para subirlos)" hint_for_supported_browsers: "puedes también arrastrar o pegar imágenes en el editor" uploading: "Subiendo" @@ -905,12 +913,15 @@ es: current_user: 'ir a tu página de usuario' topics: bulk: + unlist_topics: "Hacer invisibles" reset_read: "Restablecer leídos" delete: "Eliminar temas" - dismiss_posts: "Ignorar publicaciones" - dismiss_posts_tooltip: "Limpiar contadores de 'no leídos' en estos temas pero continuar mostrándolos en mi lista de 'no leídos' cuando se hacen nuevas publicaciones" + dismiss: "Descartar" + dismiss_button: "Descartar..." + dismiss_tooltip: "Descartar solo los nuevos posts o dejar de seguir los temas" + dismiss_body: "¿Quieres descartar solo los nuevos posts en estos temas o los temas por completo?" + dismiss_posts: "Descartar nuevos posts" dismiss_topics: "Descartar Temas" - dismiss_topics_tooltip: "Dejar de mostrar estos temas en mi lista de 'no leídos' cuando se hacen nuevas publicaciones" dismiss_new: "Ignorar nuevos" toggle: "activar selección de temas en bloque" actions: "Acciones en bloque" @@ -1054,7 +1065,7 @@ es: description: "Nunca se te notificará nada sobre este hilo de mensajes." muted: title: "Silenciar" - description: "Nunca recibirás notificaciones sobre este tema y no aparecerá en tu pestaña de no leídos." + description: "No serás notificado de algo relacionado con este tema, y no aparecerá en la página de mensajes recientes." actions: recover: "Deshacer borrar tema" delete: "Eliminar tema" @@ -1271,6 +1282,7 @@ es: revert_to_regular: "Eliminar el formato de post de staff" rebake: "Reconstruir HTML" unhide: "Deshacer ocultar" + change_owner: "Cambiar dueño" actions: flag: 'Reportar' defer_flags: @@ -1455,7 +1467,7 @@ es: description: "Se te notificará solo si alguien menciona tu @nombre o te responde a un post." muted: title: "Silenciadas" - description: "Nunca serás notificado sobre nuevos temas en estas categorías, y no aparecerán en tu pestaña de no leído." + description: "No serás notificado de ningún tema en estas categorías, y no aparecerán en la página de mensajes recientes." flagging: title: '¡Gracias por ayudar a mantener una comunidad civilizada!' private_reminder: 'los reportes son privados, son visibles únicamente por los administradores' @@ -1508,7 +1520,7 @@ es: help: "Este tema se ha dejado de destacar para ti; en tu listado de temas se mostrará en orden normal" pinned_globally: title: "Destacado globalmente" - help: "Este tema ha sido destacado globalmente, se mostrará en la parte superior de todas las listas" + help: "Este tema ha sido destacado globalmente, se mostrará en la parte superior de la página de mensajes recientes y de su categoría." pinned: title: "Destacado" help: "Este tema ha sido destacado para ti; se mostrará en la parte superior de su categoría" @@ -1762,6 +1774,10 @@ es: add: "Añadir" add_members: "Añadir miembros" custom: "Personalizado" + bulk_complete: "Los usuarios han sido añadidos al grupo." + bulk: "Añadir al grupo en masa" + bulk_paste: "Pega una lista de nombres de usuario o emails, uno por línea:" + bulk_select: "(selecciona un grupo)" automatic: "Automático" automatic_membership_email_domains: "Los usuarios que se registren con un dominio de e-mail que esté en esta lista serán automáticamente añadidos a este grupo:" automatic_membership_retroactive: "Aplicar la misma regla de dominio de email para usuarios registrados existentes " @@ -2395,9 +2411,7 @@ es: embed_username_key_from_feed: "Clave para extraer usuario de discourse del feed" embed_truncate: "Truncar los posts insertados" embed_whitelist_selector: "Selector CSS para permitir elementos a embeber" - whitelist_example: "article, #story, .post" embed_blacklist_selector: "Selector CSS para restringir elementos a embeber" - blacklist_example: ".ad-unit, header" feed_polling_enabled: "Importar posts usando RSS/ATOM" feed_polling_url: "URL del feed RSS/ATOM del que extraer datos" save: "Guardar ajustes de Insertado" diff --git a/config/locales/client.fa_IR.yml b/config/locales/client.fa_IR.yml index 06d2bd7984..d01d585ea7 100644 --- a/config/locales/client.fa_IR.yml +++ b/config/locales/client.fa_IR.yml @@ -339,7 +339,6 @@ fa_IR: tracked_categories: "پی‌گیری شده" tracked_categories_instructions: "شما به صورت خودکار تمام عناوین جدید در این دسته را پیگیری خواهید کرد. تعداد نوشته های جدید در کنار عنواین نمایش داده می‌شود." muted_categories: "بی صدا شد" - muted_categories_instructions: "از هر آن‌چه درباره موضوعات تازه در این دسته‌ بندی ها روی دهد، شما آگاه نخواهید شد و در تب نخواندهٔ‌ شما نمایش داده نمی‌شوند." delete_account: "حساب من را پاک کن" delete_account_confirm: "آیا مطمئنید که می‌خواهید شناسه‌تان را برای همیشه پاک کنید؟ برگشتی در کار نیست!" deleted_yourself: "حساب‌ کاربری شما با موفقیت حذف شد." @@ -660,7 +659,6 @@ fa_IR: edit_reason_placeholder: "چرا ویرایش می‌کنید؟" show_edit_reason: "(افزودن دلیل ویرایش)" view_new_post: "نوشته تازه‌تان را ببینید." - saving: "در حال ذخیره سازی..." saved: "اندوخته شد!" saved_draft: "در حال حاضر پیشنویس وجود دارد . برای از سر گیری انتخاب نمایید." uploading: "بارگذاری..." @@ -687,8 +685,6 @@ fa_IR: heading_title: "عنوان" heading_text: "عنوان" hr_title: "خط کش افقی" - undo_title: "برگردانی" - redo_title: "دوباره‌گردانی" help: "راهنمای ویرایش با Markdown" toggler: "مخفی یا نشان دادن پنل نوشتن" admin_options_title: "تنظیمات اختیاری مدیران برای این موضوع" @@ -732,9 +728,7 @@ fa_IR: from_my_computer: "از دستگاه من" from_the_web: "از وب" remote_tip: "لینک به تصویر" - remote_tip_with_attachments: "لطفا لینک تصویر یا فایل ({{authorized_extensions}})" local_tip: "عکس ها را از روی سیستم خود انتخاب کنید" - local_tip_with_attachments: "عکس ها را از روی سیستم خود انتخاب کنید ({{authorized_extensions}})" hint: "(برای آپلود می توانید فایل را کیشده و در ویرایشگر رها کنید)" uploading: "در حال بروز رسانی " select_file: "انتخاب فایل" @@ -758,10 +752,7 @@ fa_IR: bulk: reset_read: "تنظیم مجدد خوانده شد" delete: "حذف موضوعات" - dismiss_posts: "بستن نوشته ها" - dismiss_posts_tooltip: "پاک کردن شمارش خوانده نشده های این موضوع اما همچنان در لیست خوانده نشده های من آنها را نمایش بده زمانی که پست جدید ساخته شد" dismiss_topics: "بستن موضوعات" - dismiss_topics_tooltip: "نشان دادن این تاپیک را از لیست خوانده نشده متوقف کن وقتی پست های جدید بوجود آمد" dismiss_new: "بستن جدید" toggle: "ضامن انتخاب یکباره موضوعات" actions: "عملیات یکجا" @@ -893,7 +884,6 @@ fa_IR: description: " در باره این پیام هرگز به شما اطلاع رسانی نخواهید شد" muted: title: "بی صدا شد" - description: "درباره این موضوع به شما هرگز اطلاع رسانی نخواهد شد٬ و در کنار جستار شمار خوانده نشده ها پدیدار نمی شود" actions: recover: "بازیابی موضوع" delete: "پاک کردن موضوع" @@ -1294,7 +1284,6 @@ fa_IR: help: "این موضوع برای شما شنجاق نشده است، آن طور منظم نمایش داده خواهد شد" pinned_globally: title: "به صورت سراسری سنجاق شد" - help: "این موضوع بصورت سراسری سنجاق شده است، آن بالای تمامی موضوعات نمایش داده خواهد شد" pinned: title: "سنجاق شد" help: "این موضوع برای شما سنجاق شده است، آن طور منظم در بالای دسته بندی نمایش داده خواهد شد." diff --git a/config/locales/client.fi.yml b/config/locales/client.fi.yml index 0b98358657..ba9f984554 100644 --- a/config/locales/client.fi.yml +++ b/config/locales/client.fi.yml @@ -418,7 +418,7 @@ fi: tracked_categories: "Seuratut" tracked_categories_instructions: "Näiden alueiden kaikki uudet ketjut asetetaan automaattisesti seurantaan. Uusien viestien lukumäärä näytetään ketjun otsikon vieressä." muted_categories: "Vaimennetut" - muted_categories_instructions: "Et saa imoituksia uusista viesteistä näillä alueilla, eivätkä ne näy Lukemattomat-välilehdellä." + muted_categories_instructions: "Et saa imoituksia uusista viesteistä näillä alueilla, eivätkä ne näy tuoreimmissa." delete_account: "Poista tilini" delete_account_confirm: "Oletko varma, että haluat lopullisesti poistaa käyttäjätilisi? Tätä toimintoa ei voi perua!" deleted_yourself: "Käyttäjätilisi on poistettu." @@ -557,6 +557,9 @@ fi: user: "Kutsuttu käyttäjä" sent: "Lähetetty" none: "Avoimia kutsuja ei ole." + truncated: + one: "Näytetään ensimmäinen kutsu." + other: "Näytetään ensimmäiset {{count}} kutsua." redeemed: "Hyväksytyt kutsut" redeemed_tab: "Hyväksytyt" redeemed_tab_with_count: "Hyväksytyt ({{count}})" @@ -726,6 +729,9 @@ fi: admin_not_allowed_from_ip_address: "Et voi kirjautua ylläpitäjänä tästä IP-osoitteesta." resend_activation_email: "Klikkaa tästä lähettääksesi vahvistusviestin uudelleen." sent_activation_email_again: "Lähetimme uuden vahvistusviestin sinulle osoitteeseen {{sentTo}}. Viestin saapumisessa voi kestää muutama minuutti, muista tarkastaa myös roskapostikansio." + to_continue: "Ole hyvä ja kirjaudu sisään" + preferences: "Sinun täytyy olla kirjautuneena sisään muokataksesi tilisi asetuksia" + forgot: "En muista käyttäjätilini tietoja" google: title: "Googlella" message: "Todennetaan Googlen kautta (varmista, että ponnahdusikkunoiden esto ei ole päällä)" @@ -750,6 +756,7 @@ fi: emoji_one: "Emoji One" composer: emoji: "Emoji :smile:" + more_emoji: "lisää..." options: "Asetukset" whisper: "kuiskaus" add_warning: "Tämä on virallinen varoitus." @@ -782,7 +789,7 @@ fi: show_edit_reason: "(lisää syy muokkaukselle)" reply_placeholder: "Kirjoita tähän. Käytä Markdownia, BBCodea tai HTML:ää muotoiluun. Raahaa tai liitä kuvia." view_new_post: "Katsele uutta viestiäsi." - saving: "Tallennetaan..." + saving: "Tallennetaan" saved: "Tallennettu!" saved_draft: "Viestiluonnos kesken. Klikkaa tähän jatkaaksesi." uploading: "Lähettää..." @@ -797,6 +804,7 @@ fi: link_description: "kirjoita linkin kuvaus tähän" link_dialog_title: "Lisää linkki" link_optional_text: "vaihtoehtoinen kuvaus" + link_placeholder: "http://esimerkki.fi \"valinnainen teksti\"" quote_title: "Lainaus" quote_text: "Lainaus" code_title: "Teksti ilman muotoiluja" @@ -809,10 +817,10 @@ fi: heading_title: "Otsikko" heading_text: "Otsikko" hr_title: "Vaakaviiva" - undo_title: "Peru" - redo_title: "Tee uudestaan" help: "Markdown apu" toggler: "näytä tai piilota kirjoitusalue" + modal_ok: "OK" + modal_cancel: "Peruuta" admin_options_title: "Tämän ketjun vain henkilökunnalle näytettävät asetukset" auto_close: label: "Sulje ketju automaattisesti tämän ajan jälkeen:" @@ -868,9 +876,9 @@ fi: from_my_computer: "Tästä laitteesta" from_the_web: "Netistä" remote_tip: "linkki kuvaan" - remote_tip_with_attachments: "linkki kuvaan tai tiedostoon ({{authorized_extensions}})" + remote_tip_with_attachments: "linkki kuvaan tai tiedostoon {{authorized_extensions}}" local_tip: "valitse kuvia laitteeltasi" - local_tip_with_attachments: "valitse kuvia tai tiedostoja laitteeltasi ({{authorized_extensions}})" + local_tip_with_attachments: "valitse kuvia tai tiedostoja laitteeltasi {{authorized_extensions}}" hint: "(voit myös raahata ne editoriin ladataksesi ne sivustolle)" hint_for_supported_browsers: "voit myös raahata tai liittää kuvia editoriin" uploading: "Lähettää" @@ -907,10 +915,12 @@ fi: bulk: reset_read: "Palauta lukutila" delete: "Poista ketjut" - dismiss_posts: "Unohda viestit" - dismiss_posts_tooltip: "Tyhjennä nyt ilmoitukset lukemattomista viesteistä näiden ketjujen osalta, mutta näytä ilmoitukset uudestaan, kun ketjuihin kirjoitetaan uusia viestejä." - dismiss_topics: "Unohda ketjut" - dismiss_topics_tooltip: "Lakkaa pysyvästi näyttämästä ilmoituksia uusista viesteistä näissä ketjuissa." + dismiss: "Unohda" + dismiss_button: "Unohda..." + dismiss_tooltip: "Unohda uudet viestit tai lopeta ketjujen seuraaminen" + dismiss_body: "Haluaisitko unohtaa vain uudet viestit, vai lopettaa ilmoitukset näistä ketjuista myös jatkossa?" + dismiss_posts: "Unohda vain nämä viestit" + dismiss_topics: "Lopeta ilmoitukset ketjuista" dismiss_new: "Unohda uudet" toggle: "Vaihda useamman ketjun valintaa" actions: "Massatoiminnot" @@ -1023,7 +1033,7 @@ fi: '3_1': 'Saat ilmoituksia, koska loit tämän ketjun.' '3': 'Saat ilmoituksia, koska olet asettanut ketjun tarkkailuun.' '2_8': 'Saat ilmoituksia, koska olet asettanut tämän alueen seurantaan.' - '2_4': 'Saat ilmoituksia, koska olet kirjoittanut ketjuun viestin.' + '2_4': 'Saat ilmoituksia, koska olet kirjoittanut ketjuun.' '2_2': 'Saat ilmoituksia, koska olet asettanut ketjun seurantaan.' '2': 'Saat ilmoituksia, koska luet tätä ketjua.' '1_2': 'Saat ilmoituksen jos joku mainitsee @nimesi tai vastaa sinulle.' @@ -1054,7 +1064,7 @@ fi: description: "Et saa mitään ilmoituksia tästä keskustelusta." muted: title: "Vaimenna" - description: "Et saa ilmoituksia mistään tässä ketjussa eikä se näy lukemattomat-välilehdessä." + description: "Et saa ilmoituksia mistään tässä ketjussa, eikä se näy tuoreimmissa." actions: recover: "Peru ketjun poisto" delete: "Poista ketju" @@ -1271,6 +1281,7 @@ fi: revert_to_regular: "Poista henkilökunnan taustaväri" rebake: "Tee HTML uudelleen" unhide: "Poista piilotus" + change_owner: "Vaihda omistajuutta" actions: flag: 'Liputa' defer_flags: @@ -1455,7 +1466,7 @@ fi: description: "Saat ilmoituksen jos joku mainitsee @nimesi tai vastaa sinulle." muted: title: "Vaimennettu" - description: "Et saa imoituksia uusista viesteistä näillä alueilla, eivätkä ne näy Lukemattomat-välilehdellä." + description: "Et saa ilmoituksia uusista ketjuista näillä alueilla, eivätkä ne näy tuoreimmissa." flagging: title: 'Kiitos avustasi yhteisön hyväksi!' private_reminder: 'liput ovat yksityisiä, ne näkyvät ainoastaan henkilökunnalle' @@ -1508,7 +1519,7 @@ fi: help: "Ketjun kiinnitys on poistettu sinulta; se näytetään tavallisessa järjestyksessä." pinned_globally: title: "Kiinnitetty koko palstalle" - help: "Tämä ketju on nyt kiinnitetty koko palstalle; se näytetään kaikkien listausten ylimpänä" + help: "Tämä ketju on kiinnitetty koko palstalle; se näytetään tuoreimpien ja oman alueensa ylimpänä" pinned: title: "Kiinnitetty" help: "Tämä ketju on kiinnitetty sinulle; se näytetään alueensa ensimmäisenä" @@ -2395,9 +2406,7 @@ fi: embed_username_key_from_feed: "Avain, jolla erotetaan Discourse-käyttäjänimi syötteestä" embed_truncate: "Typistä upotetut viestit" embed_whitelist_selector: "CSS valitsin elementeille, jotka sallitaan upotetuissa viesteissä" - whitelist_example: "article, #story, .post" embed_blacklist_selector: "CSS valitstin elementeille, jotka poistetaan upotetuista viesteistä" - blacklist_example: ".ad-unit, header" feed_polling_enabled: "Tuo kirjoitukset RSS/ATOM syötteen avulla" feed_polling_url: "RSS/ATOM syötteen URL" save: "Tallenna upotusasetukset" diff --git a/config/locales/client.fr.yml b/config/locales/client.fr.yml index 1cc54b4c3a..8378034a9a 100644 --- a/config/locales/client.fr.yml +++ b/config/locales/client.fr.yml @@ -418,7 +418,7 @@ fr: tracked_categories: "Suivies" tracked_categories_instructions: "Vous allez suivre automatiquement tous les nouveaux sujets dans ces catégories. Le nombre de nouveaux messages apparaîtra à côté du sujet." muted_categories: "Désactivés" - muted_categories_instructions: "Vous ne recevrez aucune notification concernant les nouveaux sujets de ces catégories, et ils n'apparaitront pas dans votre onglet non lu." + muted_categories_instructions: "Vous ne serez notifié de rien concernant les nouveaux sujets dans ces catégories, et elles n'apparaîtront pas dans les dernières catégories." delete_account: "Supprimer mon compte" delete_account_confirm: "Êtes-vous sûr de vouloir supprimer définitivement votre compte ? Cette action ne peut être annulée !" deleted_yourself: "Votre compte a été supprimé avec succès." @@ -557,6 +557,9 @@ fr: user: "Utilisateurs" sent: "Envoyé" none: "Il n'y a plus d'invitation en attente à afficher." + truncated: + one: "Afficher la première invitation." + other: "Afficher les {{count}} premières invitations." redeemed: "Invitations acceptées" redeemed_tab: "Utilisés" redeemed_tab_with_count: "Invitations acceptées ({{count}})" @@ -726,6 +729,9 @@ fr: admin_not_allowed_from_ip_address: "Vous ne pouvez pas vous connecter comme administrateur depuis cette adresse IP." resend_activation_email: "Cliquez ici pour envoyer à nouveau le courriel d'activation." sent_activation_email_again: "Nous venons d'envoyer un nouveau courriel d'activation à {{currentEmail}}. Il peut prendre quelques minutes à arriver; n'oubliez pas de vérifier votre répertoire spam." + to_continue: "Veuillez vous connecter" + preferences: "Vous devez être connecté pour modifier vos préférences utilisateur." + forgot: "J'ai oublié les détails de mon compte" google: title: "via Google" message: "Authentification via Google (assurez-vous que les popups ne soient pas bloquées)" @@ -750,9 +756,11 @@ fr: emoji_one: "Emoji One" composer: emoji: "Emoji :smile:" + more_emoji: "plus..." options: "Options" whisper: "murmure" add_warning: "Ceci est un avertissement officiel." + toggle_whisper: "Activer/Désactiver Whisper" posting_not_on_topic: "À quel sujet voulez-vous répondre ?" saving_draft_tip: "sauvegarde en cours..." saved_draft_tip: "sauvegardé" @@ -781,7 +789,7 @@ fr: show_edit_reason: "(ajouter la raison de l'édition)" reply_placeholder: "Écrivez ici. Utilisez Markdown, BBCode, ou HTML pour formatter. Glissez ou collez des images." view_new_post: "Voir votre nouveau message." - saving: "Sauvegarde…" + saving: "Sauvegarde" saved: "Sauvegardé !" saved_draft: "Vous avez un message brouillon en cours. Sélectionner cette barre pour reprendre son édition." uploading: "Envoi en cours…" @@ -796,6 +804,7 @@ fr: link_description: "saisir ici la description du lien" link_dialog_title: "Insérez le lien" link_optional_text: "titre optionnel" + link_placeholder: "http://exemple.fr \"texte facultatif\"" quote_title: "Citation" quote_text: "Citation" code_title: "Texte préformaté" @@ -808,10 +817,10 @@ fr: heading_title: "Titre" heading_text: "Titre" hr_title: "Barre horizontale" - undo_title: "Annuler" - redo_title: "Refaire" help: "Aide Markdown" toggler: "Afficher ou cacher le composer" + modal_ok: "OK" + modal_cancel: "Annuler" admin_options_title: "Paramètres optionnels pour ce sujet" auto_close: label: "Heure de fermeture automatique de ce sujet :" @@ -867,22 +876,20 @@ fr: from_my_computer: "Depuis mon appareil" from_the_web: "Depuis le web" remote_tip: "lien vers l'image" - remote_tip_with_attachments: "lien vers l'image ou le fichier ({{authorized_extensions}})" local_tip: "sélectionnez des images depuis votre appareil" - local_tip_with_attachments: "sélectionnez des images depuis votre appareil ({{authorized_extensions}})" hint: "(vous pouvez également faire un glisser-déposer dans l'éditeur pour les télécharger)" hint_for_supported_browsers: "vous pouvez aussi glisser/déposer ou coller des images dans l'éditeur" uploading: "Fichier en cours d'envoi" select_file: "Sélectionner Fichier" image_link: "lien vers lequel pointe l'image" search: - sort_by: "Tri par" + sort_by: "Trier par" relevance: "Pertinence" latest_post: "Dernier Message" most_viewed: "Plus Vu" most_liked: "Plus Aimé" - select_all: "Tout sélectionner" - clear_all: "Tout supprimer" + select_all: "Sélectionner tout" + clear_all: "Supprimer tout" result_count: one: "1 résultat pour \"{{term}}\"" other: "{{count}} résultats pour \"{{term}}\"" @@ -906,10 +913,10 @@ fr: bulk: reset_read: "Réinitialiser la lecture" delete: "Supprimer les sujets" - dismiss_posts: "Ignorer les messages" - dismiss_posts_tooltip: "Marquer comme lus ces sujets mais continuer de les afficher dans ma liste de sujets non-lus si de nouveaux messages apparaissent." + dismiss: "Ignorer" + dismiss_body: "Voulez-vous ignorer uniquement les nouveaux messages dans ces sujets, ou bien ignorer les sujets dans leur intégralité ?" + dismiss_posts: "Ignorer uniquement les nouveaux messages" dismiss_topics: "Ignorer les sujets" - dismiss_topics_tooltip: "Marquer tous les sujets comme lus et ne plus les afficher dans ma liste de sujet non-lus si de nouveaux messages apparaissent." dismiss_new: "Ignorer Nouveaux" toggle: "activer la sélection multiple des sujets" actions: "Actions sur sélection multiple" @@ -1057,7 +1064,7 @@ fr: description: "Vous ne serez jamais averti de quoi que ce soit à propos de ce message." muted: title: "Silencieux" - description: "Vous ne serez jamais informé de quoi que ce soit à propos de ce sujet, et il n'apparaîtra pas dans votre onglet non lu." + description: "Vous ne serez jamais notifié de rien concernant ce sujet, et il n'apparaîtra pas des les derniers sujets." actions: recover: "Annuler Suppression Sujet" delete: "Supprimer Sujet" @@ -1274,6 +1281,7 @@ fr: revert_to_regular: "Retirer la couleur modérateur" rebake: "Reconstruire l'HTML" unhide: "Ré-afficher" + change_owner: "Modifier la propriété" actions: flag: 'Signaler' defer_flags: @@ -1436,7 +1444,7 @@ fr: email_in_allow_strangers: "Accepter les courriels d'utilisateurs anonymes sans compte" email_in_disabled: "La possibilité de créer des nouveaux sujets via courriel est désactivé dans les Paramètres. Pour l'activer," email_in_disabled_click: 'activer le paramètre "email in".' - suppress_from_homepage: "Supprimer cette catégorie de la page d'accueil" + suppress_from_homepage: "Retirer cette catégorie de la page d'accueil" allow_badges_label: "Autoriser les badges à être accordé dans cette catégorie" edit_permissions: "Éditer les permissions" add_permission: "Ajouter une Permission" @@ -1458,7 +1466,7 @@ fr: description: "Vous serez notifié si quelqu'un mentionne votre @pseudo ou vous répond." muted: title: "Silencieux" - description: "Vous ne serez jamais notifié concernant les nouveaux sujets dans ces catégories, et ils n'apparaîtront pas dans votre onglet non-lus." + description: "Vous ne serez jamais notifié de rien concernant les nouveaux sujets dans ces catégories, et elles n'apparaîtront pas dans les dernières catégories." flagging: title: 'Merci de nous aider à garder notre communauté aimable !' private_reminder: 'les signalements sont privés, seulement visible aux modérateurs' @@ -1511,7 +1519,7 @@ fr: help: "Ce sujet est désépinglé pour vous; il sera affiché dans l'ordre par défaut" pinned_globally: title: "Épingler globalement" - help: "Ce sujet est épinglé globalement; il s'affichera en haut de toutes les listes de sujets" + help: "Ce sujet est épinglé globalement; il apparaîtra en premier dans la liste des derniers sujets et dans sa catégorie" pinned: title: "Épingler" help: "Ce sujet est épinglé pour vous; il s'affichera en haut de sa catégorie" @@ -2031,9 +2039,9 @@ fr: impersonate: "incarner" anonymize_user: "rendre l'utilisateur anonyme" roll_up: "consolider des blocs d'IP" - change_category_settings: "modifier les paramètres de la catégorie" - delete_category: "supprimer catégorie" - create_category: "créer catégorie" + change_category_settings: "Modifier les paramètres de la catégorie" + delete_category: "Supprimer la catégorie" + create_category: "Créer une catégorie" screened_emails: title: "Courriels affichés" description: "Lorsque quelqu'un essaye de créé un nouveau compte, les adresses de courriel suivantes seront vérifiées et l'inscription sera bloquée, ou une autre action sera réalisée." diff --git a/config/locales/client.he.yml b/config/locales/client.he.yml index dc7098909b..43586bc7a1 100644 --- a/config/locales/client.he.yml +++ b/config/locales/client.he.yml @@ -418,7 +418,6 @@ he: tracked_categories: "רגיל+" tracked_categories_instructions: "בקטגוריות אלה סך הפרסומים החדשים שלא נקראו יופיע לצד שם הפוסט." muted_categories: "מושתק" - muted_categories_instructions: "לא תקבלו התראות על נושאים חדשים בקטגוריות אלו, והם לא יופיעו בעמוד הלא נקראו שלך." delete_account: "מחק את החשבון שלי" delete_account_confirm: "אתה בטוח שברצונך למחוק את החשבון? לא ניתן לבטל פעולה זו!" deleted_yourself: "חשבונך נמחק בהצלחה." @@ -781,7 +780,6 @@ he: show_edit_reason: "(הוספת סיבת עריכה)" reply_placeholder: "הקלד כאן. השתמש ב Markdown, BBCode או HTML לערוך. גרור או הדבק תמונות." view_new_post: "הצגת את ההודעה החדשה שלך." - saving: "שומר..." saved: "נשמר!" saved_draft: "טיוטאת פרסום בתהליך, לחצו כדי להמשיך." uploading: "מעלה..." @@ -808,8 +806,6 @@ he: heading_title: "כותרת" heading_text: "כותרת" hr_title: "קו אופקי" - undo_title: "בטל" - redo_title: "חזור" help: "עזרה על כתיבה ב-Markdown" toggler: "הסתר או הצג את פאנל העריכה" admin_options_title: "אפשרויות צוות אופציונליות לפוסט זה" @@ -867,9 +863,7 @@ he: 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: "מעלה" @@ -906,10 +900,7 @@ he: bulk: reset_read: "איפוס נקראו" delete: "מחיקת פוסטים" - dismiss_posts: "ביטול פרסומים" - dismiss_posts_tooltip: "ניקוי ספירת הלא-נקראים בפוסטים אלו, תווך המשך הצגתם ברשימת הלא נקראים כאשר נוספים פרסומים חדשים" dismiss_topics: "דחיית פוסטים" - dismiss_topics_tooltip: "הפסקת הצגת פוסטים אלו ברשימת הלא-נקראו האישית כאשר נוספים פרסומים חדשים" dismiss_new: "שחרור חדשים" toggle: "החלף קבוצה מסומנת של פוסטים" actions: "מקבץ פעולות" @@ -1053,7 +1044,6 @@ he: description: "לעולם לא תקבל/י התראה בנוגע להודעה זו." muted: title: "מושתק" - description: "לעולם לא תקבל/י התראות על הפוסט הזה, והוא לא יופיע בעמוד ה\"לא נקראו\" שלך." actions: recover: "שחזר פוסט" delete: "מחק פוסט" @@ -1454,7 +1444,6 @@ he: description: "תקבלו התראה אם מישהו יזכיר את @שם_המשתמש/ת שלך או ישיב לפרסום שלך." muted: title: "מושתק" - description: " אתה לעולם לא תקבל התראות על פוסטים חדשים מקטגוריות אלו והם לא יופיעו בטאב ״לא נקראו״." flagging: title: 'תודה על עזרתך לשמירה על תרבות הקהילה שלנו!' private_reminder: 'דגלים הם פרטיים וניתנים לצפייה ע"י הצוות בלבד' @@ -1507,7 +1496,6 @@ he: help: "פוסט זה אינו מקובע עבורך; הוא יופיע בסדר הרגיל" pinned_globally: title: "נעוץ גלובאלית" - help: "הפוסט הזה נעוץ גלובאלית; הוא יוצג בראש כל הרשימות" pinned: title: "נעוץ" help: "פוסט זה מקובע עבורך, הוא יופיע בראש הקטגוריה" diff --git a/config/locales/client.it.yml b/config/locales/client.it.yml index 9b82a49e3b..dde4eca5ca 100644 --- a/config/locales/client.it.yml +++ b/config/locales/client.it.yml @@ -418,7 +418,6 @@ it: tracked_categories: "Seguite" tracked_categories_instructions: "Seguirai automaticamente tutti i nuovi argomenti appartenenti a queste categorie. Di fianco all'argomento comparirà il conteggio dei nuovi messaggi." muted_categories: "Silenziate" - muted_categories_instructions: "Non ti verrà notificato nulla sui nuovi argomenti in queste categorie, e non compariranno nel tab dei non letti." delete_account: "Cancella il mio account" delete_account_confirm: "Sei sicuro di voler cancellare il tuo account in modo permanente? Questa azione non può essere annullata!" deleted_yourself: "Il tuo account è stato eliminato con successo." @@ -778,7 +777,6 @@ it: show_edit_reason: "(aggiungi motivo della modifica)" reply_placeholder: "Scrivi qui. Per formattare il testo usa Markdown, BBCode o HTML. Trascina o incolla le immagini." view_new_post: "Visualizza il tuo nuovo messaggio." - saving: "Salvataggio..." saved: "Salvato!" saved_draft: "Hai un messaggio in bozza in sospeso. Seleziona per riprendere la modifica." uploading: "In caricamento..." @@ -805,10 +803,10 @@ it: heading_title: "Intestazione" heading_text: "Intestazione" hr_title: "Linea Orizzontale" - undo_title: "Annulla" - redo_title: "Ripeti" help: "Aiuto Inserimento Markdown" toggler: "nascondi o mostra il pannello di editing" + modal_ok: "Ok" + modal_cancel: "Annulla" admin_options_title: "Impostazioni dello staff opzionali per l'argomento" auto_close: label: "Tempo per auto-chiusura argomento:" @@ -864,15 +862,15 @@ it: from_my_computer: "Dal mio dispositivo" from_the_web: "Dal web" remote_tip: "collegamento all'immagine" - remote_tip_with_attachments: "collegamento ad un'immagine o a un file ({{authorized_extensions}})" local_tip: "seleziona immagini dal tuo dispositivo" - local_tip_with_attachments: "seleziona immagini o file dal tuo dispositivo ({{authorized_extensions}})" hint: "(puoi anche trascinarle nell'editor per caricarle)" uploading: "In caricamento" select_file: "Seleziona File" image_link: "collegamento a cui la tua immagine punterà" search: latest_post: "Ultimo Messaggio" + most_viewed: "I più visti" + most_liked: "I più apprezzati" select_all: "Seleziona Tutto" clear_all: "Cancella Tutto" title: "cerca argomenti, messaggi, utenti o categorie" @@ -895,10 +893,11 @@ it: bulk: reset_read: "Reimposta Lettura" delete: "Elimina Argomenti" - dismiss_posts: "Chiudi Messaggi" - dismiss_posts_tooltip: "Azzera il contatore dei messaggi non-letti di questi argomenti, ma quando vengono creati nuovi messaggi continua a mostrarli nella mia lista dei non-letti " + dismiss: "Ignora" + dismiss_button: "Ignora..." + dismiss_tooltip: "Ignora solo gli ultimi messaggi o smetti di seguire gli argomenti" + dismiss_posts: "Ignora solo gli ultimi messaggi" dismiss_topics: "Chiudi Argomenti" - dismiss_topics_tooltip: "Quando viene creato un nuovo messaggio, non mostrare più questi argomenti nella mia lista dei non-letti " dismiss_new: "Chiudi Nuovo" toggle: "commuta la selezione multipla degli argomenti" actions: "Azioni Multiple" @@ -1042,7 +1041,6 @@ it: description: "Non ti verrà notificato nulla per questo messaggio." muted: title: "Silenziato" - description: "Non ti verrà notificato nulla di questo argomento e non comparirà nella tab dei non letti." actions: recover: "Ripristina Argomento" delete: "Cancella Argomento" @@ -1259,6 +1257,7 @@ it: revert_to_regular: "Rimuovi Colore Staff" rebake: "Ricrea HTML" unhide: "Mostra nuovamente" + change_owner: "Cambia la proprietà" actions: flag: 'Segnala' defer_flags: @@ -1492,7 +1491,6 @@ it: help: "Questo argomento è per te spuntato; verrà mostrato con l'ordinamento di default" pinned_globally: title: "Appuntato Globalmente" - help: "Questo argomento è appuntato globalmente; verrà mostrato in cima ad ogni lista" pinned: title: "Appuntato" help: "Questo argomento è per te appuntato; verrà mostrato con l'ordinamento di default" diff --git a/config/locales/client.ja.yml b/config/locales/client.ja.yml index 8fac15c7b0..769fa879ea 100644 --- a/config/locales/client.ja.yml +++ b/config/locales/client.ja.yml @@ -353,7 +353,6 @@ ja: tracked_categories: "トラック中" tracked_categories_instructions: "これらのカテゴリの新規トピックを自動的にトラックします。トピックに対して新しい投稿があった場合、トピック一覧に新しい投稿数がつきます。" muted_categories: "ミュート中" - muted_categories_instructions: "このカテゴリに投稿されたトピックについての通知を受け取りません。また、未読タブにも通知されません。" delete_account: "アカウントを削除する" delete_account_confirm: "本当にアカウントを削除しますか?削除されたアカウントを復元できません。" deleted_yourself: "あなたのアカウントは削除されました。" @@ -675,7 +674,6 @@ ja: edit_reason_placeholder: "編集する理由は何ですか?" show_edit_reason: "(編集理由を追加)" view_new_post: "新規ポストを見る。" - saving: "保存中..." saved: "保存完了!" saved_draft: "編集中の投稿があります。選択すると再開します" uploading: "アップロード中..." @@ -702,8 +700,6 @@ ja: heading_title: "見出し" heading_text: "見出し" hr_title: "水平線" - undo_title: "取り消し" - redo_title: "やり直し" help: "Markdown 編集のヘルプ" toggler: "編集パネルの表示/非表示" admin_options_title: "このトピックの詳細設定" @@ -747,9 +743,7 @@ ja: from_my_computer: "このデバイスから" from_the_web: "Web から" remote_tip: "画像へのリンク" - remote_tip_with_attachments: "画像かファイルへのリンク ({{authorized_extensions}})" local_tip: "ローカルからアップロードする画像を選択" - local_tip_with_attachments: "ローカルからアップロードする画像またはファイルを選択 ({{authorized_extensions}})" hint: "(アップロードする画像をエディタにドラッグ&ドロップすることもできます)" uploading: "アップロード中" select_file: "ファイル選択" @@ -773,10 +767,7 @@ ja: bulk: reset_read: "未読に設定" delete: "トピックを削除" - dismiss_posts: "既読に設定" - dismiss_posts_tooltip: "未読トピック数をクリアする。" dismiss_topics: "既読に設定" - dismiss_topics_tooltip: "新しい投稿を未読リストに非表示する" dismiss_new: "既読に設定" toggle: "選択したトピックを切り替え" actions: "操作" @@ -908,7 +899,6 @@ ja: description: "このメッセージについての通知を受け取りません。" muted: title: "ミュート" - description: "このトピックについての通知を受け取りません。また、未読タブにも通知されません。" actions: recover: "トピック削除の取り消し" delete: "トピック削除" @@ -1315,7 +1305,6 @@ ja: help: "このトピックはピン留めされていません。 既定の順番に表示されます。" pinned_globally: title: "全サイト的にピン留めされました" - help: "このトピックは全サイト的にピン留めされました。全てのリストのトップに表示されます。" pinned: title: "ピン留め" help: "このトピックはピン留めされています。常にカテゴリのトップに表示されます" diff --git a/config/locales/client.ko.yml b/config/locales/client.ko.yml index af910a06b7..164371b870 100644 --- a/config/locales/client.ko.yml +++ b/config/locales/client.ko.yml @@ -385,7 +385,6 @@ ko: tracked_categories: "추적하기" tracked_categories_instructions: "이 카테고리 내의 새로운 토픽들을 추적하도록 자동으로 설정됩니다. 토픽 옆에 읽지 않은 게시글의 수가 표시됩니다." muted_categories: "알림 끄기" - muted_categories_instructions: "이 카테고리들에 새로 작성되는 새로운 토픽에 대한 알림이 오지 않도록 합니다. '읽지 않은'탭에서도 보이지 않게 됩니다." delete_account: "내 계정 삭제" delete_account_confirm: "정말로 계정을 삭제할까요? 이 작업은 되돌릴 수 없습니다." deleted_yourself: "계정이 삭제 되었습니다." @@ -728,7 +727,6 @@ ko: edit_reason_placeholder: "why are you editing?" show_edit_reason: "(add edit reason)" view_new_post: "새로운 글을 볼 수 있습니다." - saving: "저장 중..." saved: "저장 완료!" saved_draft: "작성중인 글이 있습니다. 계속 작성하려면 여기를 클릭하세요." uploading: "업로딩 중..." @@ -755,8 +753,6 @@ ko: heading_title: "표제" heading_text: "표제" hr_title: "수평선" - undo_title: "취소" - redo_title: "다시" help: "마크다운 편집 도움말" toggler: "작성 패널을 숨기거나 표시" admin_options_title: "이 토픽에 대한 옵션 설정" @@ -804,9 +800,7 @@ ko: from_my_computer: "컴퓨터에서 가져오기" from_the_web: "인터넷에서 가져오기" remote_tip: "이미지 링크" - remote_tip_with_attachments: "이미지 또는 파일 링크 ({{authorized_extensions}})" local_tip: "기기에서 이미지 선택" - local_tip_with_attachments: "기기에서이미지 또는 파일을 선택 ({{authorized_extensions}})" hint: "(드래그&드랍으로 업로드 가능)" uploading: "업로드 중입니다..." select_file: "파일 선택" @@ -831,10 +825,7 @@ ko: bulk: reset_read: "읽기 초기화" delete: "토픽 삭제" - dismiss_posts: "글 닫기" - dismiss_posts_tooltip: "이 토픽들의 '읽지 않은' 표시를 없애고 새 토픽이 발생하면 내 '읽지 않은' 목록에 표시하기" dismiss_topics: "토픽 닫기" - dismiss_topics_tooltip: "새글이 발생할 때 내 '읽지 않은' 목록에 표시하지 않기" dismiss_new: "새글 제거" toggle: "토픽 복수 선택" actions: "일괄 적용" @@ -970,7 +961,6 @@ ko: description: "이 메시지에 대해 어떠한 알림도 받지 않지 않습니다." muted: title: "알림 없음" - description: "아무 알림도 없습니다. '읽지 않은 글' 탭에 나타나지 않습니다." actions: recover: "토픽 다시 복구" delete: "토픽 삭제" @@ -1380,7 +1370,6 @@ ko: help: "이 토픽은 핀 제거 되었습니다. 목록에서 일반적인 순서대로 표시됩니다." pinned_globally: title: "핀 지정됨 (전역적)" - help: "이 토픽은 전역적으로 핀 지정 되었습니다. 모든 목록의 최상위에 표시됩니다." pinned: title: "핀 지정됨" help: "이 토픽은 고정되었습니다. 카테고리의 상단에 표시됩니다." diff --git a/config/locales/client.nb_NO.yml b/config/locales/client.nb_NO.yml index 1c96eda677..21e85055b7 100644 --- a/config/locales/client.nb_NO.yml +++ b/config/locales/client.nb_NO.yml @@ -395,7 +395,6 @@ nb_NO: tracked_categories: "Sporet" tracked_categories_instructions: "Du vil automatisk spore alle nye emner i disse kategoriene. Antallet uleste og nye innlegg vil vises ved emnets oppføring." muted_categories: "Dempet" - muted_categories_instructions: "Du vil ikke bli varslet om nye emner i disse kategoriene og de vil ikke vises i listen over ulest innhold." delete_account: "Slett kontoen min" delete_account_confirm: "Er du sikker på at du vil slette kontoen din permanent? Denne handlingen kan ikke angres!" deleted_yourself: "Slettingen av din konto har vært vellykket." @@ -724,7 +723,6 @@ nb_NO: edit_reason_placeholder: "hvorfor endrer du?" show_edit_reason: "(legg till endringsbegrunnelse)" view_new_post: "Se ditt nye innlegg." - saving: "Lagrer..." saved: "Lagret!" saved_draft: "Innleggsutkast. Velg for å fortsette." uploading: "Laster opp..." @@ -751,8 +749,6 @@ nb_NO: heading_title: "Overskrift" heading_text: "Overskrift" hr_title: "Horisontalt Skille" - undo_title: "Angre" - redo_title: "Gjenta" help: "Hjelp for redigering i Markdown" toggler: "gjem eller vis redigeringspanelet" admin_options_title: "Valgfrie emne-instillinger for ansatte" @@ -796,9 +792,7 @@ nb_NO: from_my_computer: "Fra Min Enhet" from_the_web: "Fra nettet" remote_tip: "link til bilde" - remote_tip_with_attachments: "link til bilde eller fil ({{authorized_extensions}})" local_tip: "velg bilder fra din enhet" - local_tip_with_attachments: "velg bilder eller filer fra din enhet ({{authorized_extensions}})" hint: "(du kan også drag & drop inn i editoren for å laste dem opp)" uploading: "Laster opp bilde" select_file: "Velg Fil" @@ -822,10 +816,7 @@ nb_NO: bulk: reset_read: "Nullstill lest" delete: "Slett Emne" - dismiss_posts: "Avvis innlegg" - dismiss_posts_tooltip: "Tøm antallet uleste innlegg i disse emnene men fortsett å vis dem i min liste over uleste innlegg når nye innlegg blir lagt inn" dismiss_topics: "Avvis innlegg" - dismiss_topics_tooltip: "Ikke vis disse emnene i min ulest-liste når nye innlegg i disse forekommer" dismiss_new: "Lest" toggle: "Veksle mellom massevelging av emner" actions: "Massehandlinger" @@ -966,7 +957,6 @@ nb_NO: description: "Du vil ikke få varslinger om noe i denne meldingnen. " muted: title: "Dempet" - description: "du vil ikke bli varslet om noen ting i dette emnet, og det vil ikke visest som ulest." actions: recover: "Gjenopprett emne" delete: "slett emne" @@ -1397,7 +1387,6 @@ nb_NO: help: "Dette emnet er ikke lenger fastsatt, det vil vises i vanlig rekkefølge" pinned_globally: title: "Globalt fastsatt" - help: "Dette emnet er globalt fastsatt; det vil vises på toppen av alle lister" pinned: title: "Fastsatt" help: "Dette emnet er fastsatt for deg; det vil vises i toppen av sin kategori" diff --git a/config/locales/client.nl.yml b/config/locales/client.nl.yml index a11b68a3e7..954e4c3599 100644 --- a/config/locales/client.nl.yml +++ b/config/locales/client.nl.yml @@ -418,7 +418,6 @@ nl: tracked_categories: "Gevolgd" tracked_categories_instructions: "Je volgt automatisch alle nieuwe topics in deze categorie. Naast het topic wordt het aantal nieuwe berichten weergegeven." muted_categories: "Genegeerd" - muted_categories_instructions: "Je zal geen notificaties krijgen over nieuwe topics en berichten in deze categoriën en ze verschijnen niet op je ongelezen overzicht." delete_account: "Verwijder mijn account" delete_account_confirm: "Weet je zeker dat je je account definitief wil verwijderen? Dit kan niet meer ongedaan gemaakt worden!" deleted_yourself: "Je account is verwijderd." @@ -782,7 +781,6 @@ nl: show_edit_reason: "(geef een reden)" reply_placeholder: "Typ hier. Gebruik Markdown, BBCode, of HTML om op te maken. Sleep of plak afbeeldingen." view_new_post: "Bekijk je nieuwe bericht." - saving: "Opslaan..." saved: "Opgeslagen!" saved_draft: "Bezig met conceptbericht. Selecteer om door te gaan." uploading: "Uploaden..." @@ -809,8 +807,6 @@ nl: heading_title: "Kop" heading_text: "Kop" hr_title: "Horizontale lijn" - undo_title: "Herstel" - redo_title: "Opnieuw" help: "Uitleg over Markdown" toggler: "verberg of toon de editor" admin_options_title: "Optionele stafinstellingen voor deze topic" @@ -868,9 +864,7 @@ nl: from_my_computer: "Vanaf mijn apparaat" from_the_web: "Vanaf het web" remote_tip: "link naar afbeelding" - remote_tip_with_attachments: "vul een url in van een afbeelding of bestand (toegestane extensies: {{authorized_extensions}})." local_tip: "selecteer afbeeldingen van uw apparaat" - local_tip_with_attachments: "Selecteer afbeeldingen of bestanden van je apparaat ({{authorized_extensions}})" hint: "(je kan afbeeldingen ook slepen in de editor om deze te uploaden)" hint_for_supported_browsers: "je kunt ook afbeeldingen slepen of plakken in de editor" uploading: "Uploaden" @@ -907,10 +901,7 @@ nl: bulk: reset_read: "markeer als ongelezen" delete: "Verwijder topics" - dismiss_posts: "Verwijder berichten" - dismiss_posts_tooltip: "Reset de teller voor ongelezen berichten voor deze topics, maar houd ze wel in mijn lijst van ongelezen topics als er nieuwe berichten worden toegevoegd" dismiss_topics: "Verwijder topics" - dismiss_topics_tooltip: "Laat deze topics niet meer in mijn lijst van ongelezen topics zien wanneer er nieuwe berichten worden geplaatst." dismiss_new: "markeer nieuwe berichten als gelezen" toggle: "toggle bulkselectie van topics" actions: "Bulk Acties" @@ -1054,7 +1045,6 @@ nl: description: "Je zal geen enkele notificatie ontvangen over dit bericht." muted: title: "Negeren" - description: "Je zal geen notificaties krijgen van dit topic en het zal ook niet verschijnen in je lijst ongelezen topics." actions: recover: "Herstel topic" delete: "Verwijder topic" @@ -1455,7 +1445,6 @@ nl: description: "Je krijgt een notificatie als iemand je @naam noemt of reageert op een bericht van jou." muted: title: "Genegeerd" - description: "Je zal geen notificaties krijgen over nieuwe topics en berichten in deze categoriën en ze verschijnen niet op je ongelezen overzicht." flagging: title: 'Bedankt voor het helpen beleefd houden van onze gemeenschap!' private_reminder: 'vlaggen zijn privé, alleen zichtbaar voor de staf' @@ -1508,7 +1497,6 @@ nl: help: "Dit topic is niet langer vastgepind voor je en zal weer in de normale volgorde getoond worden" pinned_globally: title: "Globaal vastgepind" - help: "Deze topic is globaal vastgepind en zal bovenaan alle topiclijsten getoond worden" pinned: title: "Vastgepind" help: "Dit topic is vastgepind voor je en zal bovenaan de categorie getoond worden" @@ -2395,9 +2383,7 @@ nl: embed_username_key_from_feed: "Key voor de Discourse gebruikersnaam in de feed." embed_truncate: "Embedde berichten inkorten" embed_whitelist_selector: "CSS selector voor elementen die worden toegestaan bij embedding" - whitelist_example: "artikel #verhaal, .post" embed_blacklist_selector: "CSS selector voor elementen die worden verwijderd bij embedding" - blacklist_example: ".ad-unit, header" feed_polling_enabled: "Importeer berichten via RSS/ATOM" feed_polling_url: "URL van RSS/ATOM feed voor crawling" save: "Embedding Instellingen Opslaan " diff --git a/config/locales/client.pl_PL.yml b/config/locales/client.pl_PL.yml index e6618d7f66..287ed99cc8 100644 --- a/config/locales/client.pl_PL.yml +++ b/config/locales/client.pl_PL.yml @@ -448,7 +448,7 @@ pl_PL: tracked_categories: "Śledzone" tracked_categories_instructions: "Będziesz automatycznie śledzić wszystkie nowe tematy w tych kategoriach. Licznik nowych wpisów pojawi się obok tytułu na liście tematów." muted_categories: "Wyciszone" - muted_categories_instructions: "Nie będziesz powiadamiany o niczym dotyczącym nowych tematów w tych kategoriach, i nie będą się one pojawiać na karcie nieprzeczytanych." + muted_categories_instructions: "Nie będziesz powiadamiany o nowych tematach w tych kategoriach. Nie pojawią się na liście nieprzeczytanych." delete_account: "Usuń moje konto" delete_account_confirm: "Czy na pewno chcesz usunąć swoje konto? To nieodwracalne!" deleted_yourself: "Twoje konto zostało usunięte." @@ -587,6 +587,10 @@ pl_PL: user: "Zaproszony(-a) użytkownik(-czka)" sent: "Wysłane" none: "Nie ma żadnych zaproszeń do wyświetlenia." + truncated: + one: "Wyświetlanie pierwszego zaproszenia." + few: "Wyświetlanie {{count}} pierwszych zaproszeń." + other: "Wyświetlanie {{count}} pierwszych zaproszeń." redeemed: "Cofnięte zaproszenia" redeemed_tab: "Przyjęte" redeemed_tab_with_count: "Zrealizowane ({{count}})" @@ -757,6 +761,9 @@ pl_PL: admin_not_allowed_from_ip_address: "Nie możesz się zalogować jako admin z tego adresu IP." resend_activation_email: "Kliknij tutaj, aby ponownie wysłać email z aktywacją konta." sent_activation_email_again: "Wysłaliśmy do ciebie kolejny email z aktywacją konta na {{currentEmail}}. Zanim dotrze, może minąć kilka minut; pamiętaj, żeby sprawdzić folder ze spamem." + to_continue: "Zaloguj się" + preferences: "Musisz się zalogować, aby zmieniać swoje ustawienia." + forgot: "Nie pamiętam konta" google: title: "przez Google" message: "Uwierzytelnianie przy pomocy konta Google (upewnij się, że blokada wyskakujących okienek nie jest włączona)" @@ -781,6 +788,7 @@ pl_PL: emoji_one: "Emoji One" composer: emoji: "Emoji :smile:" + more_emoji: "więcej…" options: "Opcje" whisper: "szept" add_warning: "To jest oficjalne ostrzeżenie." @@ -813,7 +821,7 @@ pl_PL: show_edit_reason: "(dodaj powód edycji)" reply_placeholder: "Pisz w tym miejscu. Wspierane formatowanie to Markdown, BBCode lub HTML. Możesz też przeciągnąć tu obrazek." view_new_post: "Zobacz Twój nowy wpis." - saving: "Zapisuję…" + saving: "Zapisywanie" saved: "Zapisano!" saved_draft: "Posiadasz zachowany szkic wpisu. Kliknij tu aby wznowić jego edycję." uploading: "Wczytuję…" @@ -828,6 +836,7 @@ pl_PL: link_description: "wprowadź tutaj opis odnośnika" link_dialog_title: "Wstaw odnośnik" link_optional_text: "opcjonalny tytuł" + link_placeholder: "http://example.com \"opcjonalny tekst\"" quote_title: "Cytat" quote_text: "Cytat" code_title: "Tekst sformatowany" @@ -840,10 +849,10 @@ pl_PL: heading_title: "Nagłówek" heading_text: "Nagłówek" hr_title: "Pozioma linia" - undo_title: "Cofnij" - redo_title: "Ponów" help: "Pomoc formatowania Markdown" toggler: "ukryj lub pokaż panel kompozytora tekstu" + modal_ok: "OK" + modal_cancel: "Anuluj" admin_options_title: "Opcjonalne ustawienia obsługi dla tego tematu" auto_close: label: "Automatycznie zamykaj tematy po:" @@ -899,9 +908,9 @@ pl_PL: from_my_computer: "Z mojego urządzenia" from_the_web: "Z Internetu" remote_tip: "link do obrazu" - remote_tip_with_attachments: "odnośnik do obrazu lub pliku ({{authorized_extensions}})" + remote_tip_with_attachments: "link do obrazu lub pliku {{authorized_extensions}}" local_tip: "wybierz obrazy ze swojego urządzenia" - local_tip_with_attachments: "wybierz obrazy lub pliki ze swojego urządzenia ({{authorized_extensions}})" + local_tip_with_attachments: "wybierz obrazy lub pliki ze swojego urządzenia {{authorized_extensions}}" hint: "(możesz także upuścić plik z katalogu komputera w okno edytora)" hint_for_supported_browsers: "możesz też przeciągać lub wklejać grafiki do edytora" uploading: "Wgrywanie" @@ -937,13 +946,16 @@ pl_PL: current_user: 'idź do swojej strony użytkowanika' topics: bulk: + unlist_topics: "Ukryj tematy" reset_read: "Wyzeruj przeczytane" delete: "Usuń tematy" - dismiss_posts: "Wyczyść liczniki wpisów" - dismiss_posts_tooltip: "Wyczyść liczniki nieprzeczytanych wpisów w tych tematach, ale informuj mnie jeśli pojawią się w nich nowe wpisy w przyszłości." - dismiss_topics: "Wyczyść status termatów" - dismiss_topics_tooltip: "Nie pokazuj tych tematów na mojej liście nieprzeczytanych gdy pojawią się w nich nowe wpisy." - dismiss_new: "Wyczyść nieprzeczytane" + dismiss: "Wyczyść" + dismiss_button: "Wyczyść…" + dismiss_tooltip: "Wyczyść nowe wpisy lub przestań śledzić tematy" + dismiss_body: "Chcesz tylko wyczyścić nieprzeczytane wpisy, czy też zupełnie przestać śledzić wskazane tematy?" + dismiss_posts: "Wyczyść nowe wpisy" + dismiss_topics: "Wyczyść tematy" + dismiss_new: "Wyczyść nowe" toggle: "włącz grupowe zaznaczanie tematów" actions: "Operacje grupowe" change_category: "Zmień kategorię" @@ -1094,7 +1106,7 @@ pl_PL: description: "Nie będziesz otrzymywać powiadomień dotyczących tej dyskusji." muted: title: "Wyciszenie" - description: "Nie będzie jakichkolwiek powiadomień dotyczących tego tematu i nie będzie się on pojawiać na karcie nieprzeczytanych." + description: "Nie otrzymasz powiadomień o nowych wpisach w tym temacie. Nie pojawią się na liście nieprzeczytanych" actions: recover: "Przywróć temat" delete: "Usuń temat" @@ -1322,6 +1334,7 @@ pl_PL: revert_to_regular: "Wyłącz kolor moderatora" rebake: "Odśwież HTML" unhide: "Wycofaj ukrycie" + change_owner: "Zmiana właściciela" actions: flag: 'Oflaguj' defer_flags: @@ -1524,7 +1537,7 @@ pl_PL: description: "Dostaniesz powiadomienie jedynie, gdy ktoś wspomni twoją @nazwę lub odpowie na twój wpis." muted: title: "Wyciszone" - description: "Nie otrzymasz powiadomień o tematach w tych kategoriach i nie będą się one pojawiać na karcie Nieprzeczytane." + description: "Nie otrzymasz powiadomień o nowych tematach w tych kategoriach. Nie pojawią się na liście nieprzeczytanych." flagging: title: 'Dziękujemy za pomoc w utrzymaniu porządku w naszej społeczności!' private_reminder: 'oflagowania są poufne i widoczne jedynie dla obsługi serwisu' @@ -1578,7 +1591,7 @@ pl_PL: help: "Temat nie jest przypięty w ramach twojego konta. Będzie wyświetlany w normalnej kolejności." pinned_globally: title: "Przypięty globalnie" - help: "Temat przypięty globalnie. Będzie wyświetlany na początku wszystkich list." + help: "Ten temat jest przypięty globalnie. Będzie wyświetlany na początku głównej listy oraz swojej kategorii." pinned: title: "Przypięty" help: "Temat przypięty dla twojego konta. Będzie wyświetlany na początku swojej kategorii." @@ -1834,6 +1847,10 @@ pl_PL: add: "Dodaj" add_members: "Dodaj członków" custom: "Niestandardowe" + bulk_complete: "Użytkownicy zostali dodani do wskazanej grupy." + bulk: "Dodaj więcej do grupy" + bulk_paste: "Podaj listę nazw użytkowników lub adresów e-mail, każdy w oddzielnej linii:" + bulk_select: "(wybierz grupę)" automatic: "Automatyczne" automatic_membership_email_domains: "Użytkownicy rejestrujący się przy pomocy adresu z tej listy zostaną automatycznie przypisani do tej grupy." automatic_membership_retroactive: "Zastosuj tę regułę domenową do już istniejących użytkowników." @@ -2474,9 +2491,7 @@ pl_PL: embed_username_key_from_feed: "Klucz używany do pobrania nazwy użytkownika z kanału" embed_truncate: "Skracaj treść osadzanych wpisów" embed_whitelist_selector: "Selektor CSS elementów jakie mogą być osadzane" - whitelist_example: "article, #tresc, .wpis" embed_blacklist_selector: "Selektor CSS elementów jakie są usuwane podczas osadzania" - blacklist_example: ".reklama, header" feed_polling_enabled: "Importowanie wpisów via RSS/ATOM" feed_polling_url: "URL kanału RSS/ATOM" save: "Zapisz" diff --git a/config/locales/client.pt.yml b/config/locales/client.pt.yml index 33e22e21a8..a423a053d4 100644 --- a/config/locales/client.pt.yml +++ b/config/locales/client.pt.yml @@ -418,7 +418,7 @@ pt: tracked_categories: "Acompanhado" tracked_categories_instructions: "Irá acompanhar automaticamente todos os novos tópicos nestas categorias. Uma contagem de novas mensagens irá aparecer junto ao tópico." muted_categories: "Silenciado" - muted_categories_instructions: "Não será notificado relativamente a novos tópicos nestas categorias, e não aparecerão no seu separador de tópicos não lidos." + muted_categories_instructions: "Não será notificado de nada acerca de novos tópicos nestas categorias, e estes não irão aparecer nos recentes." delete_account: "Eliminar A Minha Conta" delete_account_confirm: "Tem a certeza que pretende eliminar a sua conta de forma permanente? Esta ação não pode ser desfeita!" deleted_yourself: "A sua conta foi eliminada com sucesso." @@ -729,6 +729,9 @@ pt: admin_not_allowed_from_ip_address: "Não pode iniciar sessão como administrador a partir desse endereço IP." resend_activation_email: "Clique aqui para enviar o email de ativação novamente." sent_activation_email_again: "Enviámos mais um email de ativação para o endereço {{currentEmail}}. Pode ser que demore alguns minutos; certifique-se que verifica a sua pasta de spam ou lixo." + to_continue: "Por favor Inicie Sessão" + preferences: "Necessita de ter sessão iniciada para alterar as suas preferências de utilizador." + forgot: "Não me recordo dos detalhes da minha conta" google: title: "com Google" message: "A autenticar com Google (certifique-se de que os bloqueadores de popup estão desativados)" @@ -786,7 +789,7 @@ pt: show_edit_reason: "(adicione a razão para a edição)" reply_placeholder: "Digite aqui. Utilize Markdown, BBCode, ou HTML para formatar. Arraste ou cole imagens." view_new_post: "Ver a sua nova mensagem." - saving: "A Guardar..." + saving: "A Guardar" saved: "Guardado!" saved_draft: "Rascunho da mensagem em progresso. Selecione para continuar." uploading: "A carregar…" @@ -801,6 +804,7 @@ pt: link_description: "digite a descrição da hiperligação aqui" link_dialog_title: "Inserir Hiperligação" link_optional_text: "título opcional" + link_placeholder: "http://example.com \"texto opcional\"" quote_title: "Bloco de Citação" quote_text: "Bloco de Citação" code_title: "Texto pré-formatado" @@ -813,10 +817,10 @@ pt: heading_title: "Título" heading_text: "Título" hr_title: "Barra horizontal" - undo_title: "Desfazer" - redo_title: "Refazer" help: "Ajuda de Edição Markdown" toggler: "esconder ou exibir o painel de composição" + modal_ok: "OK" + modal_cancel: "Cancelar" admin_options_title: "Configurações opcionais do pessoal para este tópico" auto_close: label: "Tempo de fecho automático do tópico:" @@ -872,9 +876,9 @@ pt: from_my_computer: "Do meu dispositivo " from_the_web: "Da internet" remote_tip: "hiperligação para imagem" - remote_tip_with_attachments: "hiperligação para imagem ou ficheiro ({{authorized_extensions}})" + remote_tip_with_attachments: "hiperligação para imagem ou ficheiro {{authorized_extensions}}" local_tip: "selecionar imagens do seu dispositivo" - local_tip_with_attachments: "selecionar imagens ou ficheiros do seu dispositivo ({{authorized_extensions}})" + local_tip_with_attachments: "selecionar imagens ou ficheiros a partir do seu dispositivo {{authorized_extensions}}" hint: "(pode também arrastar o ficheiro para o editor para fazer o carregamento)" hint_for_supported_browsers: "pode também arrastar e largar ou colar imagens no editor" uploading: "A carregar" @@ -909,12 +913,15 @@ pt: current_user: 'ir para a sua página de utilizador' topics: bulk: + unlist_topics: "Remover Tópicos da Lista" reset_read: "Repor Leitura" delete: "Eliminar Tópicos" - dismiss_posts: "Destituir mensagens" - dismiss_posts_tooltip: "Remover contagem de não lidos nestes tópicos, mas manter a exibição dos mesmos na minha lista de não lidos quando novas mensagens são criadas." + dismiss: "Destituir" + dismiss_button: "Destituir..." + dismiss_tooltip: "Destituir apenas novas mensagens ou parar o acompanhamento de tópicos" + dismiss_body: "Gostaria de destituir apenas as novas mensagens nestes tópicos, ou destituir os tópicos por inteiro?" + dismiss_posts: "Destituir Apenas Novas Mensagens" dismiss_topics: "Destituir Tópicos" - dismiss_topics_tooltip: "Parar a exibição destes tópicos na minha lista de não lidos quando são criadas novas mensagens" dismiss_new: "Destituir Novo" toggle: "ativar seleção em massa de tópicos" actions: "Ações em Massa" @@ -1058,7 +1065,7 @@ pt: description: "Não será notificado de nada relacionado com esta mensagem." muted: title: "Silenciado" - description: "Não será notificado de nada que esteja relacionado com este tópico, e este não será apresentado no seu separador de 'não lido'." + description: "Nunca será notificado de nada acerca deste tópico, e este não irá aparecer nos recentes." actions: recover: "Recuperar Tópico" delete: "Eliminar Tópico" @@ -1275,6 +1282,7 @@ pt: revert_to_regular: "Remover Cor do Pessoal" rebake: "Reconstruir HTML" unhide: "Mostrar" + change_owner: "Mudar Titularidade" actions: flag: 'Sinalizar' defer_flags: @@ -1459,7 +1467,7 @@ pt: description: "Será notificado se alguém mencionar o seu @nome ou responder-lhe." muted: title: "Silenciado" - description: "Nunca será notificado de nada acerca de novos tópicos nestas categorias, e estes não irão aparecer no seu separador de não lidos." + description: "Nunca será notificado de nada acerca de novos tópicos nestas categorias, e estes não irão aparecer nos recentes." flagging: title: 'Obrigado por ajudar a manter a nossa comunidade cívica!' private_reminder: 'as sinalizações são privadas, visíveis apenas para o pessoal' @@ -1512,7 +1520,7 @@ pt: help: "Este tópico foi desafixado por si; será mostrado na ordem habitual" pinned_globally: title: "Fixado Globalmente" - help: "Este tópico está fixado globalmente; será mostrado no topo de todas as listas" + help: "Este tópico está fixado globalmente; será exibido no topo dos recentes e da sua categoria" pinned: title: "Fixado" help: "Este tópico foi fixado por si; será mostrado no topo da sua categoria" @@ -1766,6 +1774,10 @@ pt: add: "Adicionar" add_members: "Adicionar membros" custom: "Personalizar" + bulk_complete: "Os utilizadores foram adicionados ao grupo." + bulk: "Adicionar ao Grupo em Massa" + bulk_paste: "Colar uma lista de nomes de utilizador ou emails, um por linha:" + bulk_select: "(selecionar um grupo)" automatic: "Automático" automatic_membership_email_domains: "Utilizadores que registem um domínio de email que corresponde exactamente a algum desta lista irão ser automaticamente adicionados a este grupo:" automatic_membership_retroactive: "Aplicar a mesma regra de domínio de email para adicionar utilizadores registados existentes" @@ -2399,9 +2411,7 @@ pt: embed_username_key_from_feed: "Chave para puxar o nome de utilizador discouse do feed" embed_truncate: "Truncar as mensagens incorporadas" embed_whitelist_selector: "Seletor CSS para elementos que são permitidos nas incorporações" - whitelist_example: "artigo, #história, .mensagem" embed_blacklist_selector: "Seletor CSS para elementos que são removidos das incorporações" - blacklist_example: ".unidade-anuncio, cabeçalho" feed_polling_enabled: "Importar mensagens através de RSS/ATOM" feed_polling_url: "URL do feed RSS/ATOM para rastreio" save: "Guardar Configurações de Incorporação" diff --git a/config/locales/client.pt_BR.yml b/config/locales/client.pt_BR.yml index 9803ba5b08..4abd9e026f 100644 --- a/config/locales/client.pt_BR.yml +++ b/config/locales/client.pt_BR.yml @@ -418,7 +418,6 @@ pt_BR: tracked_categories: "Monitorado" tracked_categories_instructions: "Automaticamente monitora todos novos tópicos nestas categorias. Uma contagem de posts não lidos e novos aparecerá próximo ao tópico." muted_categories: "Silenciado" - muted_categories_instructions: "Você não será notificado sobre novos tópicos dessas categorias e eles não vão aparecer na guia de mensagens não lidas." delete_account: "Excluir Minha Conta" delete_account_confirm: "Tem certeza de que deseja excluir permanentemente a sua conta? Essa ação não pode ser desfeita!" deleted_yourself: "Sua conta foi excluída com sucesso." @@ -786,7 +785,6 @@ pt_BR: show_edit_reason: "(adicione motivo da edição)" reply_placeholder: "Escreva aqui. Use Markdown, BBCode ou HTML para formatar. Arraste ou cole uma imagens." view_new_post: "Ver sua nova resposta." - saving: "Salvando..." saved: "Salvo!" saved_draft: "Rascunho salvo, clique em selecionar para continuar editando." uploading: "Enviando..." @@ -813,8 +811,6 @@ pt_BR: heading_title: "Título" heading_text: "Título" hr_title: "Barra horizontal" - undo_title: "Desfazer" - redo_title: "Refazer" help: "Ajuda da edição Markdown" toggler: "esconder ou exibir o painel de composição" admin_options_title: "Configurações opcionais da equipe para este tópico" @@ -872,9 +868,7 @@ pt_BR: from_my_computer: "Do meu dispositivo" from_the_web: "Da internet" remote_tip: "link da imagem" - remote_tip_with_attachments: "link da imagem ou arquivo ({{authorized_extensions}})" local_tip: "selecione imagens a partir do seu dispositivo" - local_tip_with_attachments: "Selecione imagens ou arquivos do seu dispositivo ({{authorized_extensions}})" hint: "(Você também pode arrastar e soltar para o editor para carregá-las)" hint_for_supported_browsers: "Você pode também arrastar e soltar ou copiar imagens no editor" uploading: "Enviando" @@ -911,10 +905,7 @@ pt_BR: bulk: reset_read: "Redefinir Lido" delete: "Apagar Tópicos" - dismiss_posts: "Ignorar Posts" - dismiss_posts_tooltip: "Zerar contagem de não lidos nestes tópicos, mas continuar a mostrar eles em minha lista de não lidos quando novos posts forem feitos." dismiss_topics: "Ignorar Tópicos" - dismiss_topics_tooltip: "Para de mostrar estes tópicos em minha lista de não lidos quando novos posts forem feitos." dismiss_new: "Dispensar Nova" toggle: "alternar a seleção em massa de tópicos" actions: "Ações em Massa" @@ -1058,7 +1049,6 @@ pt_BR: description: "Você nunca será notificado de qualquer coisa sobre essa mensagem privada." muted: title: "Silenciar" - description: "Você nunca será notificado em nada sobre esse tópico e não aparecerá na guia de não lidas." actions: recover: "Recuperar Tópico" delete: "Apagar tópico" @@ -1459,7 +1449,6 @@ pt_BR: description: "Você será notificado se alguém mencionar o seu @nome ou responder à sua mensagem." muted: title: "Silenciar" - description: "Você não será notificado sobre novos tópicos dessas categorias e eles não vão aparecer na guia de mensagens não lidas." flagging: title: 'Obrigado por ajudar a manter a civilidade da nossa comunidade!' private_reminder: 'sinalizações são privadas, apenas ficam visíveis a moderação' @@ -1512,7 +1501,6 @@ pt_BR: help: "Este tópico está desfixado para você; ele será mostrado em ordem normal" pinned_globally: title: "Fixo Globalmente" - help: "Esse tópico está fixo; ele será mostrado no topo de todas as listas" pinned: title: "Fixo" help: "Este tópico está fixado para você; ele será mostrado no topo de sua categoria" @@ -2399,9 +2387,7 @@ pt_BR: embed_username_key_from_feed: "Chave para obter o nome de usuário no discourse do feed" embed_truncate: "Truncar as postagens incorporadas" embed_whitelist_selector: "Seletor de CSS para elementos que são permitidos na incorporação" - whitelist_example: "article, #historia, .post" embed_blacklist_selector: "Seletor de CSS para elementos que são removidos da incorporação" - blacklist_example: ".ad-unit, header, .propaganda" feed_polling_enabled: "Importar postagens via RSS/ATOM" feed_polling_url: "URL do feed RSS/ATOM para pesquisar" save: "Salvar Configurações de Incorporação" diff --git a/config/locales/client.ro.yml b/config/locales/client.ro.yml index 265ca0fd51..abf368bdbf 100644 --- a/config/locales/client.ro.yml +++ b/config/locales/client.ro.yml @@ -370,7 +370,6 @@ ro: watched_categories: "Văzut" tracked_categories: "Tracked" muted_categories: "Muted" - muted_categories_instructions: "Nu vei fii notificat de dicuțiile apărute în aceste categorii și ele nu vor apărea în tabul necitite." delete_account: "Șterge-mi contul" delete_account_confirm: "Ești sigur că vrei sa ștergi contul? Această acțiune poate fi anulată!" deleted_yourself: "Contul tău a fost șters cu succes." @@ -689,7 +688,6 @@ ro: edit_reason_placeholder: "de ce editați?" show_edit_reason: "(adaugă motivul editării)" view_new_post: "Vizualizează noua postare." - saving: "Salvează..." saved: "Salvat!" saved_draft: "Ai o postare în stadiul neterminat. Fă click oriunde pentru a continua editarea." uploading: "Încarcă..." @@ -716,8 +714,6 @@ ro: heading_title: "Titlu" heading_text: "Titlu" hr_title: "Regulă de ordonare orizontală" - undo_title: "Anulează schimbările" - redo_title: "Refă schimbările" help: "Ajutor de editare" toggler: "ascunde sau arată panelul de compus" admin_options_title: "Setări opționale ale discuției pentru moderatori" @@ -761,7 +757,6 @@ ro: from_my_computer: "din dispozitivul meu" from_the_web: "De pe web" remote_tip: "adresă către imagine http://example.com/image.jpg" - remote_tip_with_attachments: "adresă către imagine sau fișier http://example.com/file.ext (extensii permise: {{authorized_extensions}})." hint: "(puteți să trageți și să aruncați în editor pentru a le încărca)" uploading: "Încarcă" image_link: "Adresa din imagine va duce la" @@ -782,10 +777,7 @@ ro: bulk: reset_read: "resetează citirea" delete: "Șterge subiectele" - dismiss_posts: "Șterge postarea" - dismiss_posts_tooltip: "Șterge părțile necitite din această discuție dar continuă afișarea lor în lista de necitite când au loc postări noi" dismiss_topics: "Sterge discuția" - dismiss_topics_tooltip: "Nu arăta aceste discuții în lista de necitite când au loc postări noi" dismiss_new: "Anulează cele noi" toggle: "activează selecția în masă pentru discuții" actions: "Acțiuni în masă" @@ -919,7 +911,6 @@ ro: description: "Nu veţi fi niciodată notificat despre acest mesaj." muted: title: "Silențios" - description: "Nu veți fi notificat de nimic în legătură cu această dicuție, nu va apărea în tabul necitite." actions: recover: "Rescrie discuție" delete: "Șterge Discuție" @@ -1357,7 +1348,6 @@ ro: help: "Această discuţie va fi afişată în ordinea iniţială, nici un mesaj nu este promovat la inceputul listei." pinned_globally: title: "Fixată Global" - help: "Această discuție a fost fixată global; va fi afișată în capătul tuturor listelor" pinned: title: "Fixată" help: "Aceast mesaj va fi promovat. Va fi afişat la începutul discuţiei." diff --git a/config/locales/client.ru.yml b/config/locales/client.ru.yml index 24f0829381..976aa335e1 100644 --- a/config/locales/client.ru.yml +++ b/config/locales/client.ru.yml @@ -26,7 +26,7 @@ ru: tb: ТБ short: thousands: "{{number}} тыс." - millions: "{{number}} млн" + millions: "{{number}} млн." dates: time: "HH:mm" long_no_year: "D MMM HH:mm" @@ -433,6 +433,7 @@ ru: private_messages: "Личные сообщения" activity_stream: "Активность" preferences: "Настройки" + expand_profile: "Развернуть" bookmarks: "Закладки" bio: "Обо мне" invited_by: "Пригласил" @@ -471,7 +472,6 @@ ru: tracked_categories: "Отслеживаемые разделы" tracked_categories_instructions: "Автоматически следить за всеми новыми темами из следующих разделов. Счетчик новых и непрочитанных сообщений будет появляться рядом с названием темы." muted_categories: "Выключенные разделы" - muted_categories_instructions: "Вы не будете получать уведомления о новых темах в этих разделах. Также, они не будут показываться во вкладке Непрочитанное." delete_account: "Удалить мою учётную запись" delete_account_confirm: "Вы уверены, что хотите удалить свою учётную запись? Отменить удаление будет невозможно!" deleted_yourself: "Ваша учётная запись была успешно удалена." @@ -581,16 +581,28 @@ ru: every_two_weeks: "каждые 2 недели" email_direct: "Присылать почтовое уведомление, когда кто-то цитирует меня, отвечает на мой пост, упоминает мой @псевдоним или приглашает меня в тему" email_private_messages: "Присылать почтовое уведомление, когда кто-то оставляет мне сообщение" + email_always: "Присылать почтовое уведомление, даже если я присутствую на сайте" other_settings: "Прочее" categories_settings: "Разделы" new_topic_duration: label: "Считать темы новыми, если" not_viewed: "Еще не просмотрены" - last_here: "создано после вашего последнего визита" + 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 минут" invited: search: "Введите текст для поиска по приглашениям..." title: "Приглашения" @@ -819,7 +831,6 @@ ru: edit_reason_placeholder: "почему вы хотите изменить?" show_edit_reason: "(добавить причину редактирования)" view_new_post: "Посмотреть созданное вами сообщение." - saving: "Сохранение..." saved: "Сохранено!" saved_draft: "Черновик сообщения. Нажмите, чтобы продолжить редактирование." uploading: "Загрузка..." @@ -846,8 +857,6 @@ ru: heading_title: "Заголовок" heading_text: "Заголовок" hr_title: "Горизонтальный разделитель" - undo_title: "Отменить" - redo_title: "Повторить" help: "Справка по Markdown" toggler: "скрыть / показать панель редактирования" admin_options_title: "Дополнительные настройки темы" @@ -891,7 +900,6 @@ ru: from_my_computer: "From my device" from_the_web: "From the web" remote_tip: "ссылка на изображение" - remote_tip_with_attachments: "ссылка на изображение или файл ({{authorized_extensions}})" hint: "(вы так же можете перетащить объект в редактор для его загрузки)" uploading: "Загрузка" select_file: "Выбрать файл" @@ -927,10 +935,10 @@ ru: bulk: reset_read: "Сбросить прочтённые" delete: "Удалить темы" - dismiss_posts: "Отложить сообщения" - dismiss_posts_tooltip: "Сбросить текущие непрочитанные сообщения в этих темах сейчас, но снова показывать в непрочитанных, когда появятся новые ответы." + dismiss: "OK" + dismiss_button: "Отложить..." + dismiss_tooltip: "Отложить новые сообщения или перестать следить за этими темами" dismiss_topics: "Отложить темы" - dismiss_topics_tooltip: "Больше не показывать эти темы в непрочитанных, когда в них появятся новые ответы." dismiss_new: "Отложить новые" toggle: "Вкл./выкл. выбор нескольких тем" actions: "Массовое действие" @@ -1083,7 +1091,6 @@ ru: description: "Никогда не получать уведомлений, связанных с этой беседой." muted: title: "Без уведомлений" - description: "Никогда не получать уведомлений, связанных с этой темой, и не показывать ее во вкладке «Непрочитанные»." actions: recover: "Отменить удаление темы" delete: "Удалить тему" @@ -1573,7 +1580,6 @@ ru: help: "Эта тема не закреплена; она будет отображаться в обычном порядке" pinned_globally: title: "Закреплена глобально" - help: "Эта тема закреплена глобально и будет отображаться в начале всех списков" pinned: title: "Закреплена" help: "Тема закреплена; она будет показана вверху соответствующего раздела" diff --git a/config/locales/client.sq.yml b/config/locales/client.sq.yml index 937919b681..a6a645dd96 100644 --- a/config/locales/client.sq.yml +++ b/config/locales/client.sq.yml @@ -383,7 +383,6 @@ sq: tracked_categories: "Gjurmuar" tracked_categories_instructions: "You will automatically track all new topics in these categories. A count of new posts will appear next to the topic." muted_categories: "Heshtur" - muted_categories_instructions: "You will not be notified of anything about new topics in these categories, and they will not appear on your unread tab." delete_account: "Fshi Llogarin Time" delete_account_confirm: "Are you sure you want to permanently delete your account? This action cannot be undone!" deleted_yourself: "Llogaria juaj u fshi me sukses." @@ -706,7 +705,6 @@ sq: edit_reason_placeholder: "pse jeni duke e redaktuar?" show_edit_reason: "(arsye redaktimit)" view_new_post: "Shikoni postimin tuaj te ri." - saving: "Duke ruajtur..." saved: "U Ruajt!" saved_draft: "Post draft in progress. Select to resume." uploading: "Duke nga ngarkuar..." @@ -733,8 +731,6 @@ sq: heading_title: "Heading" heading_text: "Heading" hr_title: "Horizontal Rule" - undo_title: "Rikthe" - redo_title: "Ribëj" help: "Markdown Editing Help" toggler: "hide or show the composer panel" admin_options_title: "Optional staff settings for this topic" @@ -778,9 +774,7 @@ sq: from_my_computer: "Nga çdo paisje" from_the_web: "Nga web" remote_tip: "lidhje tek imazhi" - remote_tip_with_attachments: "lidhje për tek imazhi ose skedari ({{authorized_extensions}})" local_tip: "select images from your device" - local_tip_with_attachments: "select images or files from your device ({{authorized_extensions}})" hint: "(you can also drag & drop into the editor to upload them)" uploading: "Duke ngarkaur" select_file: "Select File" @@ -804,10 +798,7 @@ sq: bulk: reset_read: "Reseto Leximet" delete: "Delete Topics" - dismiss_posts: "Dismiss Posts" - dismiss_posts_tooltip: "Clear unread counts on these topics but continue to show them on my unread list when new posts are made" dismiss_topics: "Dismiss Topics" - dismiss_topics_tooltip: "Stop showing these topics in my unread list when new posts are made" dismiss_new: "Dismiss New" toggle: "toggle bulk selection of topics" actions: "Bulk Actions" @@ -946,7 +937,6 @@ sq: description: "You will never be notified of anything about this message." muted: title: "Muted" - description: "You will never be notified of anything about this topic, and it will not appear on your unread tab." actions: recover: "Un-Delete Topic" delete: "Fshi Diskutimin" @@ -1383,7 +1373,6 @@ sq: help: "This topic is unpinned for you; it will display in regular order" pinned_globally: title: "Pinned Globally" - help: "This topic is pinned globally; it will display at the top of all lists" pinned: title: "Pinned" help: "This topic is pinned for you; it will display at the top of its category" diff --git a/config/locales/client.sv.yml b/config/locales/client.sv.yml index 762ab29f8e..5d7939400a 100644 --- a/config/locales/client.sv.yml +++ b/config/locales/client.sv.yml @@ -381,7 +381,6 @@ sv: tracked_categories: "Bevakade" tracked_categories_instructions: "Du kommer automatiskt att följa alla nya ämnen i dessa kategorier. Antalet nya inlägg visas bredvid ämnet." muted_categories: "Tystad" - muted_categories_instructions: "Du kommer inte att få notifieringar om nya ämnen inom dessa kategorier, och de kommer inte att visas under din \"oläst\"-flik." delete_account: "Radera mitt konto" delete_account_confirm: "Är du säker på att du vill ta bort ditt konto permanent? Denna åtgärd kan inte ångras!" deleted_yourself: "Ditt konto har tagits bort." @@ -702,7 +701,6 @@ sv: edit_reason_placeholder: "varför redigerar du?" show_edit_reason: "(lägg till anledningar för redigering)" view_new_post: "Visa ditt nya inlägg." - saving: "Sparar..." saved: "Sparat!" saved_draft: "Utkast för inlägg. Välj för att fortsätta." uploading: "Laddar upp..." @@ -729,8 +727,6 @@ sv: heading_title: "Rubrik" heading_text: "Rubrik" hr_title: "Horisontell linje" - undo_title: "Ångra" - redo_title: "Återställ" help: "Markdown Redigeringshjälp" toggler: "Dölj eller visa composer-panelen" admin_options_title: "Valfria personalinställningar för detta ämne" @@ -774,7 +770,6 @@ sv: from_my_computer: "Från min enhet" from_the_web: "Från webben" remote_tip: "länk till bild" - remote_tip_with_attachments: "länk till bild eller fil ({{authorized_extensions}})" hint: "(du kan också dra & släppa in i redigeraren för att ladda upp dem)" uploading: "Laddar upp bild" select_file: "Välj fil" @@ -796,10 +791,7 @@ sv: bulk: reset_read: "Återställ Lästa" delete: "Ta bort diskussioner" - dismiss_posts: "Avfärda inlägg" - dismiss_posts_tooltip: "Nollställ räknaren för olästa i dessa diskussioner men fortsätt visa mig dem på min olästalista när nya inlägg har gjorts. " dismiss_topics: "Avfärda Diskussioner" - dismiss_topics_tooltip: "Sluta visa mig dessa diskussioner i min olästalista när nya inlägg har gjorts" dismiss_new: "Avfärda Nya" toggle: "toggla val av multipla ämnen" actions: "Massändringar" @@ -938,7 +930,6 @@ sv: description: "Du kommer aldrig bli notifierad om något gällande detta meddelande." muted: title: "Dämpad" - description: "Du kommer aldrig meddelas om detta ämne alls, och den kommer inte visas i din \"oläst\"-flik." actions: recover: "Återställ ämne" delete: "Radera ämne" @@ -1366,7 +1357,6 @@ sv: help: "Detta ämne är oklistrat för dig. Det visas i vanlig ordning" pinned_globally: title: "Klistrat Globalt" - help: "Det här ämnet är klistrat globalt; det kommer att visas högst upp i alla listor" pinned: title: "Klistrat" help: "Detta ämne är klistrat för dig. Det visas i toppen av dess kategori" diff --git a/config/locales/client.te.yml b/config/locales/client.te.yml index 331aa68870..855d6a223c 100644 --- a/config/locales/client.te.yml +++ b/config/locales/client.te.yml @@ -303,7 +303,6 @@ te: watched_categories: "ఒకకన్నేసారు" tracked_categories: "గమనించారు" muted_categories: "నిశ్శబ్దం" - muted_categories_instructions: "ఈ వర్గాలలోని ఏ కొత్త విషయాల గురించీ మీకు ప్రకటనలు రావు. ఇంకా అవి చదవని ట్యాబులో కనిపించవు." delete_account: "నా ఖాతా తొలగించు" delete_account_confirm: "నిజ్జంగా మీరు మీ ఖాతాను శాస్వతంగా తొలగించాలనుకుంటున్నారా? ఈ చర్య రద్దుచేయలేరు సుమా! " deleted_yourself: "మీ ఖాతా విజయవంతంగా తొలగించబడింది. " @@ -597,7 +596,6 @@ te: edit_reason_placeholder: "మీరెందుకు సవరిస్తున్నారు?" show_edit_reason: "(సవరణ కారణం రాయండి)" view_new_post: "మీ కొత్త టపా చూడండి" - saving: "భద్రమవుతోంది..." saved: "భద్రం!" saved_draft: "టపా చిత్తుప్రతి నడుస్తోంది. కొనసాగించుటకు ఎంచుకోండి." uploading: "ఎగుమతవుతోంది..." @@ -624,8 +622,6 @@ te: heading_title: "తలకట్టు" heading_text: "తలకట్టు" hr_title: "అడ్డు గీత" - undo_title: "రద్దు" - redo_title: "తిద్దు" help: "మార్క్ డైన్ సవరణ సహాయం" toggler: "దాచు లేదా చూపు కంపోజరు ఫలకం" admin_options_title: "ఈ విషయానికి ఐచ్చిక సిబ్బంది అమరికలు" @@ -659,7 +655,6 @@ te: from_my_computer: "నా పరికరం నుండి" from_the_web: "జాలం నుండి" remote_tip: "బొమ్మకు లంకె" - remote_tip_with_attachments: "బొమ్మకు లేదా దస్త్రానికి లంకె ({{authorized_extensions}})" hint: "(మీరు వాటిని ఎడిటరులోకి లాగి వదిలెయ్యటు ద్వారా కూడా ఎగుమతించవచ్చు)" uploading: "ఎగుమతవుతోంది" image_link: "మీ బొమ్మ చూపే లంకె" @@ -679,10 +674,7 @@ te: bulk: reset_read: "రీలోడ్ రీసెట్" delete: "విషయాలు తొలగించు" - dismiss_posts: "టపాలు తుడువు" - dismiss_posts_tooltip: "ఈ విషయాలపే చదవని సంఖ్యను తుడువు, కానీ కొత్తగా వచ్చే టపాలను నా చదవని సంఖ్యలో చూపుటు కొనసాగించు" dismiss_topics: "విషయాలు తుడువు" - dismiss_topics_tooltip: "కొత్త టపాలు వచ్చినా, నా చదవని జాబితాలో ఈ విషయాలు నుండి చూపుటు ఆపు. " dismiss_new: "కొత్తవి తుడువు" toggle: "విషయాల బహుళ ఎంపికలు అటుఇటుచేయి" actions: "బహుళ చర్యలు" @@ -805,7 +797,6 @@ te: title: "నిశ్శబ్దం" muted: title: "నిశ్శబ్దం" - description: "ఈ ప్రైవేటు సందేశం నుండి మీకు అస్సలు ప్రకటనలు రావు. ఇంకా చదవని సంఖ్య కనిపించదు." actions: recover: "విషయం తొలగింపు రద్దుచేయి" delete: "విషయం తొలగించు" @@ -1157,7 +1148,6 @@ te: help: "ఈ విషయం మీకు అగ్గుచ్చబడింది. ఇది ఇహ క్రమ వరుసలోనే కనిపిస్తుంది" pinned_globally: title: "సార్వత్రికంగా గుచ్చారు" - help: "ఈ విషయం సార్వత్రికంగా గుచ్చారు; అన్ని వరుసల్లోనూ ఇది అగ్రభాగాన కనిపిస్తుంది." pinned: title: "గుచ్చారు" help: "ఈ విషయం మీకు గుచ్చబడింది. దాని వర్గంలో అది అగ్రభాగాన కనిపిస్తుంది." diff --git a/config/locales/client.tr_TR.yml b/config/locales/client.tr_TR.yml index 6ab81095b3..b036721bfe 100644 --- a/config/locales/client.tr_TR.yml +++ b/config/locales/client.tr_TR.yml @@ -386,7 +386,6 @@ tr_TR: tracked_categories: "Takip edildi" tracked_categories_instructions: "Bu kategorilerdeki tüm yeni konuları otomatik olarak takip edeceksiniz. Okunmamış ve yeni gönderilerin sayısı ilgili konunun yanında belirecek." muted_categories: "Susturuldu" - muted_categories_instructions: "Bu kategorideki yeni konular okunmamışlar sekmenizde belirmeyecek, ve haklarında hiçbir bildirim almayacaksınız." delete_account: "Hesabımı Sil" delete_account_confirm: "Hesabınızı kalıcı olarak silmek istediğinize emin misiniz? Bu işlemi geri alamazsınız!" deleted_yourself: "Hesabınız başarıyla silindi." @@ -726,7 +725,6 @@ tr_TR: show_edit_reason: "(düzenleme sebebi ekle)" reply_placeholder: "Buraya yazın. Biçimlendirmek için Markdown, BBCode ya da HTML kullanabilirsin. Resimleri sürükleyebilir ya da yapıştırabilirsin." view_new_post: "Yeni gönderinizi görüntüleyin." - saving: "Kaydediliyor..." saved: "Kaydedildi!" saved_draft: "Gönderi taslağı işleniyor. Geri almak için seçin. " uploading: "Yükleniyor..." @@ -753,8 +751,6 @@ tr_TR: heading_title: "Başlık" heading_text: "Başlık" hr_title: "Yatay Çizgi" - undo_title: "Geri Al" - redo_title: "Tekrarla" help: "Markdown Düzenleme Yardımı" toggler: "yazım alanını gizle veya göster" admin_options_title: "Bu konu için opsiyonel görevli ayarları" @@ -812,9 +808,7 @@ tr_TR: from_my_computer: "Kendi cihazımdan" from_the_web: "Webden" remote_tip: "resme bağlantı ver" - remote_tip_with_attachments: "resme ya da dosyaya ({{authorized_extensions}}) bağlantı ver" local_tip: "cihazınızdan resimler seçin" - local_tip_with_attachments: "cihazınızdan resim veya dosyalar seçin ({{authorized_extensions}})" hint: "(editöre sürekle & bırak yaparak da yükleyebilirsiniz)" hint_for_supported_browsers: "ayrıca resimleri düzenleyiciye sürükleyip bırakabilir ya da yapıştırabilirsiniz" uploading: "Yükleniyor" @@ -843,10 +837,7 @@ tr_TR: bulk: reset_read: "Okunmuşları Sıfırla" delete: "Konuları Sil" - dismiss_posts: "Gönderileri Yoksay" - dismiss_posts_tooltip: "Bu konulardaki okunmamışların sayısını sıfırla ama yeni gönderiler oluşturulduğunda okunmamışlar listemde göster" dismiss_topics: "Konuları Yoksay" - dismiss_topics_tooltip: "Bu konularda yeni gönderiler oluşturulunca okunmamış listemde gösterme" dismiss_new: "Yenileri Yoksay" toggle: "konuların toplu seçimini aç/kapa" actions: "Toplu İşlemler" @@ -983,7 +974,6 @@ tr_TR: description: "Bu mesajlaşmayla ilgili hiç bir bildirim almayacaksınız." muted: title: "Susturuldu" - description: "Bu konu okunmamışlar sekmenizde belirmeyecek, ve hakkında hiç bir bildirim almayacaksınız." actions: recover: "Konuyu Geri Getir" delete: "Konuyu Sil" @@ -1403,7 +1393,6 @@ tr_TR: help: "Bu konu sizin için başa tutturulmuyor; normal sıralama içerisinde görünecek" pinned_globally: title: "Her Yerde Başa Tutturuldu" - help: "Bu konu her yerde başa tutturuldu; tüm listelerin başında görünecek" pinned: title: "Başa Tutturuldu" help: "Bu konu sizin için başa tutturuldu; kendi kategorisinin en üstünde görünecek" diff --git a/config/locales/client.uk.yml b/config/locales/client.uk.yml index 3e3b842183..5fe50f3bb4 100644 --- a/config/locales/client.uk.yml +++ b/config/locales/client.uk.yml @@ -299,7 +299,6 @@ uk: watched_categories: "Відслідковувані" tracked_categories: "Відстежувані" muted_categories: "Ігноровані" - muted_categories_instructions: "Ви не будете отримувати жодних сповіщень про нові теми у цих категоріях, і вони не з'являтимуться у вкладці Непрочитані." delete_account: "Delete My Account" delete_account_confirm: "Are you sure you want to permanently delete your account? This action cannot be undone!" deleted_yourself: "Your account has been deleted successfully." @@ -547,7 +546,6 @@ uk: edit_reason_placeholder: "чому Ви редагуєте допис?" show_edit_reason: "(додати причину редагування)" view_new_post: "Перегляньте свій новий допис." - saving: "Збереження..." saved: "Збережено!" uploading: "Завантаження..." show_preview: 'попередній перегляд »' @@ -572,8 +570,6 @@ uk: heading_title: "Заголовок" heading_text: "Заголовок" hr_title: "Горизонтальна лінія" - undo_title: "Скасувати" - redo_title: "Повернути" help: "Markdown Editing Help" toggler: "показати або сховати панель редагування" admin_options_title: "Необов'язкові налаштування персоналу для цієї теми" @@ -689,7 +685,6 @@ uk: title: "Ігнорувати" muted: title: "Ігнорувати" - description: "Ви ніколи не будете отримувати жодних сповіщень з цієї теми, і вона не буде відображатися у Вашій вкладці \"Непрочитані\"." actions: recover: "Відкликати видалення теми" delete: "Видалити тему" diff --git a/config/locales/client.zh_CN.yml b/config/locales/client.zh_CN.yml index 9f64ce6cd0..7082a69d00 100644 --- a/config/locales/client.zh_CN.yml +++ b/config/locales/client.zh_CN.yml @@ -388,7 +388,6 @@ zh_CN: tracked_categories: "已追踪" tracked_categories_instructions: "你将会自动追踪这些分类中的所有新主题。新帖数量将在每个主题后显示。" muted_categories: "已屏蔽" - muted_categories_instructions: "你不会收到这些分类的新主题的任何通知,他们也不会出现在你的未读标签中。" delete_account: "删除我的帐号" delete_account_confirm: "你真的要永久删除自己的账号吗?删除之后无法恢复!" deleted_yourself: "你的帐号已被成功删除。" @@ -751,7 +750,6 @@ zh_CN: show_edit_reason: "(添加编辑理由)" reply_placeholder: "正文。使用 Markdown、BBCode 或 HTML 格式化内容。拖拽或粘贴图片。" view_new_post: "浏览你的新帖子。" - saving: "保存中..." saved: "已保存!" saved_draft: "帖子还没写完,点击继续" uploading: "上传中..." @@ -778,8 +776,6 @@ zh_CN: heading_title: "标题" heading_text: "标题头" hr_title: "分割线" - undo_title: "撤销" - redo_title: "重做" help: "Markdown 编辑帮助" toggler: "隐藏或显示编辑面板" admin_options_title: "本主题可选设置" @@ -837,9 +833,7 @@ zh_CN: 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: "上传中" @@ -875,10 +869,7 @@ zh_CN: bulk: reset_read: "设为未读" delete: "删除主题" - dismiss_posts: "忽略帖子" - dismiss_posts_tooltip: "清除这些帖子的未读计数但当有新帖子时在我的未读列表中继续显示他们" dismiss_topics: "忽略主题" - dismiss_topics_tooltip: "停止当有新帖子时在我的未读列表中显示这些主题" dismiss_new: "设为已读" toggle: "切换批量选择" actions: "批量操作" @@ -1015,7 +1006,6 @@ zh_CN: description: "你不会收到关于此消息的任何通知。" muted: title: "防打扰" - description: "你不会收到关于此主题的任何通知,也不会在你的未阅选项卡中显示。" actions: recover: "撤销删除主题" delete: "删除主题" @@ -1387,7 +1377,6 @@ zh_CN: description: "如果某人@你或者回复你,你将收到通知。" muted: title: "免打扰" - description: "你不会收到这些分类的新主题的任何通知,他们也不会出现在你的未读标签中。" flagging: title: '感谢帮助社群远离邪恶!' private_reminder: '标记是不公开的,只有职员才可以见到' @@ -1439,7 +1428,6 @@ zh_CN: help: "主题已经解除置顶;它将以默认顺序显示" pinned_globally: title: "全局置顶" - help: "本主题已置顶;它将始终显示在它所属分类的顶部" pinned: title: "置顶" help: "本主题已置顶;它将始终显示在它所属分类的顶部" @@ -2311,9 +2299,7 @@ zh_CN: embed_username_key_from_feed: "从流中拉取 Discourse 用户名的 Key " embed_truncate: "截断嵌入的帖子" embed_whitelist_selector: "使用 CSS 选择器选择允许的嵌入元素" - whitelist_example: "article, #story, .post" embed_blacklist_selector: "使用 CSS 选择器移除嵌入元素" - blacklist_example: ".ad-unit, header" feed_polling_enabled: "通过RSS/ATOM导入帖子" feed_polling_url: "用于抓取的 RSS/ATOM 流的 URL" save: "保存嵌入设置" diff --git a/config/locales/client.zh_TW.yml b/config/locales/client.zh_TW.yml index 299ef0bd11..637a759f2e 100644 --- a/config/locales/client.zh_TW.yml +++ b/config/locales/client.zh_TW.yml @@ -339,7 +339,6 @@ zh_TW: watched_categories: "關注" tracked_categories: "追蹤" muted_categories: "靜音" - muted_categories_instructions: "你將不會收到此分類的新討論話題通知,以及不會出現在未讀欄內。" delete_account: "刪除我的帳號" delete_account_confirm: "你真的要刪除帳號嗎?此動作不能被還原!" deleted_yourself: "你的帳號已成功刪除" @@ -667,7 +666,6 @@ zh_TW: edit_reason_placeholder: "你為什麼做編輯?" show_edit_reason: "(請加入編輯原因)" view_new_post: "檢視你的新文章。" - saving: "正在儲存..." saved: "儲存完畢!" saved_draft: "草稿待完成,點擊繼續。" uploading: "正在上傳..." @@ -694,8 +692,6 @@ zh_TW: heading_title: "標頭" heading_text: "標頭" hr_title: "分隔線" - undo_title: "復原" - redo_title: "重做" help: "Markdown 編輯說明" toggler: "隱藏或顯示編輯面板" admin_options_title: "此討論話題可選用之工作人員設定選項" @@ -733,7 +729,6 @@ zh_TW: from_my_computer: "從我的電腦" from_the_web: "從網站" remote_tip: "圖片連結" - remote_tip_with_attachments: "圖片或文件連結 ({{authorized_extensions}})" hint: "(你也可以將檔案拖放至編輯器直接上傳)" uploading: "正在上傳" select_file: "選取檔案" @@ -755,10 +750,7 @@ zh_TW: bulk: reset_read: "重設閱讀" delete: "刪除討論話題" - dismiss_posts: "已讀文章" - dismiss_posts_tooltip: "標記此討論話題內未讀文章為已讀" dismiss_topics: "已讀討論話題" - dismiss_topics_tooltip: "停止顯示這個討論話題在我的未讀清單" dismiss_new: "設定新文章為已讀" toggle: "批量切換選擇討論話題" actions: "批量操作" @@ -880,7 +872,6 @@ zh_TW: description: "你將不會再收到關於此訊息的通知。" muted: title: "靜音" - description: "你將不會收到任何關於此討論話題的通知,此討論話題也不會出現在你的未讀分頁裡。" actions: recover: "復原已刪除的討論話題" delete: "刪除討論話題" @@ -1258,7 +1249,6 @@ zh_TW: help: "此討論話題已取消置頂,將會以預設順序顯示。" pinned_globally: title: "全區置頂" - help: "此討論話題已全區置頂,將顯示在所有討論話題列表的最上方" pinned: title: "已釘選" help: "此討論話題已置頂,將顯示在它所屬分類話題列表的最上方" diff --git a/config/locales/server.ar.yml b/config/locales/server.ar.yml index 47d1c6266c..5d03ac4cf3 100644 --- a/config/locales/server.ar.yml +++ b/config/locales/server.ar.yml @@ -21,7 +21,7 @@ ar: purge_reason: "حذف آلي للحسابات المهجوره وغير النشطة." disable_remote_images_download_reason: "لقد تم تعطيل تحميل الصور عن بعد بسبب عدم وجود مساحة كافية." anonymous: "مجهول." - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "إنها محددة بعدد حروف %{max} حرف; لقد أدخلت %{length}." @@ -276,6 +276,7 @@ ar: attributes: hex: invalid: "هذا اللون غير صالح" + <<: *errors user_profile: no_info_me: "
    مجال المعلومات عني لملف تعريفك فارغ حاليا، هل تريد أن تملأه؟
    " no_info_other: "
    %{name} لم يدخلوا أي شيء في مجال المعلومات عني لملفهم بعد
    " @@ -311,8 +312,6 @@ ar: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "عن الفئة %{category}." - replace_paragraph: "[استبدل هذا الفقرة الأولى بوصف قصير لفئتك الجديدة. سيظهر هذا التوجيه في منطقة اختيار الفئة, لذا حاول أن تبقيها أقل من 200 حرف. حتى عند تحريرك لهذا النص أو إنشائك لموضوع, هذه الفئة لن تظهر على صفحة الفئات.]" - post_template: "%{replace_paragraph}\n\nاستخدم الفقرات التالي لوصف طويل, إضافة لإنشاء أي فئة قواعد أو توجيهات.\n\nبعض الأشياء تؤخذ بعين الإعتبار في أسفل أي ردود لنقاش:\n\n- لما هذا الفئة؟لماذا يختار الناس هذه الفئة لمواضيعهم؟\n\n- كيف تختلف الفئات الأخرى عن التي لدينا؟\n\n- هل نحتاج هذه الفئة؟\n\n- هل يجب أن ندمج هذه مع فئة أخرى, أو تقسم إلى أكثر من قئة ؟\n" errors: uncategorized_parent: "غير مصنف لا يمكن أن يكون فئة الأم" self_parent: "الفئة الفرعية لا يمكن ان تكون كالفئة الرئيسية." @@ -885,7 +884,6 @@ ar: summary_likes_required: "الحد الأدنى للإعجابات في الموضوع قبل \"تلخيص هذا الموضوع\" مفعل." summary_percent_filter: "عندما يضغط المستخدم على \"تلخيص هذا الموضوع\"، يظهر أعلى % o المشاركات." summary_max_results: "الحد الأقصى للمشاركات العائدة بـ 'ملخص هذا الموضوع'" - enable_private_messages: "يسمح مستوى الثقة 1 للمستخدمين بإنشاء والرد على الرسائل" enable_long_polling: "ناقل الرسالة المستخدم للاشعارات يمكن أن يستخدم التصويت الطويل." long_polling_base_url: "قاعدة URL تستخدم للتصويت الطويل (عندما CDN يخدم المحتوى الديناميكي, تأكد لتعيين هذا لسحب الأصل) eg: http://origin.site.com" long_polling_interval: "المدة الزمنية التي سينتظرها الخادم قبل الرد على العملاء في حالة عدم وجود أية بيانات لارسالها (للأعضاء المسجلين فقط)" @@ -2026,9 +2024,7 @@ ar: تعديل محتويات المنشور الاول في هذا الموضوع %{page_name} page. guidelines_topic: title: "الأسئلة الشائعة/توجيهات" - body: "\n\n## [هذا مكان راقي للنقاشات العامة](#الراقي)\nالرجاء التعامل في هذا المنتدى بنفس الاحترام الذي يكون في حديقة عامة، نحن أيضًا مجتمع مشارك للمصدر و mdahs ؛ المكان هنا لتبادل المهارات والمعرفة والاهتمامات عبر الحوارات.\n\nهذه ليست شروط صارمة و سريعة، مجرد مساعده لحفظ حقوق الأشخاص في مجتمعنا، استخدام هذه المبادئ والتوجيهات يساعد في الحفاظ على الجتمع جيدًا للنقاشات الراقية.\n\n\n\n## [تحسين النقاشات](#تحسين)\n\nساعدنا على جعل هذا المكان جيد للمناقشة، من خلال العمل الدائم لتحسين المناقشات ببعض الطرق، مهما كانت صغيرة، اذا لم تكن متأكدًا أن ما تكتبه سيضيف قيمة، فكر فيما ستكتبه وحاول مرة أخرى في وقت لاحق.\n\nالموضوعات التي تتم مناقشتها هنا مهمة بالنسبة لنا، ونريد منك أن تناقشها كما لو أنها مهمة بالنسبة لك، احترم الموضوعات والاشخاص، حتى لو لم تكن متفقًا مع بعض ما يقال.\n\nأحد طرق تحسين النقاش هو اكتشاف ما يجري، يرجى قضاء بعض الوقت في تصفح المواضيع هنا قبل الرد أو نشر موضوعك، لتكون لديك فرصة افضل في تلبية حاجات الآخرين اللذين يشاركونك اهتماماتك.\n\n\n\n## [تقبل الآخرين، حتى لو كنت غير متفق](#تقبل)\n\nقد ترغب في الرد على من اختلفت معهم، هذا جيد/ ولكن تذكر، انتقد الافكار وليس الأشخاص، يرجى تجنب :\n\n* الاهانة.\n* Ad hominem attacks.\n* الرد على اسلوب المنشور بدلا من المضمون الفعلي.\n* لا تحتسب المتناقضات.\nبدلا من ذلك، وفر الأدلة البينة التي تعمل على تحسين المحادثة.\n\n\n\n## [مشاركاتكم](#شارك)\n\nالمحادثات التي تكون لدينا متناغمة مع الجميع، ساعدونا في التأثير على مستقبل المجتمع، عن طريق مناقشة ما يجعل لهذا المنتدى أهمية و mdash ؛ وتجنب غير ذلك.\n\nيوفر النقاش\ - \ الأدوات التي تمكن الجميع من معرفة أفضل (واسوأ) المشاركات: كالمفضلة، العلامات المرجعية، الاعجابات، البلاغات، الردود، التعديلات، وما الى ذلك. استخدمها لتحسين تجربة الجميع.\nدعونا نحاول ترك المكان أفضل مما كان.\n\n\n\n## [اذا رأيت مشكلة، بلّغ عنها ](#الابلاغ-عن-المشاكل)\n\nالمشرفون لديهم سلطة خاصة، وهم مسؤولون عن هذا المنتدى، ولكن حتى أنتم بمساعدتكم، يستطيع المشرفون تسيير المجتمع، ليس عمال النظافة أو الشرطة.\n\nعندما ترى سلوك سيئ، لا ترد عليه، وتشجع السلوك السيئ بالاعتراف به، وتستهلك طاقتك، قم بالإبلاغ عنه، اذا وصلت بلاغات بما فيه الكفاية، سيتم اتخاذ الإجراءات اللازمة، اما تلقائيا، أو عن طريق مشرف.\n\nمن أجل الحفاظ على سلامة المجتمع، المشرفين لديهم الحق في إزالة اي محتوى أو حذف أي حساب لأي سبب في اي وقت، المشرفون لا يتابعون جميع المنشورات الجديدة بأي شكل كان، المشرفون ومشغلوا الموقع لا يتحملون أية مسؤولية عن اي محتو يتم نشره بواسطة المجتمع.\n\n\n\n## [دائما كن محترما](#محترم)\n\nلا شيء يخرب المحادثة الجيدة، مثل الوقاحة:\n\n* كم محترمًا، لا تنشر أي شيء تهجمي، أو خطاب كراهية.\n* ابق المجتمع نظيفا، لا تنشر أي شيء فاحش أو جنسي صريح.\n* احترم الآخرين، لا تضايق أو تحزن شخص، لا تنتحل شخصية أحد آخر، أو تنشر معلوماتهم الخاصة.\n* احترم منتدانا، لا تعمل ازعاجا - spam - أو تخرب أو خلاف ذك في المنتدى.\n\nهذه المصطلحات ليست محددة مع تعريف دقيق و mdahs ؛ عليك تجنب ظهور اي من هذه الأشياء. اذا كنت غير مقتنع، أسال نفسك ما ذا سيكون شعورك اذا نشرت على الصفحة الاولى في صحيفة نيويورك تايمز.\nهذا منتدى عام، ومؤشرات محركات البحث تحتوي هذه النقاشات، حافظ على اللغة، الروابط والصور الآمنة للعائلة والاصدقاء.\n\n\n\ - \n## [حافظ عليه مرتبا](#المحافظة-على-الترتيب)\n\nأبذل مزيدا من الجهد في وضع الأمور في مكانها المناسب، حتى نتمكن من قضاء المزيد من الوقت في المناقشات ونقلل من التنظيف، هكذا:\n\n* لا تبدأ موضوع في قسم غير مناسب.\n* لا تنشر نفس المشاركة في مواضيع متعددة.\n* لا ترد ردودا دون محتوى مناسب.\n* لا تحول مسار الموضوع من المنتصف. \n* لا توقع مشاركاتك أو mdash؛ كل منشوراتك مرتبطة بمعلومات ملفك الشخصي.\n\nبدلا من كتابة \"+1\" أو كتابة \" نتفق عليه \"، استخدم زر أعجبني، من أخذ المواضيع لمواضيع مختلفة جذريا، استخدم ردا برابط الموضوع مرتبط .\n\n\n\n## [انشر فقط شيء تملكه](#سرقة)\nلا تستيطع نشر أي شيء رقمي يملكه شخص آخر دون إذن، لا تستطيع نشر وصف، رابط ، أو سرقة ممتلكات شخص ما الفكرية(البرامج والفيديو والصوت والصور)، أو انتهاك اي قانون آخر.\n\n\n\n## [بدعم منك](#دعم)\n\nيتم تشغيل هذا الموقع من قِبل [friendly local staff](/about) وأنت، و المجتمع، إذا كان لديك اي أسئلة أخرى حول كيف تعمل الأشياء هنا، افتح موضوع جديد في [site feedback category](/c/site-feedback)وأُدعنا للمناقشة! إذا كان هناك أي قضية حرجة أو حاجة ماسة لم يتم التعامل معها بموضوع ميت أو أو بلاغ، اتصل بنا عبر [staff page] (/about).\n\n\n\n## [شروط الخدمة](#شروط-الخدمة)\n\nنعم، الكلام القانوني ممل، ولكن يجب أن نحمي أنفسنا و ndahs ؛ من الاشخاص الغير ودودين، لدينا [Terms of Service](/tos) وصف لك (ولنا) السلوك والحقوق ذات الصلة بالمحتوى والخصوصية، لاستخدام هذه الخدمة، يجب أن توافق على التزامك بالشروط والقوانين[TOS](/tos).\n" + body: "\n\n## [هذا مكان راقي للنقاشات العامة](#الراقي)\nالرجاء التعامل في هذا المنتدى بنفس الاحترام الذي يكون في حديقة عامة، نحن أيضًا مجتمع مشارك للمصدر و mdahs ؛ المكان هنا لتبادل المهارات والمعرفة والاهتمامات عبر الحوارات.\n\nهذه ليست شروط صارمة و سريعة، مجرد مساعده لحفظ حقوق الأشخاص في مجتمعنا، استخدام هذه المبادئ والتوجيهات يساعد في الحفاظ على الجتمع جيدًا للنقاشات الراقية.\n\n\n\n## [تحسين النقاشات](#تحسين)\n\nساعدنا على جعل هذا المكان جيد للمناقشة، من خلال العمل الدائم لتحسين المناقشات ببعض الطرق، مهما كانت صغيرة، اذا لم تكن متأكدًا أن ما تكتبه سيضيف قيمة، فكر فيما ستكتبه وحاول مرة أخرى في وقت لاحق.\n\nالموضوعات التي تتم مناقشتها هنا مهمة بالنسبة لنا، ونريد منك أن تناقشها كما لو أنها مهمة بالنسبة لك، احترم الموضوعات والاشخاص، حتى لو لم تكن متفقًا مع بعض ما يقال.\n\nأحد طرق تحسين النقاش هو اكتشاف ما يجري، يرجى قضاء بعض الوقت في تصفح المواضيع هنا قبل الرد أو نشر موضوعك، لتكون لديك فرصة افضل في تلبية حاجات الآخرين اللذين يشاركونك اهتماماتك.\n\n\n\n## [تقبل الآخرين، حتى لو كنت غير متفق](#تقبل)\n\nقد ترغب في الرد على من اختلفت معهم، هذا جيد/ ولكن تذكر، انتقد الافكار وليس الأشخاص، يرجى تجنب :\n\n* الاهانة.\n* Ad hominem attacks.\n* الرد على اسلوب المنشور بدلا من المضمون الفعلي.\n* لا تحتسب المتناقضات.\nبدلا من ذلك، وفر الأدلة البينة التي تعمل على تحسين المحادثة.\n\n\n\n## [مشاركاتكم](#شارك)\n\nالمحادثات التي تكون لدينا متناغمة مع الجميع، ساعدونا في التأثير على مستقبل المجتمع، عن طريق مناقشة ما يجعل لهذا المنتدى أهمية و mdash ؛ وتجنب غير ذلك.\n\nيوفر النقاش الأدوات التي تمكن الجميع من معرفة أفضل (واسوأ) المشاركات: كالمفضلة، العلامات المرجعية، الاعجابات، البلاغات، الردود، التعديلات، وما الى ذلك. استخدمها لتحسين تجربة الجميع.\nدعونا نحاول ترك المكان أفضل مما كان.\n\n\n\n## [اذا رأيت مشكلة، بلّغ عنها ](#الابلاغ-عن-المشاكل)\n\nالمشرفون لديهم سلطة خاصة، وهم مسؤولون عن هذا المنتدى، ولكن حتى أنتم بمساعدتكم، يستطيع المشرفون تسيير المجتمع، ليس عمال النظافة أو الشرطة.\n\nعندما ترى سلوك سيئ، لا ترد عليه، وتشجع السلوك السيئ بالاعتراف به، وتستهلك طاقتك، قم بالإبلاغ عنه، اذا وصلت بلاغات بما فيه الكفاية، سيتم اتخاذ الإجراءات اللازمة، اما تلقائيا، أو عن طريق مشرف.\n\nمن أجل الحفاظ على سلامة المجتمع، المشرفين لديهم الحق في إزالة اي محتوى أو حذف أي حساب لأي سبب في اي وقت، المشرفون لا يتابعون جميع المنشورات الجديدة بأي شكل كان، المشرفون ومشغلوا الموقع لا يتحملون أية مسؤولية عن اي محتو يتم نشره بواسطة المجتمع.\n\n\n\n## [دائما كن محترما](#محترم)\n\nلا شيء يخرب المحادثة الجيدة، مثل الوقاحة:\n\n* كم محترمًا، لا تنشر أي شيء تهجمي، أو خطاب كراهية.\n* ابق المجتمع نظيفا، لا تنشر أي شيء فاحش أو جنسي صريح.\n* احترم الآخرين، لا تضايق أو تحزن شخص، لا تنتحل شخصية أحد آخر، أو تنشر معلوماتهم الخاصة.\n* احترم منتدانا، لا تعمل ازعاجا - spam - أو تخرب أو خلاف ذك في المنتدى.\n\nهذه المصطلحات ليست محددة مع تعريف دقيق و mdahs ؛ عليك تجنب ظهور اي من هذه الأشياء. اذا كنت غير مقتنع، أسال نفسك ما ذا سيكون شعورك اذا نشرت على الصفحة الاولى في صحيفة نيويورك تايمز.\nهذا منتدى عام، ومؤشرات محركات البحث تحتوي هذه النقاشات، حافظ على اللغة، الروابط والصور الآمنة للعائلة والاصدقاء.\n\n\n\n## [حافظ عليه مرتبا](#المحافظة-على-الترتيب)\n\nأبذل مزيدا من الجهد في وضع الأمور في مكانها المناسب، حتى نتمكن من قضاء المزيد من الوقت في المناقشات ونقلل من التنظيف، هكذا:\n\n* لا تبدأ موضوع في قسم غير مناسب.\n* لا تنشر نفس المشاركة في مواضيع متعددة.\n* لا ترد ردودا دون محتوى مناسب.\n* لا تحول مسار الموضوع من المنتصف. \n* لا توقع مشاركاتك أو mdash؛ كل منشوراتك مرتبطة بمعلومات ملفك الشخصي.\n\nبدلا من كتابة \"+1\" أو كتابة \" نتفق عليه \"، استخدم زر أعجبني، من أخذ المواضيع لمواضيع مختلفة جذريا، استخدم ردا برابط الموضوع مرتبط .\n\n\n\n## [انشر فقط شيء تملكه](#سرقة)\nلا تستيطع نشر أي شيء رقمي يملكه شخص آخر دون إذن، لا تستطيع نشر وصف، رابط ، أو سرقة ممتلكات شخص ما الفكرية(البرامج والفيديو والصوت والصور)، أو انتهاك اي قانون آخر.\n\n\n\n## [بدعم منك](#دعم)\n\nيتم تشغيل هذا الموقع من قِبل [friendly local staff](/about) وأنت، و المجتمع، إذا كان لديك اي أسئلة أخرى حول كيف تعمل الأشياء هنا، افتح موضوع جديد في [site feedback category](/c/site-feedback)وأُدعنا للمناقشة! إذا كان هناك أي قضية حرجة أو حاجة ماسة لم يتم التعامل معها بموضوع ميت أو أو بلاغ، اتصل بنا عبر [staff page] (/about).\n\n\n\n## [شروط الخدمة](#شروط-الخدمة)\n\nنعم، الكلام القانوني ممل، ولكن يجب أن نحمي أنفسنا و ndahs ؛ من الاشخاص الغير ودودين، لدينا [Terms of Service](/tos) وصف لك (ولنا) السلوك والحقوق ذات الصلة بالمحتوى والخصوصية، لاستخدام هذه الخدمة، يجب أن توافق على التزامك بالشروط والقوانين[TOS](/tos).\n" tos_topic: title: "شروط الخدمة" body: | @@ -2168,9 +2164,7 @@ ar: متأقلم أصلا مع [ شروط خدمة WordPress](http://en.wordpress.com/tos/). privacy_topic: title: "سياسة الخصوصية" - body: "\n\n## [ما هي البيانات التي نقوم بجمعها؟](#جمع)\n\nنحن نجمع معلومات عنك عندما تسجل في موقعنا، وعندما تشارك في المنتدى عن طريق القراءة أو الكتابة، ونقوم بتقييم ما تم مشاركته هنا .\n\n\nيمكنك زيارة موقعنا بدون تسجيل، ولكن عند التسجيل في موقعنا، سيطلب منك ادخال اسمك وعنوان بريدك الالكتروني، وسيتم التحقق من بريدك الالكتروني بإرسال رسالة الى بريدك الالكتروني تحتوي على رابط خاص، عند الضغط على هذا الرابط، نحن سنعرف أنك مالك البريد الالكتروني المتحكم فيه.\n\nعندما تقوم بالتسجيل في موقعنا والنشر، سنقوم بتسجيل عنوان IP الذي نشرت منه، أيضا قد تحتفظ سجلات الخادم عناوين IP جميع الطلبات من الخادم.\n\n\n\n## [في ماذا نستخدم المعلومات الخاصة بك؟](#استخدام)\n\nيمكننا استخدام المعلومات التي نجمعها عنك بإحدى الطرق التالية:\n\n* لتخصيص تجربتك و mdahs؛ المعلومات الخاصة بك تساعدنا على الاستجابة بشكل أفضل لاحتياجاتك الفردية.\n* لتحسين موقعنا و mdash ؛ نسعى باستمرار لتحسين ما يعرضه الموقع استنادًا الى المعلومات والتغذية الراجعة - الملاحظات - التي نتلقاها منك.\n* لتحسين خدمة العملاء و mdash ؛ المعلومات الخاصة بك تساعدنا على الاستجابة بشكل أكثر فعالية لطلبات الدعم وخدمة العملاء.\n* لإرسال رسائل البريد الالكتروني الدورية و mdash ؛ سنستخدم عنوان البريد الالكتروني الذي وفرته لنا لإرسال معلومات إليك، الاشعارات التي تطلبها حول التحديثات في المواضيع، أو الاستجابة لاسم المستخدم الخاص بك، كالرد على الاستفسارات، او الطلبات أو اسئلة اخرى.\n\n\n\n## [كيف نقوم بحماية معلوماتك ؟](#حماية)\n\nنقوم بتطبيق مجموعة من الإجراءات الأمنية للمحافظة على أمن وسلامة معلوماتك الشخصية، عندما تقوم بإرسال أو إدخال أو الدخول لمعلوماتك الشخصية.\n\ - \n\n\n## [ما هي سياسة الاحتفاظ بالبيانات الخاصة بك ؟](#الاحتفاظ-بالبيانات)\n\nسوف نبذل جهونا بإخلاص للتالي :\n\n* الاحتفاظ بسجلات عناوين IP لجميع الطلبات لهذا الخادم لمدة لا تزيد عن 90 يومًا.\n* الاحتفاظ بعناوين IP الخاصة بالمستخدمين المسجلين ومنشوراتهم لمدة لا تزيد عن 5 سنوات.\n\n\n\n## [هل نستخدم الكعكات - cookies - ملفات تعريف الارتباط ؟ ](#كعكات)\n\nنعم، الكعكات هي عبارة عن ملفات صغيرة يقوم الموقع أو مزود الخدمة بنقلها الى القرص الصلب لحاسبك من خلال متصفحك (اذا سمحتم بذلك)، هذه الكعكات تعرف الموقع على متصفحك، فن كان لديك حساب مسجل، سيتم ربطه مع حسابك.\n\nنحن نستخدم ملفات تعريف الارتباط - cookies - لفهم وحفظ التفضيلات الخاصة بك للزيارات في المستقبل، وجمع البيانات العامة حول حركة المرور والتفاعل في الموقع حتى نتمكن من تقديم تجربة وأدوات افضل في المستقبل، نحن قد نتعاقد مع مقدمي خدمات من الطرف الثالث لمساعدتنا في تحسين فهمنا لزوار الموقع، مقدمي الخدمات لا يسمح لهم بإستخدام المعلومات التي تم جمعها نيابة عنا، إلّا لمساعدتنا في سلوكنا وتحسين أعمالنا.\n\n\n\n## [هل نقوم بالإفصاح عن أي معلومات لأطراف خارجية؟](#إفصاح)\n\nنحن لا نبيع، ولا نتاجر أو ننقل المعلومات الشخصية الى أطراف خارجية. وهذا لا يشمل الطرف الخاجية الموثوق بها والتي تساعد في تشغيل موقعنا، واجراء أعمالنا، أو تقديم الخدمات لكم، طالما أن تلك الأطراف موافقة للحفاظ على سرية المعلومات، يجوز لنا الافراج عن معوماتك الشخصية عندما نرى أنه هو المناسب للإمتثال للقانون، مع فرض سياسة موقعنا، أو حماية حقوقنا أو حقوق الآخرين، أو حقوق الملكية، أو السلامة. ومع ذلك، يمكننا تقديم معلومات الزائرين دون تحديد الهوية، الى أطراف أخرى للتسويق والاعلان،\ - \ أو غيرها من الاستخدامات.\n\n\n\n## [روابط الطرف الثالث](#الطرف-الثالث)\n\nأحيانًا، نفترض، أنه عند وجود مواقع طرف ثالث تقجم خدمات أو منتجات على موقعنا، كان لدى مواقع الطرف الثالث هذه، سياسات خصوصية منفصلة ومستقلة، لن يكون لدينا أية مسؤولية عن محتوى وأنشطة هذه المواقع المرتبطة، ومع ذلك، نحن نسعى إلى حماية موقعنا وسلامته، ونرحب بأي ملاحظات حول هذه المواقع. \n\n\n\n## [الالتزام بقانون حماية خصوصية الأطفال على الانترنت ](#coppa)\n\nموقعنا والمنتجات والخدمات موجهه للأشخاص اللذين لا تقل أعمارهم عن 13 سنة، إذا كان هذا الخادم في الولايات المتحدة الأمريكية، من شروط COPPA\n ([Children's Online Privacy Protection Act](https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act))\nعدم استخدم هذا الموقع.\n\n\n\n## [سياسة الخصوصية على الانترنت](#متصل)\n\nتنطبق سياسة الخصوصية على الانترنت فقط على المعلومات التي يتم جمعها من خلال موقعنا، ولاتنطبق على المعلومات التي يتم جمعها أثناء عدم الاتصال.\n\n\n\n## [الموافقة](#الموافقة)\n\nبإستخدام موقعنا، أنت توافق على سياسة الخصوصية لموقعنا.\n\n\n\n## [تغييرات على سياسة الخصوصية](#تغييرات)\n\nإذا قمنا بتغيير سياسة الخصوصية، سوف نقوم بنشر هذه التغييرات في هذه الصفحة.\n\nهذه الوثيقة هي نسخة من CC-BY-SA تم تحديثها في 31 مايو عام 2013م .\n" + body: "\n\n## [ما هي البيانات التي نقوم بجمعها؟](#جمع)\n\nنحن نجمع معلومات عنك عندما تسجل في موقعنا، وعندما تشارك في المنتدى عن طريق القراءة أو الكتابة، ونقوم بتقييم ما تم مشاركته هنا .\n\n\nيمكنك زيارة موقعنا بدون تسجيل، ولكن عند التسجيل في موقعنا، سيطلب منك ادخال اسمك وعنوان بريدك الالكتروني، وسيتم التحقق من بريدك الالكتروني بإرسال رسالة الى بريدك الالكتروني تحتوي على رابط خاص، عند الضغط على هذا الرابط، نحن سنعرف أنك مالك البريد الالكتروني المتحكم فيه.\n\nعندما تقوم بالتسجيل في موقعنا والنشر، سنقوم بتسجيل عنوان IP الذي نشرت منه، أيضا قد تحتفظ سجلات الخادم عناوين IP جميع الطلبات من الخادم.\n\n\n\n## [في ماذا نستخدم المعلومات الخاصة بك؟](#استخدام)\n\nيمكننا استخدام المعلومات التي نجمعها عنك بإحدى الطرق التالية:\n\n* لتخصيص تجربتك و mdahs؛ المعلومات الخاصة بك تساعدنا على الاستجابة بشكل أفضل لاحتياجاتك الفردية.\n* لتحسين موقعنا و mdash ؛ نسعى باستمرار لتحسين ما يعرضه الموقع استنادًا الى المعلومات والتغذية الراجعة - الملاحظات - التي نتلقاها منك.\n* لتحسين خدمة العملاء و mdash ؛ المعلومات الخاصة بك تساعدنا على الاستجابة بشكل أكثر فعالية لطلبات الدعم وخدمة العملاء.\n* لإرسال رسائل البريد الالكتروني الدورية و mdash ؛ سنستخدم عنوان البريد الالكتروني الذي وفرته لنا لإرسال معلومات إليك، الاشعارات التي تطلبها حول التحديثات في المواضيع، أو الاستجابة لاسم المستخدم الخاص بك، كالرد على الاستفسارات، او الطلبات أو اسئلة اخرى.\n\n\n\n## [كيف نقوم بحماية معلوماتك ؟](#حماية)\n\nنقوم بتطبيق مجموعة من الإجراءات الأمنية للمحافظة على أمن وسلامة معلوماتك الشخصية، عندما تقوم بإرسال أو إدخال أو الدخول لمعلوماتك الشخصية.\n\n\n\n## [ما هي سياسة الاحتفاظ بالبيانات الخاصة بك ؟](#الاحتفاظ-بالبيانات)\n\nسوف نبذل جهونا بإخلاص للتالي :\n\n* الاحتفاظ بسجلات عناوين IP لجميع الطلبات لهذا الخادم لمدة لا تزيد عن 90 يومًا.\n* الاحتفاظ بعناوين IP الخاصة بالمستخدمين المسجلين ومنشوراتهم لمدة لا تزيد عن 5 سنوات.\n\n\n\n## [هل نستخدم الكعكات - cookies - ملفات تعريف الارتباط ؟ ](#كعكات)\n\nنعم، الكعكات هي عبارة عن ملفات صغيرة يقوم الموقع أو مزود الخدمة بنقلها الى القرص الصلب لحاسبك من خلال متصفحك (اذا سمحتم بذلك)، هذه الكعكات تعرف الموقع على متصفحك، فن كان لديك حساب مسجل، سيتم ربطه مع حسابك.\n\nنحن نستخدم ملفات تعريف الارتباط - cookies - لفهم وحفظ التفضيلات الخاصة بك للزيارات في المستقبل، وجمع البيانات العامة حول حركة المرور والتفاعل في الموقع حتى نتمكن من تقديم تجربة وأدوات افضل في المستقبل، نحن قد نتعاقد مع مقدمي خدمات من الطرف الثالث لمساعدتنا في تحسين فهمنا لزوار الموقع، مقدمي الخدمات لا يسمح لهم بإستخدام المعلومات التي تم جمعها نيابة عنا، إلّا لمساعدتنا في سلوكنا وتحسين أعمالنا.\n\n\n\n## [هل نقوم بالإفصاح عن أي معلومات لأطراف خارجية؟](#إفصاح)\n\nنحن لا نبيع، ولا نتاجر أو ننقل المعلومات الشخصية الى أطراف خارجية. وهذا لا يشمل الطرف الخاجية الموثوق بها والتي تساعد في تشغيل موقعنا، واجراء أعمالنا، أو تقديم الخدمات لكم، طالما أن تلك الأطراف موافقة للحفاظ على سرية المعلومات، يجوز لنا الافراج عن معوماتك الشخصية عندما نرى أنه هو المناسب للإمتثال للقانون، مع فرض سياسة موقعنا، أو حماية حقوقنا أو حقوق الآخرين، أو حقوق الملكية، أو السلامة. ومع ذلك، يمكننا تقديم معلومات الزائرين دون تحديد الهوية، الى أطراف أخرى للتسويق والاعلان، أو غيرها من الاستخدامات.\n\n\n\n## [روابط الطرف الثالث](#الطرف-الثالث)\n\nأحيانًا، نفترض، أنه عند وجود مواقع طرف ثالث تقجم خدمات أو منتجات على موقعنا، كان لدى مواقع الطرف الثالث هذه، سياسات خصوصية منفصلة ومستقلة، لن يكون لدينا أية مسؤولية عن محتوى وأنشطة هذه المواقع المرتبطة، ومع ذلك، نحن نسعى إلى حماية موقعنا وسلامته، ونرحب بأي ملاحظات حول هذه المواقع. \n\n\n\n## [الالتزام بقانون حماية خصوصية الأطفال على الانترنت ](#coppa)\n\nموقعنا والمنتجات والخدمات موجهه للأشخاص اللذين لا تقل أعمارهم عن 13 سنة، إذا كان هذا الخادم في الولايات المتحدة الأمريكية، من شروط COPPA\n ([Children's Online Privacy Protection Act](https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act))\nعدم استخدم هذا الموقع.\n\n\n\n## [سياسة الخصوصية على الانترنت](#متصل)\n\nتنطبق سياسة الخصوصية على الانترنت فقط على المعلومات التي يتم جمعها من خلال موقعنا، ولاتنطبق على المعلومات التي يتم جمعها أثناء عدم الاتصال.\n\n\n\n## [الموافقة](#الموافقة)\n\nبإستخدام موقعنا، أنت توافق على سياسة الخصوصية لموقعنا.\n\n\n\n## [تغييرات على سياسة الخصوصية](#تغييرات)\n\nإذا قمنا بتغيير سياسة الخصوصية، سوف نقوم بنشر هذه التغييرات في هذه الصفحة.\n\nهذه الوثيقة هي نسخة من CC-BY-SA تم تحديثها في 31 مايو عام 2013م .\n" static: search_help: |

    نصائح

    @@ -2258,3 +2252,6 @@ ar: performance_report: initial_post_raw: 'هذا الموضوع يحتوي على معلومات الاداء اليومي للموقع ' initial_topic_title: التبليغ عن اداء الموقع + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.bs_BA.yml b/config/locales/server.bs_BA.yml index af53526909..9117ebda29 100644 --- a/config/locales/server.bs_BA.yml +++ b/config/locales/server.bs_BA.yml @@ -20,7 +20,7 @@ bs_BA: is_reserved: "is reserved" purge_reason: "Automatically deleted due to being old and unverified" disable_remote_images_download_reason: "Remote images download was disabled because there wasn't enough disk space available." - errors: + errors: &errors messages: too_long_validation: "is limited to %{max} characters; you entered %{length}." invalid_boolean: "Invalid boolean." @@ -169,6 +169,7 @@ bs_BA: attributes: hex: invalid: "is not a valid color" + <<: *errors user_profile: no_info_me: "
    the About Me field of your profile is currently blank, would you like to fill it out?
    " no_info_other: "
    %{name} hasn't entered anything in the About Me field of their profile yet
    " @@ -203,8 +204,6 @@ bs_BA: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "About the %{category} category" - replace_paragraph: "[Replace this first paragraph with a short description of your new category. This guidance will appear in the category selection area, so try to keep it below 200 characters. Until you edit this text or create topics, this category won't appear on the categories page.]" - post_template: "%{replace_paragraph}\n\nUse the following paragraphs for a longer description, as well as to establish any category guidelines or rules.\n\nSome things to consider in any discussion replies below:\n\n- What is this category for? Why should people select this category for their topic?\n\n- How is this different than the other categories we already have?\n\n- Do we need this category?\n\n- Should we merge this with another category, or split it into more categories?\n" errors: uncategorized_parent: "Uncategorized can't have a parent category" self_parent: "A subcategory's parent cannot be itself" @@ -500,7 +499,6 @@ bs_BA: summary_posts_required: "Minimum posts in a topic before 'Summarize This Topic' is enabled" summary_likes_required: "Minimum likes in a topic before 'Summarize This Topic' is enabled" summary_percent_filter: "When a user clicks 'Summarize This Topic', show the top % of posts" - enable_private_messages: "Allow trust level 1 users to create private messages and reply to private messages" enable_long_polling: "Message bus used for notification can use long polling" long_polling_interval: "Interval before a new long poll is issued in milliseconds " polling_interval: "How often should logged in user clients poll in milliseconds" @@ -1283,3 +1281,6 @@ bs_BA: title: "Terms of Service" privacy_topic: title: "Privacy Policy" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.cs.yml b/config/locales/server.cs.yml index 450f54f9cb..d7d23dc290 100644 --- a/config/locales/server.cs.yml +++ b/config/locales/server.cs.yml @@ -20,7 +20,7 @@ cs: is_reserved: "je rezervováno" disable_remote_images_download_reason: "Stahování obrázků z cizích serverů bylo vypnuto protože na disku není dostatek místa." anonymous: "Anonymní" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "je limitováno na %{max} znaků; zadali jste %{length}." @@ -212,6 +212,7 @@ cs: attributes: hex: invalid: "není platná barva" + <<: *errors user_profile: no_info_me: "
    Pole 'o mně' je v tuto chvíli prázdné, nechcete si ho vyplnit?
    " no_info_other: "
    %{name} o sobě zatím žádné informace nevyplnil
    " @@ -225,8 +226,6 @@ cs: title: "Vítejte v Redakci" category: topic_prefix: "Definice kategorie pro %{category}" - replace_paragraph: "[Nahraďte tento první odstavec krátkých popisem nové kategorie. Zkuste se vejít do 200 znaků.]" - post_template: "%{replace_paragraph}\\\n\\\nPoužijte toto místo níže pro delší popis a stanovení pravidel diskuze!\n" errors: uncategorized_parent: "„Bez kategorie“ nemůže mít nadřazenou kategorii" self_parent: "Nadřazená kategorie nemůže zároveň být podkategorie" @@ -900,3 +899,6 @@ cs: title: "Podmínky používání" privacy_topic: title: "Ochrana soukromí" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.da.yml b/config/locales/server.da.yml index 60cb7ee897..32533f07fb 100644 --- a/config/locales/server.da.yml +++ b/config/locales/server.da.yml @@ -21,7 +21,7 @@ da: purge_reason: "Automatisk slettet som forladt, ikke aktiveret, konto" disable_remote_images_download_reason: "Fjerndownload af billeder deaktiveret grundet utilstrækkelig diskplads" anonymous: "Anonym" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "er begrænset til %{max} tegn; du har brugt %{length}." @@ -233,6 +233,7 @@ da: attributes: hex: invalid: "er ikke en gyldig fave" + <<: *errors user_profile: no_info_me: "
    “Om mig” feltet på din profil er pt. tomt, ønsker du at udfylde det?
    " no_info_other: "
    %{name} har ikke skrevet noget i “Om mig”-feltet endnu
    " @@ -246,8 +247,6 @@ da: title: "Velkommen i loungen" category: topic_prefix: "Kategoridefinition for %{category}" - replace_paragraph: "[Erstat det første afsnit med en kort beskrivelse af din nye kategori. Denne tekst vises i området til valg af kategori, så prøv at holde den på under 200 tegn. Indtil du redigerer denne tekst eller opretter emner vil denne kategori ikke optræde på kategorisiden.]" - post_template: "%{replace_paragraph}\n\nBrug de følgende afsnit til en længere beskrivelse samt til at fastlægge retningslinjer eller regler for kategorien.\n\nNogle ting som du kan overveje i svarene nedenfor:\n\n- Hvad er kategorien beregnet til? Hvorfor skal folk vælge denne kategori til deres emne?\n\n- Hvordan er den anderledes end de andre kategorier vi allerede har?\n\n- Har vi behov for denne kategori?\n\n- Skal vi kombinere denne kategori med en anden kategori eller dele den op i flere kategorier?\n" errors: uncategorized_parent: "Ukategoriserede kan ikke have en overordnede kategori" self_parent: "En underkategori kan ikke være sin egen overordnede kategori." @@ -718,6 +717,8 @@ da: most_posts: "Flest indlæg" most_recent_poster: "Seneste forfatter" frequent_poster: "Hyppig forfatter" + redirected_to_top_reasons: + new_user: "Velkommen til fællesskabet! Dette er de seneste mest populære emner." topic_statuses: archived_enabled: "Dette emne er nu arkiveret. Det er frosset fast og kan ikke ændres på nogen måde." archived_disabled: "Dette emne er nu ikke længere arkiveret. Det er ikke længere frosset fast, og kan ændres." @@ -939,3 +940,6 @@ da: error: "Fejl!" email_input: "Admin email" submit_button: "Send email" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml index 5d08d72792..b0a81f4d3c 100644 --- a/config/locales/server.de.yml +++ b/config/locales/server.de.yml @@ -21,7 +21,7 @@ de: purge_reason: "Stillgelegtes, nicht aktives Konto wurde automatisch gelöscht." disable_remote_images_download_reason: "Der Download von Bildern wurde deaktiviert, weil nicht mehr genug Plattenplatz vorhanden war." anonymous: "Anonym" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "darf höchstens %{max} Zeichen lang sein; du hast %{length} eingegeben." @@ -249,6 +249,7 @@ de: attributes: hex: invalid: "ist keine gültige Farbe" + <<: *errors user_profile: no_info_me: "
    Das 'Über mich'-Feld deines Profils ist aktuell leer, möchtest du es ausfüllen?
    " no_info_other: "
    %{name} hat noch nichts in das 'Über mich'-Feld des Nutzerprofils eingetragen
    " @@ -264,8 +265,6 @@ de: body: "\nGratuliere! :confetti_ball:\n\nWenn du dieses Thema sehen kannst, wurdest du vor Kurzem zum **Stammgast** (Vertrauensstufe 3) befördert.\n \nDu kannst nun …\n\n* den Titel eines jeden Themas ändern\n* Themen in andere Kategorien verschieben\n* Links veröffentlichen, die von Suchmaschinen weiterverfolgt werden (das automatische [nofollow](http://de.wikipedia.org/wiki/Nofollow) wird entfernt)\n* auf die private Lounge-Kategorie zugreifen, die für Benutzer mit Vertrauensstufe 3 oder höher sichtbar ist\n\nHier ist die [aktuelle Liste aller Stammgäste](/badges/3/regular). Vergiss nicht, hallo zu sagen!\n\nVielen Dank dafür, dass du ein wichtiger Teil dieser Community bist!\n\n(Wenn du mehr über Vertrauensstufen wissen möchtest, kannst du [dieses Thema lesen][trust]. Beachte bitte, dass nur jene Mitglieder Stammgäste bleiben, die auch im Laufe der Zeit die Anforderungen erfüllen.)\n\n[trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924\n" category: topic_prefix: "Über die Kategorie %{category}" - replace_paragraph: "[Ersetze den ersten Absatz mit einer kurzen Beschreibung deiner neuen Kategorie. Bitte benutze weniger als 200 Zeichen.]" - post_template: "%{replace_paragraph}\n\nBenutze den folgenden Platz für eine ausführliche Beschreibung sowie für Regeln und zur Diskussion!" errors: uncategorized_parent: "Die \"unkategorisiert\" Kategorie kann keine Elternkategorie haben." self_parent: "Eine Kategorie kann nicht sich selbst untergeordnet werden." @@ -734,7 +733,6 @@ de: summary_likes_required: "Mindestanzahl an \"Gefällt mir\" Wertungen in einem Thema, bevor die \"Thema zusammenfassen\" Funktion aktiviert wird." summary_percent_filter: "Zeige die besten (n)% der Beiträge eines Themas in der \"Thema zusammenfassen\"-Ansicht." summary_max_results: "Maximale Anzahl der sichtbaren Beiträge beim Zusammenfassen von Themen" - enable_private_messages: "Erlaube Benutzern auf Vertrauensstufe 1, Direktnachrichten zu erstellen und zu beantworten." enable_long_polling: "Nachrichtenbus für Benachrichtigungen kann Long-Polling nutzen." long_polling_base_url: "Basis-URL für Long Polling (wenn zum Ausliefern von dynamischen Inhalten ein CDN verwendet wird, setze es auf Origin Pull), z. B. http://origin.site.com" long_polling_interval: "Wartezeit, bevor der Server auf Clients reagiert, wenn keine Daten gesendet werden müssen (nur für angemeldete Benutzer)" @@ -1010,6 +1008,7 @@ de: embed_username_key_from_feed: "Schlüsse, um Discourse-Benutzernamen aus Feed zu ziehen." embed_truncate: "Kürze die eingebetteten Beiträge" embed_post_limit: "Maximale Anzahl der Beiträge die eingebettet werden." + embed_username_required: "Der Benutzername ist für die Betragserstellung notwendig" embed_whitelist_selector: "CSS Selektor für Elemente, die in Einbettungen erlaubt sind." embed_blacklist_selector: "CSS Selektor für Elemente, die in Einbettungen entfernt werden." notify_about_flags_after: "Wenn es Markierungen gibt, die nicht nach dieser Anzahl von Stunden behandelt wurden, sende eine E-Mail an contact_email. Setze dies auf 0 um es zu deaktivieren." @@ -1767,11 +1766,11 @@ de: nice_post: | Dieses Abzeichen hast du erhalten, weil du eine Antwort erstellt hast, welche 10 Likes erhalten hat. Gut gemacht! nice_topic: | - Dieses Abzeichen hast du erhalten, weil du ein Thema erstellt hast, welche 10 Likes erhalten hat. Gut gemacht! + Dieses Abzeichen hast du erhalten, weil du ein Thema erstellt hast, welches 10 Likes erhalten hat. Gut gemacht! good_post: | Dieses Abzeichen hast du erhalten, weil du eine Antwort erstellt hast, welche 25 Likes erhalten hat. Gute Arbeit! good_topic: | - Dieses Abzeichen hast du erhalten, weil du ein Thema erstellt hast, welche 25 Likes erhalten hat. Gute Arbeit! + Dieses Abzeichen hast du erhalten, weil du ein Thema erstellt hast, welches 25 Likes erhalten hat. Gute Arbeit! great_post: | Dieses Abzeichen hast du erhalten, weil du einen Beitrag erstellt hast, welcher 50 Likes erhalten hat. Wow! great_topic: | @@ -1786,3 +1785,6 @@ de: performance_report: initial_post_raw: Dieser Beitrag enthält tägliche performance Berichte deiner Seite. initial_topic_title: Berichte zur Webseitengeschwindigkeit + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index dd4240c338..3f1952d92b 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -20,17 +20,21 @@ en: short_date: "D MMM, YYYY" long_date: "MMMM D, YYYY h:mma" - datetime: &datetime - month_names: - [~, January, February, March, April, May, June, July, August, September, October, November, December] + datetime_formats: &datetime_formats formats: + # Format directives: http://ruby-doc.org/core-2.2.0/Time.html#method-i-strftime short: "%m-%d-%Y" + # Format directives: http://ruby-doc.org/core-2.2.0/Time.html#method-i-strftime short_no_year: "%B %-d" + # Format directives: http://ruby-doc.org/core-2.2.0/Time.html#method-i-strftime date_only: "%B %-d, %Y" date: - <<: *datetime + # Do not remove the brackets and commas and do not translate the first month name. It should be "null". + month_names: + [~, January, February, March, April, May, June, July, August, September, October, November, December] + <<: *datetime_formats time: - <<: *datetime + <<: *datetime_formats title: "Discourse" topics: "Topics" @@ -62,8 +66,10 @@ en: exclusion: is reserved greater_than: must be greater than %{count} greater_than_or_equal_to: must be greater than or equal to %{count} + has_already_been_used: "has already been used" inclusion: is not included in the list invalid: is invalid + is_invalid: "is invalid; try to be a little more descriptive" less_than: must be less than %{count} less_than_or_equal_to: must be less than or equal to %{count} not_a_number: is not a number @@ -101,9 +107,6 @@ en: activemodel: errors: <<: *errors - activerecord: - errors: - <<: *errors bulk_invite: file_should_be_csv: "The uploaded file should be of csv or txt format." @@ -280,9 +283,7 @@ en: user: ip_address: "" errors: - messages: - is_invalid: "is invalid; try to be a little more descriptive" - has_already_been_used: "has already been used" + <<: *errors models: topic: attributes: @@ -1162,6 +1163,8 @@ en: anonymous_posting_min_trust_level: "Minimum trust level required to enable anonymous posting" anonymous_account_duration_minutes: "To protect anonymity create a new anonymous account every N minutes for each user. Example: if set to 600, as soon as 600 minutes elapse from last post AND user switches to anon, a new anonymous account is created." + hide_user_profiles_from_public: "Disable user cards, user profiles and user directory for anonymous users." + allow_profile_backgrounds: "Allow users to upload profile backgrounds." sequential_replies_threshold: "Number posts a user has to make in a row in a topic before being reminded about too many sequential replies. " diff --git a/config/locales/server.es.yml b/config/locales/server.es.yml index 879f5c1bd3..af7b0bf5d2 100644 --- a/config/locales/server.es.yml +++ b/config/locales/server.es.yml @@ -21,7 +21,7 @@ es: purge_reason: "Eliminada automáticamente como cuenta abandonada, sin activar" disable_remote_images_download_reason: "La descarga de imágenes remotas se desactivó porque no había suficiente espacio disponible en disco." anonymous: "Anónimos" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "está limitado a %{max} caracteres; has introducido %{length}." @@ -240,6 +240,7 @@ es: attributes: hex: invalid: "no es un color válido" + <<: *errors user_profile: no_info_me: "
    El campo 'Sobre mí' de tu perfil está vacío, ¿Te gustaría completarlo?
    " no_info_other: "
    %{name} no has completado aún el campo 'Sobre mí' de tu perfil
    " @@ -275,8 +276,8 @@ es: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Definición de la categoría %{category}" - replace_paragraph: "[Reemplaza el primer párrafo con una descripción corta de tu nueva categoría. Esta guía aparecerá en el área de selección de categoría, por lo que trata de mantenerla por debajo de los 200 caracteres.]" - post_template: "%{replace_paragraph}\n\nUtiliza los siguientes párrafos para dar una descripción más larga y también para establecer cualquier norma o recomendación para esta categoría.\n\nAlgunos aspectos a tener en consideración en cualquier respuesta:\n\n- ¿Para que es esta categoría? ¿Por qué deben que seleccionar esta categoría como tema?\n\n- ¿Qué diferencia esta categoría de las demas?\n\n- ¿Es necesaria esta categoría?\n\n- ¿Deberíamos unir esta categoría con otra o dividirla en varias?\n" + replace_paragraph: "(Sustituye este primer párrafo con una descripción breve de tu nueva categoría. Esta descripción aparecerá en el área de selección de categoría, por ello, intenta que sea inferior a 200 caracteres. **Hasta que edites esta descripción o se creen temas, esta categoría no aparecerá en la página de categorías.**)" + post_template: "%{replace_paragraph}\n\nUtiliza los siguientes párrafos para una descripción más detallada, o establece las directrices o reglas de la categoría::\n\n- ¿Para qué podrían usar los usuarios esta categoría? ¿De qué trata?\n\n- ¿Cómo se distingue de otras categorías existentes?\n\n- ¿Qué temas debería contener esta categoría normalmente?\n\n- ¿Necesitamos esta categoría? ¿Podría agruparse o converger con otra categoría o subcategoría?\n" errors: uncategorized_parent: "Sin categoría no puede tener categoría primaria" self_parent: "La categoría primaria de una subcategoría no puede ser ella misma." @@ -745,7 +746,7 @@ es: summary_likes_required: "Mínimo de \"me gusta\" en un tema para habilitar 'Resumen de este tema'" summary_percent_filter: "Cuando un usuario hace clic en 'Resumen de este tema', se muestra el n % mejores posts" summary_max_results: "Máximo de posts devueltos en \"Resumen de este tema\"" - enable_private_messages: "Permitir a los usuarios de nivel de confianza 1 crear y responder mensajes" + enable_private_messages: "Permitir a los usuarios de nivel 1 (configurable vía nivel de confianza para enviar mensajes) crear y responder mensajes" enable_long_polling: "Los mensajes usados para notificaciones pueden usar el long polling" long_polling_base_url: "URL base usada para el 'long polling' (cuando un CDN esta sirviendo contenido dinámico, asegúrate de ajustar esto al 'pull' de origen) ejemplo: http://origin.site.com" long_polling_interval: "Cantidad de tiempo que el servidor debe de esperar antes de responder a los clientes que no hay datos enviados (solamente usuarios con sesión iniciada)." @@ -764,6 +765,7 @@ es: notify_mods_when_user_blocked: "Si un usuario es bloqueado automáticamente, enviar un mensaje a todos los moderadores." flag_sockpuppets: "Si un nuevo usuario responde a un tema desde la misma dirección de IP que el nuevo usuario que inició el tema, reportar los posts de los dos como spam en potencia." traditional_markdown_linebreaks: "Utiliza saltos de línea tradicionales en Markdown, que requieren dos espacios al final para un salto de línea." + allow_html_tables: "Permitir la inserción de tablas en Markdown usando etiquetas HTML. Se permitirá usar TABLE, THEAD, TD, TR o TH (requiere un rebake completo para los posts antiguos que contengan tablas)" post_undo_action_window_mins: "Número de minutos durante los cuales los usuarios pueden deshacer sus acciones recientes en un post (me gusta, reportes, etc)." must_approve_users: "Los miembros administración deben aprobar todas las nuevas cuentas antes de que se les permita el acceso al sitio. AVISO: ¡habilitar esta opción en un sitio activo revocará el acceso a los usuarios que no sean moderadores o admin!" ga_tracking_code: "Código de Google Analytics, ej: UA-12345678-9; visita http://google.com/analytics" @@ -790,6 +792,7 @@ es: topics_per_period_in_top_summary: "Número de mejores temas mostrados en el resumen de mejores temas." topics_per_period_in_top_page: "Número de mejores temas mostrados en la vista expandida al clicar en 'ver más'." redirect_users_to_top_page: "Redirigir automáticamente a los nuevos usuarios y a los ausentes de larga duración a la página de mejores temas." + top_page_default_timeframe: "Período de tiempo por defecto para la página de temas top" show_email_on_profile: "Mostrar el e-mail los usuarios en su perfil (solamente visibles para ellos mismos y el staff)" email_token_valid_hours: "Los tokens para restablecer contraseña olvidada / activar cuenta son válidos durante (n) horas." email_token_grace_period_hours: "Los tokens para restablecer contraseña olvidada / activar cuenta son válidos durante (n) horas de periodo de gracia, después de ser redimidos." @@ -875,6 +878,7 @@ es: avatar_sizes: "Lista de tamaños de avatar generados automáticamente." external_system_avatars_enabled: "Usar un servicio externo para los avatares." external_system_avatars_url: "Dirección URL del servicio externo para los avatares. Sustituciones permitidas: {username} {first_letter} {color} {size}" + default_opengraph_image_url: "URL de la imagen opengraph por defecto." enable_flash_video_onebox: "Habilitar el embebido de enlaces swf y flv (Adobe Flash) en formato Onebox. AVISO: podría introducir riesgos de seguridad." default_invitee_trust_level: "Nivel de confianza por defecto (0-4) para usuarios invitados." default_trust_level: "Nivel de confianza por defecto (0-4) para los nuevos usuarios. ¡AVISO! Cambiar esto puede resultar en riesgo por spam." @@ -901,6 +905,7 @@ es: tl3_links_no_follow: "No remover rel=nofollow de los enlaces publicados por usuarios con nivel de confianza 3." min_trust_to_create_topic: "El mínimo nivel de confianza requerido para crear un nuevo tema." min_trust_to_edit_wiki_post: "El mínimo nivel de confianza requerido para editar un post marcado como wiki." + min_trust_to_send_messages: "Mínimo nivel de confianza requerido para crear nuevos mensajes directos." newuser_max_links: "Cuántos enlaces puede un nuevo usuario añadir a un post." newuser_max_images: "Cuántas imágenes puede un nuevo usuario añadir a un post." newuser_max_attachments: "Cuántos adjuntos puede un nuevo usuario añadir a un post." @@ -997,12 +1002,14 @@ es: allow_anonymous_posting: "Permitir a los usuarios cambiar a modo anónimo" anonymous_posting_min_trust_level: "Nivel de confianza mínimo requerido para activar el modo anónimo" anonymous_account_duration_minutes: "Para proteger el anonimato, crear una nueva cuenta anónima cada N minutos para cada usuario. Ejemplo: si se establece en 600, tan pronto como pasen 600 minutos desde el último post Y el usuario cambie a anónimo, se creará una nueva cuenta anónima." + hide_user_profiles_from_public: "Desactiva las tarjetas de usuario, los perfiles y el directorio de usuarios para usuarios anónimos." allow_profile_backgrounds: "Permitir a los usuarios subir sus propios fondos de perfil personalizados." sequential_replies_threshold: "Número de posts consecutivos que un usuario publicará en un mismo tema hasta mostrarle un recordatorio sobre demasiadas repuestas seguidas." enable_mobile_theme: "Los dispositivos móviles utilizan un tema adaptado, con la habilidad de cambiar al estilo de sitio completo. Deshabilita esta opción si quieres utilizar una plantilla personalizada que sea completamente adaptable." dominating_topic_minimum_percent: "Qué porcentaje de posts tiene que publicar un usuario en un mismo tema hasta mostrarle un recordatorio acerca de dominar en demasía un tema." daily_performance_report: "Analizar registros de NGINX diariamente y publicar un tema para Administradores con los detalles" suppress_uncategorized_badge: "No mostrar la etiqueta de los temas sin categoría en la lista de temas." + permalink_normalizations: "Aplicar la siguiente expresion regular antes de los enlaces, por ejemplo: /(\\/topic.*)\\?.*/\\1 despojará las cadenas de consulta de las rutas de los temas. El formato es regex+string use \\1 etc. para acceder a capturas" global_notice: "Mostrar una noticia de URGENCIA o EMERGENCIA para todos los visitantes, deja este campo en blanco para ocultarla (se puede utilizar código HTML)" disable_edit_notifications: "Inhabilitar editar notificaciones por el usuario system cuando 'download_remote_images_to_local' este activo." full_name_required: "Su nombre completo es un campo obligatorio de un perfil de usuario." @@ -1021,6 +1028,7 @@ es: embed_username_key_from_feed: "Clave para extraer el nombre de usuario en Discourse desde el feed." embed_truncate: "Truncar los posts embebidos." embed_post_limit: "Número máximo de posts a embeber." + embed_username_required: "Se requiere el nombre de usuario para la creación de temas." embed_whitelist_selector: "Selector CSS para los elementos que están permitidos en los embebidos." embed_blacklist_selector: "Selector CSS para los elementos que están eliminados desde los embebidos." notify_about_flags_after: "Si hay reportes que no han sido revisados después de este número de horas, enviar un correo electrónico al contact_email. Deshabilita esta opción introduciendo el valor 0." @@ -1333,12 +1341,7 @@ es: Para más información, por favor consulta nuestras [directrices](%{base_url}/guidelines). usage_tips: - text_body_template: "Aquí tienes unos breves consejos para empezar:\n\n## Lectura\n\nPara leer más, **¡tan solo tienes que hacer scroll!** \n\nTan pronto como se publiquen nuevas respuestas o temas, aparecerán automáticamente – sin necesidad de actualizar la página.\n\n## Navegación\n\n- Para la búsqueda, tu perfil de usuario, o el menú ;, usa los **botones con iconos de la esquina superior derecha**. \n\n- Entrar a un tema desde su título te llevará a la **última respuesta sin leer** del hilo. Para ir al primer o al último post, haz clic en el contador de respuestas o en la fecha de última respuesta.\n\n \n\n- Mientras lees un tema, selecciona la barra de progreso en la esquina inferior derecha para ver los controles de navegación. Podrás ir al inicio del hilo seleccionando su\ - \ título. Teclea ? para ver una lista de rápidos atajos de teclado.\n\n \n\n## Participando\n\n- Para responder al **tema en general**, utiliza al final del hilo. \n\n- Para responder a **una persona en específico**, utiliza en su post. \n\n- Para responder **creando un nuevo tema**, utiliza a la derecha del post. Tanto el tema original como el nuevo serán enlazados entre sí automáticamente. \n\nPara escribir una cita, selecciona el texto que quieres citar, después haz clic en el botón citar. ¡Puedes repetir para realizar\ - \ múltiples citas! \n\n\n\nPara notificar a alguien en tu respuesta, menciónale. Empieza a escribir `@` para elegir su nombre de usuario. \n\n \n\nPara usar [Emojis](http://www.emoji.codes/), teclea `:` para elegir por nombre, o usa los tradicionales smileys `;)` \n\n \n\n## Acciones\n\nHay algunos botones de acción al final de cada post: \n\n \n\nPara hacerle saber a alguien que has disfrutado o que aprecias su post, utiliza el botón de **Me gusta**. ¡Compartir es amor! \n\nSi ves algún problema en la publicación de\ - \ alguien, escríbele un privado, o házselo saber [a nuestros moderadores](%{base_url}/about), con el botón **reporte**. También puedes **compartir** un enlace a un post, o guardarlo en **marcadores** para tenerlo de referencia en tu página de perfil. \n\n## Notificaciones\n\nCuando alguien te responde, cita tu post, o bien menciona tu `@usuario`, inmediatamente aparecerá un número en la esquina superior derecha de la página. Usa ese botón para acceder a tus **notificaciones**. \n\n \n\nNo te preocupes si te pierdes alguna respuesta – te enviaremos un email con las notificaciones que lleguen cuando estés fuera.\n\n## Tus preferencias\n\n- Todos los temas creados hace menos de **dos días** se consideran nuevos. \n\n- Aquellos temas en los que hayas **participado activamente** (porque lo hayas creado,\ - \ o respondido o leído durante un período razonable) serán seguidos por tu usuario automáticamente. Verás los indicadores azules de temas nuevos o número de respuestas no leídas al lado de estos temas: \n\n \n\nPuedes cambiar tus notificaciones para cualquier tema mediante el control de notificaciones al final del tema. \n\n \n\nTambién puedes establecer el estado de notificación de una categoría entera, si quieres vigilar cualquier nuevo tema en una categoría específica. Para cambiar cualquiera de estas opciones, puedes ver [tus preferencias](%{base_url}/my/preferences). \n\n## Confianza \n\nAl participar aquí, con el tiempo te ganarás la confianza de la comunidad, te convertirás en usuario de\ - \ pleno derecho y te serán retiradas las limitaciones de nuevo usuario. Llegado a un punto de un alto [nivel de confianza](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), obtendrás además nuevas habilidades para ayudarnos a gestionar la comunidad juntos.\n" + text_body_template: "Aquí tienes unos breves consejos para empezar:\n\n## Lectura\n\nPara leer más, **¡tan solo tienes que hacer scroll!** \n\nTan pronto como se publiquen nuevas respuestas o temas, aparecerán automáticamente – sin necesidad de actualizar la página.\n\n## Navegación\n\n- Para la búsqueda, tu perfil de usuario, o el menú ;, usa los **botones con iconos de la esquina superior derecha**. \n\n- Entrar a un tema desde su título te llevará a la **última respuesta sin leer** del hilo. Para ir al primer o al último post, haz clic en el contador de respuestas o en la fecha de última respuesta.\n\n \n\n- Mientras lees un tema, selecciona la barra de progreso en la esquina inferior derecha para ver los controles de navegación. Podrás ir al inicio del hilo seleccionando su título. Teclea ? para ver una lista de rápidos atajos de teclado.\n\n \n\n## Participando\n\n- Para responder al **tema en general**, utiliza al final del hilo. \n\n- Para responder a **una persona en específico**, utiliza en su post. \n\n- Para responder **creando un nuevo tema**, utiliza a la derecha del post. Tanto el tema original como el nuevo serán enlazados entre sí automáticamente. \n\nPara escribir una cita, selecciona el texto que quieres citar, después haz clic en el botón citar. ¡Puedes repetir para realizar múltiples citas! \n\n\n\nPara notificar a alguien en tu respuesta, menciónale. Empieza a escribir `@` para elegir su nombre de usuario. \n\n \n\nPara usar [Emojis](http://www.emoji.codes/), teclea `:` para elegir por nombre, o usa los tradicionales smileys `;)` \n\n \n\n## Acciones\n\nHay algunos botones de acción al final de cada post: \n\n \n\nPara hacerle saber a alguien que has disfrutado o que aprecias su post, utiliza el botón de **Me gusta**. ¡Compartir es amor! \n\nSi ves algún problema en la publicación de alguien, escríbele un privado, o házselo saber [a nuestros moderadores](%{base_url}/about), con el botón **reporte**. También puedes **compartir** un enlace a un post, o guardarlo en **marcadores** para tenerlo de referencia en tu página de perfil. \n\n## Notificaciones\n\nCuando alguien te responde, cita tu post, o bien menciona tu `@usuario`, inmediatamente aparecerá un número en la esquina superior derecha de la página. Usa ese botón para acceder a tus **notificaciones**. \n\n \n\nNo te preocupes si te pierdes alguna respuesta – te enviaremos un email con las notificaciones que lleguen cuando estés fuera.\n\n## Tus preferencias\n\n- Todos los temas creados hace menos de **dos días** se consideran nuevos. \n\n- Aquellos temas en los que hayas **participado activamente** (porque lo hayas creado, o respondido o leído durante un período razonable) serán seguidos por tu usuario automáticamente. Verás los indicadores azules de temas nuevos o número de respuestas no leídas al lado de estos temas: \n\n \n\nPuedes cambiar tus notificaciones para cualquier tema mediante el control de notificaciones al final del tema. \n\n \n\nTambién puedes establecer el estado de notificación de una categoría entera, si quieres vigilar cualquier nuevo tema en una categoría específica. Para cambiar cualquiera de estas opciones, puedes ver [tus preferencias](%{base_url}/my/preferences). \n\n## Confianza \n\nAl participar aquí, con el tiempo te ganarás la confianza de la comunidad, te convertirás en usuario de pleno derecho y te serán retiradas las limitaciones de nuevo usuario. Llegado a un punto de un alto [nivel de confianza](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), obtendrás además nuevas habilidades para ayudarnos a gestionar la comunidad juntos.\n" welcome_user: subject_template: "¡Bienvenido a %{site_name}!" text_body_template: | @@ -1889,12 +1892,7 @@ es: title: "Términos de Servicio" privacy_topic: title: "Políticas de Privacidad" - body: "\n\n## [¿Qué información recolectamos?](#collect)\n\nRecolectamos información tuya cuando te registras en nuestra web, y recopilamos información cuando participas en ella leyendo, escribiendo y evaluando el contenido compartido aquí.\n\nAl registrarte en nuestra web, puede que se te pida que indiques tu nombre y tu email. Sin embargo, puedes visitarnos sin registrarte. Tu email será verificado a través de un mensaje que contendrá un enlace único. Si ese enlace es visitado, sabremos que controlas el email.\n\nCuando estés registrado y publiques, guardamos la dirección IP de donde el mensaje ha sido publicado. Puede que guardemos registros que incluyan la dirección IP de cada intercambio de datos con nuestro servidor.\n\n\n\n## [¿Para qué usamos tu información?](#use)\n\nCualquier información recolectada puede ser usada en una de las siguientes\ - \ maneras:\n\n* Para personalizar tu experiencia — tu información nos ayuda a responder a tus necesidades individuales.\n* Para mejorar nuestra web — intentamos continuamente mejorar nuestro sitio web ofreciéndote contenido basado en la información que recibimos de ti.\n* Para mejorar el servicio de soporte — tu información nos ayuda a responder de una forma más efectiva a tus dudas y problemas.\n* Para enviar emails cada cierto tiempo — La direccion de email que nos proporciones puede ser usada para enviarte información, notificaciones que tú solicites sobre cambios en temas, sobre respuestas a tu nombre, respuestas a consultas y/o cualquier otro tipo de solicitudes o cuestiones.\n\n\n\n## [¿Cómo protegemos tu información?](#protect)\n\nTenemos implementadas varias medidas de seguridad para mantener tu información personal segura cuuando la introduces\ - \ o accedes a ella.\n\n\n\n## [¿Cuál es la política de retención de datos?](#data-retention)\n\nIntentamos:\n\n* No retener los registros de los servidores conteniendo la dirección IP de todas las solicitudes durante más de 90 días.\n* No retener las direcciones IP asociadas con usuarios registrados y sus mensajes durante no más de 5 años.\n\n\n\n\n## [¿Usamos cookies?](#cookies)\n\nSí. Las cookies con pequeños archivos que una web o su proveedor de servicios transfiere a tu disco duro a través de tu navegador (si lo permites).\nEstas cookies permiten a la web reconocer tu navegador y, si tienes una cuenta registrada, asociarlo con ella.nt.\n\nUsamos cookies para entender y guardar tus preferencias para futuras visitas y para recolectar información sobre el tráfico y la interacción con este sitio web para que podamos ofrecer mejores experiencias\ - \ y herramientas en un futuro. Puede que nos asociemos con terceras personas para que nos asisten a entender mejor a nuestros visitantes. Estos proveedores de servicios no tienen permitido usar esta información para otro propósito que no sea ayudarnos a mejorar.\n\n\n\n## [¿Revelamos alguna información a terceros?](#disclose)\n\nNo vendemos, intercambiamos o transferimos a terceros tu información personal. Esto no incluye a terceros que nos ayuden a operar correctamente este sitio web, a administrar nuestro negocio o a ofrecerte un servicio, siempre y cuando acepten mantener esta información confidencial.\nPuede que revelemos tu información cuando creamos que sea apropiado para cumplir con la ley, hacer cumplir con nuestras políticas, derechos, propiedades, o seguridad nuestros o de terceros. Sin embargo, la información no personal de los visitantes puede que sea entregada\ - \ debidamente a terceros con propósitos de marketing, publicidad u otros usos. \n\n\n\n## [Enlaces de terceros](#third-party)\n\nOcasionalmente, es posible que incluyamos u ofrezcamos enlaces a productos o servicios de terceros en esta web. Estos sitios webs de terceros tienen otras políticas de privacidad, por lo que no nos hacemos responsables del contenido y actividades de estos sitios. Sin embargo, intentamos proteger la integridad de nuestra web y aceptamos opiniones sobre estos sitios de terceros.\n\n\n\n## [Cumplimiento del Acta de Protección de la Privacidad Online de los Niños de 1998](#coppa)\n\nNuestra web, sus productos y servicios están dirigidos a personas que tengan 13 o más años de edas. Si este servidor está en EEUU, y tienes menos de 13 años de edad, a causa del Acta de Protección de la Privacidad Online de los Niños de 1998\ - \ ([Children's Online Privacy Protection Act](https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act)) de EEUU, no uses este sitio web.\n\n\n\n## [Política de privacidad online](#online)\n\nEsta política de privacidad sólo tiene validez para la información recolectada a través de nuestro sitio web, y no para aquella recolectada offline.\n\n\n\n## [Consentimiento](#consent)\n\nAl usar nuestra web, aceptas esta política.\n\n\n\n## [Cambios a nuestra política de privacidad](#changes)\n\nSi decidimos cambiar nuestra política de privacidad, publicaremos los cambios en esta misma página.\n\nEste documento tiene una licencia \"CC-BY-SA\". Última actualización: 31 de mayo del 2013.\n" + body: "\n\n## [¿Qué información recolectamos?](#collect)\n\nRecolectamos información tuya cuando te registras en nuestra web, y recopilamos información cuando participas en ella leyendo, escribiendo y evaluando el contenido compartido aquí.\n\nAl registrarte en nuestra web, puede que se te pida que indiques tu nombre y tu email. Sin embargo, puedes visitarnos sin registrarte. Tu email será verificado a través de un mensaje que contendrá un enlace único. Si ese enlace es visitado, sabremos que controlas el email.\n\nCuando estés registrado y publiques, guardamos la dirección IP de donde el mensaje ha sido publicado. Puede que guardemos registros que incluyan la dirección IP de cada intercambio de datos con nuestro servidor.\n\n\n\n## [¿Para qué usamos tu información?](#use)\n\nCualquier información recolectada puede ser usada en una de las siguientes maneras:\n\n* Para personalizar tu experiencia — tu información nos ayuda a responder a tus necesidades individuales.\n* Para mejorar nuestra web — intentamos continuamente mejorar nuestro sitio web ofreciéndote contenido basado en la información que recibimos de ti.\n* Para mejorar el servicio de soporte — tu información nos ayuda a responder de una forma más efectiva a tus dudas y problemas.\n* Para enviar emails cada cierto tiempo — La direccion de email que nos proporciones puede ser usada para enviarte información, notificaciones que tú solicites sobre cambios en temas, sobre respuestas a tu nombre, respuestas a consultas y/o cualquier otro tipo de solicitudes o cuestiones.\n\n\n\n## [¿Cómo protegemos tu información?](#protect)\n\nTenemos implementadas varias medidas de seguridad para mantener tu información personal segura cuuando la introduces o accedes a ella.\n\n\n\n## [¿Cuál es la política de retención de datos?](#data-retention)\n\nIntentamos:\n\n* No retener los registros de los servidores conteniendo la dirección IP de todas las solicitudes durante más de 90 días.\n* No retener las direcciones IP asociadas con usuarios registrados y sus mensajes durante no más de 5 años.\n\n\n\n\n## [¿Usamos cookies?](#cookies)\n\nSí. Las cookies con pequeños archivos que una web o su proveedor de servicios transfiere a tu disco duro a través de tu navegador (si lo permites).\nEstas cookies permiten a la web reconocer tu navegador y, si tienes una cuenta registrada, asociarlo con ella.nt.\n\nUsamos cookies para entender y guardar tus preferencias para futuras visitas y para recolectar información sobre el tráfico y la interacción con este sitio web para que podamos ofrecer mejores experiencias y herramientas en un futuro. Puede que nos asociemos con terceras personas para que nos asisten a entender mejor a nuestros visitantes. Estos proveedores de servicios no tienen permitido usar esta información para otro propósito que no sea ayudarnos a mejorar.\n\n\n\n## [¿Revelamos alguna información a terceros?](#disclose)\n\nNo vendemos, intercambiamos o transferimos a terceros tu información personal. Esto no incluye a terceros que nos ayuden a operar correctamente este sitio web, a administrar nuestro negocio o a ofrecerte un servicio, siempre y cuando acepten mantener esta información confidencial.\nPuede que revelemos tu información cuando creamos que sea apropiado para cumplir con la ley, hacer cumplir con nuestras políticas, derechos, propiedades, o seguridad nuestros o de terceros. Sin embargo, la información no personal de los visitantes puede que sea entregada debidamente a terceros con propósitos de marketing, publicidad u otros usos. \n\n\n\n## [Enlaces de terceros](#third-party)\n\nOcasionalmente, es posible que incluyamos u ofrezcamos enlaces a productos o servicios de terceros en esta web. Estos sitios webs de terceros tienen otras políticas de privacidad, por lo que no nos hacemos responsables del contenido y actividades de estos sitios. Sin embargo, intentamos proteger la integridad de nuestra web y aceptamos opiniones sobre estos sitios de terceros.\n\n\n\n## [Cumplimiento del Acta de Protección de la Privacidad Online de los Niños de 1998](#coppa)\n\nNuestra web, sus productos y servicios están dirigidos a personas que tengan 13 o más años de edas. Si este servidor está en EEUU, y tienes menos de 13 años de edad, a causa del Acta de Protección de la Privacidad Online de los Niños de 1998 ([Children's Online Privacy Protection Act](https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act)) de EEUU, no uses este sitio web.\n\n\n\n## [Política de privacidad online](#online)\n\nEsta política de privacidad sólo tiene validez para la información recolectada a través de nuestro sitio web, y no para aquella recolectada offline.\n\n\n\n## [Consentimiento](#consent)\n\nAl usar nuestra web, aceptas esta política.\n\n\n\n## [Cambios a nuestra política de privacidad](#changes)\n\nSi decidimos cambiar nuestra política de privacidad, publicaremos los cambios en esta misma página.\n\nEste documento tiene una licencia \"CC-BY-SA\". Última actualización: 31 de mayo del 2013.\n" static: search_help: |

    Consejos

    @@ -1977,3 +1975,6 @@ es: performance_report: initial_post_raw: Este tema contiene informes diarios sobre el rendimiento de tu sito. initial_topic_title: Informe sobre el rendimiento del sitio + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.fa_IR.yml b/config/locales/server.fa_IR.yml index d96de19f21..ef1228bdeb 100644 --- a/config/locales/server.fa_IR.yml +++ b/config/locales/server.fa_IR.yml @@ -21,7 +21,7 @@ fa_IR: purge_reason: "بطور خودکار پاک شد بدلیل استفاده نشدن٬ حساب کاربری غیرفعال" disable_remote_images_download_reason: "عکس های ریموت دانلود شده غیرفعال شدند زیرا آنجا فضای کافی در دیسک وجود نداشت" anonymous: "ناشناس" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "محدود به %{max} کاراکتر; شما وارد %{length} کردید " @@ -217,6 +217,7 @@ fa_IR: attributes: hex: invalid: "این یک رنگ معتبر نیست" + <<: *errors user_profile: no_info_me: "
    درباره من نمایه شما خالی در حال حاضر خالی است٬ علاقه دارید آن را تکمیل کنید ؟
    " no_info_other: "
    %{name}هنوز چیزی وارد نکرده درباره خودش در نمایه شان. " @@ -252,8 +253,6 @@ fa_IR: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "در رابطه با دسته بندی {category}% " - replace_paragraph: "[به جای پاراگراف اول توضیحات کوتاهی درباره دسته جدیدتون قرار بدید. این راهنما در قسمت دسته ها نمایش داده می شود٬ پس سعی کن زیر 200 کلمه اون را نگاه دارید. قبل از اینکه این متن را ویرایش کنید یا جستار جدیدی بوجود بیاورید٬ این دسته در صفحه دسته ها نمایش داده نمی شود.]" - post_template: "%{replace_paragraph}\n\nUse the following paragraphs for a longer description, as well as to establish any category guidelines or rules.\n\nSome things to consider in any discussion replies below:\n\n- What is this category for? Why should people select this category for their topic?\n\n- How is this different than the other categories we already have?\n\n- Do we need this category?\n\n- Should we merge this with another category, or split it into more categories?\n" errors: uncategorized_parent: "بدون دسته بندی نمی تواند طبقه خانواده داشته باشد" self_parent: "والد زیر شاخه نمی تواند خودش باشد." @@ -670,7 +669,6 @@ fa_IR: summary_likes_required: "حداقل پسندها در این جستار قبل از اینکه \" خلاصه این جستار\" فعال شود" summary_percent_filter: "وقتی کاربر بر روی ' خلاصه این جستار ' کلیک کرد٬‌ % بهترین نوشته ها را نشان بده" summary_max_results: "حداکثر نوشته های برگردانده شد با \" خلاصه این جستار\"" - enable_private_messages: "به کاربران سطح اعتماد 1 برای ساختن پیام ها و ارسال پاسخ با پیام ها اجازه بده" enable_long_polling: "پیام اتوبوس استفاده شده برای آگاه سازی می تواند برای رای گیری طولانی استفاده شود. " long_polling_base_url: " URL پایه استفاده شده برای رای گیری طولانی ( وقتی CDN خدمت محتوای پویا می دهد٬ مطمئن شوید از تنظیم بودن منشا این کشش) برای نمونه : http://origin.site.com" long_polling_interval: "مدت زمانی که سرور باید صبر کند قبل پاسخ دادن به مشتری ها وقتی در آنجا داده ای برای ارسال نیست ( فقط کاربران وارد شده )" @@ -1449,3 +1447,6 @@ fa_IR: performance_report: initial_post_raw: این مطلب شامل گزارش عملکرد روزانه سایت شماست. initial_topic_title: گزارش عملکرد وب‌سایت + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.fi.yml b/config/locales/server.fi.yml index 76bdb7bfaa..9f588f7b60 100644 --- a/config/locales/server.fi.yml +++ b/config/locales/server.fi.yml @@ -21,7 +21,7 @@ fi: purge_reason: "Poistettu automaattisesti hylättynä, aktivoimattomana tilinä" disable_remote_images_download_reason: "Linkattujen kuvien lataaminen poistettiin käytöstä vähäisen tallennustilan vuoksi." anonymous: "Anonyymejä" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "on rajoitettu %{max} merkkiin; sinä syötit %{length} merkkiä." @@ -249,6 +249,7 @@ fi: attributes: hex: invalid: "ei ole sallittu väri" + <<: *errors user_profile: no_info_me: "
    Minusta -kohta käyttäjäprofiilissasi on vielä täyttämättä,haluaisitko täyttää sen nyt?
    " no_info_other: "
    %{name} ei ole täyttänyt vielä mitään Minusta -kohtaan profiilissaan
    " @@ -284,8 +285,8 @@ fi: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Alueesta %{category}" - 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 pituisenä. Tätä aluetta ei näytetä listauksissa ennen kuin olet muokannut tätä tekstiä tai luonut viestiketjuja.]" - post_template: "%{replace_paragraph}\n\nKäytä seuraavat kappaleet pidempään kuvaukseen ja selvittääksesi alueen säännöt ja ohjeet.\n\nJotain huomioitavia asioita alle muodostuvaa keskustelua ajatellen:\n\n- Mitä varten tämä alue on? Miksi ihmiset valitsisivat tämän alueen viestiketjulleen?\n\n- Kuinka se eroaa muista alueista?\n\n- Tarvitaanko tätä aluetta?\n\n- Pitäisikö alue yhdistää toisen alueen kanssa, tai jakaa useammaksi alueeksi?\n" + 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 pituisenä. **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." @@ -754,7 +755,7 @@ fi: summary_likes_required: "Montako tykkäystä ketjussa pitää olla, jotta ketjun tiivistelmä otetaan käyttöön" summary_percent_filter: "Kun käyttäjä klikkaa 'Näytä ketjun tiivistelmä', näytä paras % viesteistä" summary_max_results: "Maksimimäärä viestejä, jotka näytetään ketjun tiivistelmässä" - enable_private_messages: "Salli luottamustason 1 käyttäjien luoda ja vastata viesteihin" + enable_private_messages: "Salli luottamustason 1 (muokattavissa asetuksista) käyttäjien lähettää yksityisviestejä ja vastata viesteihin" enable_long_polling: "Ilmoitusten käyttämä viestiväylä voi käyttää long pollingia" long_polling_base_url: "Base URL, jota käytetään long pollingissa (kun CDN on käytössä, varmista että tähän on asetettu origin pull) esim: http://origin.site.com" long_polling_interval: "Kuinka kauan palvelimen pitäisi odottaa ennen vastaamista asiakkaalle, kun ei ole mitään dataa jota lähettää (vain kirjautuneille käyttäjille)" @@ -773,6 +774,7 @@ fi: notify_mods_when_user_blocked: "Jos käyttäjä estetään automaattisesti, lähetä viesti kaikille valvojille." flag_sockpuppets: "Jos uusi käyttäjä vastaa toisen uuden käyttäjän luomaan ketjun samasta IP osoitteesta, liputa molemmat viestit mahdolliseksi roskapostiksi." traditional_markdown_linebreaks: "Käytä perinteisiä rivinvaihtoja Markdownissa, joka vaatii kaksi perättäistä välilyöntiä rivin vaihtoon." + allow_html_tables: "Salli taulukoiden syöttäminen Markdowniin käyttäen HTML tageja. TABLE, THEAD, TD, TR, TH valkolistataan (edellyttää kaikkien taulukoita sisältävien vanhojen viestien uudelleen rakentamisen)" post_undo_action_window_mins: "Kuinka monta minuuttia käyttäjällä on aikaa perua viestiin kohdistuva toimi (tykkäys, liputus, etc)." must_approve_users: "Henkilökunnan täytyy hyväksyä kaikki uudet tilit, ennen uusien käyttäjien päästämistä sivustolle. VAROITUS: tämän asetuksen valitseminen poistaa pääsyn kaikilta jo olemassa olevilta henkilökuntaan kuulumattomilta käyttäjiltä." ga_tracking_code: "Google analytics (ga.js) seurantakoodi, esim.: UA-12345678-9; katso http://google.com/analytics" @@ -799,6 +801,7 @@ fi: topics_per_period_in_top_summary: "Kejujen lukumäärä, joka näytetään oletuksena Huiput-listauksissa." topics_per_period_in_top_page: "Kejujen lukumäärä, joka näytetään laajennetussa Huiput-listauksessa." redirect_users_to_top_page: "Ohjaa uudet ja kauan poissa olleet käyttäjät automaattisesti huiput-sivulle." + top_page_default_timeframe: "Huiput-sivun oletusaikajakso." show_email_on_profile: "Näytä käyttäjän sähköpostiosoite profiilissa (näkyy vain käyttäjälle itselleen ja henkilökunnalle)" email_token_valid_hours: "Unohtuneen salasanan / tilin vahvistamisen tokenit ovat voimassa (n) tuntia." email_token_grace_period_hours: "Unohtuneen salasanan / tilin vahvistamisen tokenit ovat vielä voimassa (n) tuntia käyttämisen jälkeen." @@ -884,6 +887,7 @@ fi: avatar_sizes: "Profiilikuvista automaattisesti luotavat koot." external_system_avatars_enabled: "Käytä ulkopuolista avatarpalvelua." external_system_avatars_url: "Ulkoisen avatarpalvelun URL. Sallitut vaihdokset ovat {username} {first_letter} {color} {size}" + default_opengraph_image_url: "Oletuksena käytettävän opengraph-kuvan URL." enable_flash_video_onebox: "Ota käyttöön swf- ja flv-linkkien (Adobe Flash) onebox-tuki. VAROITUS: saattaa lisätä tietoturvariskejä." default_invitee_trust_level: "Oletus luottamustaso (0-4) kutsutuille käyttäjille." default_trust_level: "Uusien käyttäjien oletusarvoinen luottamustaso (0-4). VAROITUS! Tämän muuttaminen altistaa roskapostille." @@ -910,6 +914,7 @@ fi: tl3_links_no_follow: "Älä poista rel=nofollow -attribuuttia linkeistä luottamustason 3 käyttäjiltä." min_trust_to_create_topic: "Ketjun luomiseksi vaadittava luottamustaso." min_trust_to_edit_wiki_post: "Wikiviestin muokkaamiseen vaadittava luottamustaso." + min_trust_to_send_messages: "Yksityisviestien luomiseen vaadittava luottamustaso" newuser_max_links: "Kuinka monta linkkiä uusi käyttäjä voi lisätä viestiin." newuser_max_images: "Kuinka monta kuvaa uusi käyttäjä voi lisätä viestiin." newuser_max_attachments: "Kuinka monta liitettä uusi käyttäjä voi lisätä viestiin." @@ -1030,6 +1035,7 @@ fi: embed_username_key_from_feed: "Avain, jolla erotetaan Discourse-käyttäjänimi syötteestä." embed_truncate: "Typistä upotetut viestit." embed_post_limit: "Upotettavien viestien maksimimäärä." + embed_username_required: "Käyttäjänimi vaaditaan ketjun luomiseksi." embed_whitelist_selector: "CSS valitsin elementeille, jotka sallitaan upotetuissa viesteissä." embed_blacklist_selector: "CSS valitstin elementeille, jotka poistetaan upotetuista viesteistä." notify_about_flags_after: "Jos liputuksia ei ole käsitelty näin moneen tuntiin, lähetä sähköposti contact_email osoitteeseen. Aseta 0 ottaaksesi pois käytöstä." @@ -1926,3 +1932,6 @@ fi: performance_report: initial_post_raw: Tämä ketju sisältää päivittäisiä suorituskykyrapotteja sivustoltasi initial_topic_title: Sivuston suorituskykyraportit + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml index 1eddf94c85..20bf195622 100644 --- a/config/locales/server.fr.yml +++ b/config/locales/server.fr.yml @@ -21,7 +21,7 @@ fr: purge_reason: "Supprimé automatiquement comme compte abandonné, non activé" disable_remote_images_download_reason: "Le téléchargement des images externes a été désactivé faute de place suffisante sur le disque." anonymous: "Anonyme" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "est limité à %{max} caractères maximum; il y en a %{length}." @@ -71,6 +71,7 @@ fr: max_username_length_exists: "Il n'est pas possible de définir une longeur maximale de pseudo qui soit plus court qu'un pseudo qui existe déjà." max_username_length_range: "Vous ne pouvez pas mettre le maximum sous le minimum" default_categories_already_selected: "Vous ne pouvez pas séléctionner une catégorie qui est utilisée dans une autre liste." + s3_upload_bucket_is_required: "Vous ne pouvez pas activer l'upload sur S3 avant d'avoir renseigné le 's3_upload_bucket'." bulk_invite: file_should_be_csv: "Le fichier envoyé doit être au format csv ou txt." backup: @@ -243,6 +244,7 @@ fr: attributes: hex: invalid: "n'est pas une couleur valide" + <<: *errors user_profile: no_info_me: "
    Le champs A Propos de moi de votre profil est vide, voulez vous le remplir ?
    " no_info_other: "
    %{name} n'a pas encore renseigné le champ A Propos de Moi de son profil
    " @@ -278,8 +280,7 @@ fr: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "A propos de la catégorie %{category}" - replace_paragraph: "[Remplacez ce premier paragraphe par une courte description de votre nouvelle catégorie. Ce texte apparaît dans la zone de sélection de catégorie, alors essayez de le maintenir en dessous de 200 caractères. Cette catégorie n'apparaîtra pas sur la page des catégories tant que vous modifiez ce texte ou jusqu'à ce qu'un sujet soit crée.]" - post_template: "%{replace_paragraph}\n\nUtilisez les paragraphes suivants pour une plus longue description, voire pour établir des règles. \n\nChoses à considérer avant toute réponse ou discussion :⏎\n\n- A quoi sert cette catégorie ? Pourquoi les utilisateurs choisiraient-ils cette catégorie pour leur discussion ?\n\n- En quoi elle est différente des autres catégories que nous avons déjà ?\n\n- Avons-nous besoin de cette catégorie ?\n\n- Devrions-nous fusionner celle-ci avec une autre catégorie, ou la diviser en plusieurs catégories ?\n" + replace_paragraph: "(Remplacez ce premier paragraphe par une brève description de votre nouvelle catégorie. Ce guide apparaîtra dans la zone de sélection de la catégorie, alors essayez de rester en dessous de 200 caractères. **Cette catégorie n'apparaîtra pas sur la page des catégories jusqu'à ce que vous ayez modifié cette description ou créé des sujets.**" errors: uncategorized_parent: "Sans catégorie ne peut pas avoir de parent" self_parent: "Le parent d'une sous-catégorie ne peut pas être elle-même" @@ -305,7 +306,18 @@ fr: title: "meneur" change_failed_explanation: "Vous avez essayé de rétrograder %{user_name} au niveau '%{new_trust_level}'. Cependant son niveau de confiance est déjà '%{current_trust_level}'. %{user_name} restera au niveau '%{current_trust_level}' - Si vous souhaitez rétrograder un utilisateur vous devez verrouiller le niveau de confiance au préalable" rate_limiter: + slow_down: "Vous avez réalisé cette action un trop grand nombre de fois, essayez plus tard." too_many_requests: "Nous avons une limite journalière du nombre d'actions qui peuvent être effectuées. Veuillez patienter %{time_left} avant de recommencer." + by_type: + first_day_replies_per_day: "Vous avez atteint le nombre maximum de réponses qu'un nouvel utilisateur peut créer pour son premier jour. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + first_day_topics_per_day: "Vous avez atteint le nombre maximum de sujets qu'un nouvel utilisateur peut créer pour son premier jour. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + create_topic: "Vous créez des sujets trop rapidement. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + create_post: "Vous répondez trop rapidement. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + topics_per_day: "Vous avez atteint le nombre maximum de nouveaux sujets pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + pms_per_day: "Vous avez atteint le nombre maximum de nouveaux messages pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + create_like: "Vous avez atteint le nombre maximum de J'aime pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + create_bookmark: "Vous avez atteint le nombre maximum de favoris pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." + edit_post: "Vous avez atteint le nombre maximum de modifications pour aujourd'hui. Patientez s'il vous plaît %{time_left} avant d'essayer à nouveau." hours: one: "1 heure" other: "%{count} heures" @@ -494,6 +506,10 @@ fr: title: "Nouveaux utilisateurs" xaxis: "Jour" yaxis: "Nombre de nouveaux utilisateurs" + profile_views: + title: "Vues du Profil Utilisateur" + xaxis: "Jour" + yaxis: "Nombre de profils utilisateurs consultés" topics: title: "Sujets" xaxis: "Jour" @@ -732,7 +748,6 @@ fr: summary_likes_required: "Nombre de J'aime minimum dans un sujet avant que le 'Résumé du sujet' soit activé" summary_percent_filter: "Quand un utilisateur clique sur 'Résumé du sujet', montrer le top % des messages" summary_max_results: "Nombre maximum de messages retournés par 'Résumé de ce sujet'" - enable_private_messages: "Autoriser les utilisateurs de niveau de confiance 1 à créer des messages et à y répondre" enable_long_polling: "Utiliser les requêtes longues pour le flux de notifications." long_polling_base_url: "Racine de l'url utilisée pour les requêtes longues (dans le cas de l'utilisation d'un CDN pour fournir du contenu dynamique, pensez à le configurer en mode \"origin pull\") par exemple: http://origin.site.com" long_polling_interval: "Délai d'attente du serveur avant de répondre aux clients lorsqu'il n'y a pas de données à envoyer\n(réservé aux utilisateurs connectés)" @@ -1799,15 +1814,7 @@ fr: Modifier le premier message de ce sujet pour changer le contenu de la page %{page_name}. guidelines_topic: title: "FAQ/Règlement" - body: "\n\n## [Ceci est un endroit civilisé, merci de le respecter](#civilized)\n\nMerci de traiter ce forum de discussion avec le même respect que vous pourriez avoir dans un parc public. Nous, aussi, sommes une ressource partagée par la communauté — un endroit pour partager des compétences, savoirs et intérêts au travers de conversations.\n\nIl ne s'agit pas de règles absolues, uniquement d'aide au bon sens de notre communauté. Suivez ces instructions pour garder cet endroit propre et bien éclairé pour un débat public civilisé.\n\n\n\n## [Améliorez la discussion](#improve)\n\nAidez nous à faire de cet endroit un lieu idéal pour la discussion en améliorant constamment le débat d'une certaine façon, même minime. Si vous n'êtes pas sûr que votre message soit utile à la discussion\ - \ ou pourrait nuire à son utilité, pensez à ce que vous voulez dire et essayer de nouveau plus tard.\n\nLes sujets abordés ici sont importants pour nous et nous voulons que vous agissiez comme s'ils comptaient également pour vous. Soyez respectueux des sujets et des autres utilisateurs, même si vous êtes en désaccord avec une partie de ce qui est dit.\n\nUne façon d'améliorer la discussion est de découvrir celles qui sont déjà en cours. Essayez de passez un peu de temps à parcourir les sujets avant de répondre ou démarrer votre propre discussion. De fait, vous aurez de plus grandes chances de rencontrer d'autres personnes qui partagent vos intérêts.\n\n\n\n## [Soyez agréable, même si vous n'êtes pas d'accord](#agreeable)\n\nLa critique peut être constructive. Vous pouvez répondre à une personne en étant\ - \ en désaccord avec elle. C'est très bien. Mais n'oubliez pas de *critiquer les idées, pas les gens*. Merci d'éviter :\n\n* les injures,\n* les attaques ad hominem,\n* de répondre à la tonalité d'un sujet plutôt qu'à son contenu réel,\n* les contradictions primaires.\n \nAu lieu de cela, fournissez des contre-arguments motivés qui améliorent la conversation.\n\n\n\n## [Votre participation compte](#participate)\n\nLes conversations que nous avons ici donnent le ton pour tout le monde. Aidez-nous à influencer l'avenir de cette communauté en choisissant de vous engager dans des discussions qui font de ce forum un lieu intéressant — et en évitant celles qui n'y participent pas.\n\nDiscourse fournit des outils qui permettent à la communauté d'identifier collectivement le meilleur (et le pire) des contributions\ - \ : favoris, signets, des *J'aime*, des signalements, des réponses, des vérifications et ainsi de suite. Utilisez ces outils pour améliorer votre propre expérience et celle de tous les autres aussi.\n\nEssayons de laisser notre parc mieux que nous l'avons trouvé.\n\n\n\n## [Si vous voyez un problème, signaler le](#flag-problems)\n\nLes modérateurs ont un rôle spécial ; ils sont responsables de ce forum. Mais vous aussi. Avec votre aide, les modérateurs peuvent être des facilitateurs de la vie de la communauté et pas seulement des concierges ou des policiers.\n\nQuand vous voyez un mauvais comportement, ne répondez pas. Votre reconnaissance encourage le mauvais comportement, il consomme votre énergie et fait perdre du temps à chacun. *Signalez-le*. Si suffisamment de signalements s'accumulent, des\ - \ mesures seront prises, automatiquement ou par l'intervention d'un modérateur.\n\nAfin de maintenir notre communauté, les modérateurs se réservent le droit de supprimer tout contenu et n'importe quel compte utilisateur pour une raison quelconque, et ce à n'importe quel moment. Les modérateurs ne disposent pas d'un aperçu des nouveaux messages avant leur publication, les modérateurs et opérateurs du site n'assument aucune responsabilité pour tout contenu affiché par la communauté.\n\n\n\n## [Soyez toujours civilisé](#be-civil)\n\nRien ne sabote une conversation saine mieux que la grossièreté :\n\n* Soyez civilisé. Ne postez pas ce qu'une personne raisonnable jugerait offensif, ni de discours violent ou haineux.\n* Gardez-le forum propre. Ne publiez rien d'obscène ou sexuellement explicite.\n* Se respecter\ - \ mutuellement est primordial. Ne pas harceler ou chagriner quelqu'un, ni usurper l'identité de quelqu'un ou exposer des informations privées le concernant.\n* Respecter notre forum. Ne postez pas de spam ou tout autre forme de vandalisme.\n \nIl ne s'agit pas ici de choses concrètes avec des définitions précises - évitez *même d'avoir l'air* d'agir de la sorte. Si vous avez un doute, demandez-vous comment vous vous sentiriez si votre sujet était publié sur la première page du Monde.\n\nIl s'agit d'un forum public et les moteurs de recherche indexent ces discussions. Utilisez un langage, des liens et des images sans danger pour votre famille et vos amis.\n\n\n\n## [Gardez cet endroit propre](#keep-tidy)\n\nFaites l'effort de mettre les choses au bon endroit, afin que nous puissions passer plus de temps\ - \ à discuter et moins à ranger. Ainsi :\n\n* Ne commencez pas un sujet dans la mauvaise catégorie.\n* Ne postez pas le même contenu dans plusieurs discussions.\n* Ne postez pas de message sans contenu.\n* Ne pas détourner un sujet en le changeant en cours de route.\n* Ne signez pas vos messages — chaque message dispose d'informations sur le profil qui s'y rattache.\n\nPlutôt que de poster \"+1\", \"lol\", \"mdr\" ou \"d'accord\", utilisez le bouton 'J'aime'. Plutôt que de faire prendre à une discussion existante une direction radicalement différente, utilisez \"Répondre en créant un sujet lié\". \n\n\n\n## [Postez seulement vos propres trucs](#stealing)\n\nVous ne pouvez pas poster n'importe quel contenu numérique s'il appartient à quelqu'un d'autre sans son autorisation. Vous ne pouvez pas poster\ - \ des descriptions, des liens ou des méthodes pour voler la propriété intellectuelle de quelqu'un (logiciels, vidéo, audio, images), ou pour transgresser toute autre loi.\n\n\n\n## [Powered by You](#power)\n\nCe site est géré par votre [équipe de responsables](/about) ainsi que *vous*, la communauté. Si vous avez d'autres questions sur comment les choses devraient fonctionner ici, créez un nouveau sujet dans [la catégorie meta](/c/meta) et discutons-en ! S'il y un problème critique ou urgent qui ne peut pas être résolu par un sujet meta ou un signalement, contactez nous [ici](/about). \n\n\n\n## [Lisez les conditions générales d'utilisation](#tos)\n\nOui, le jargon juridique est ennuyeux, mais nous devons nous protéger – et par extension, vous et vos données – contre des gens\ - \ hostiles. Nous avons des [Conditions générales d'utilisation](/tos) décrivant votre (et notre) comportement et les droits liés au contenu, la confidentialité et les lois. Pour utiliser ce service, vous devez accepter de respecter nos [CGU](/tos).\n" + body: "\n\n## [Ceci est un endroit civilisé, merci de le respecter](#civilized)\n\nMerci de traiter ce forum de discussion avec le même respect que vous pourriez avoir dans un parc public. Nous, aussi, sommes une ressource partagée par la communauté — un endroit pour partager des compétences, savoirs et intérêts au travers de conversations.\n\nIl ne s'agit pas de règles absolues, uniquement d'aide au bon sens de notre communauté. Suivez ces instructions pour garder cet endroit propre et bien éclairé pour un débat public civilisé.\n\n\n\n## [Améliorez la discussion](#improve)\n\nAidez nous à faire de cet endroit un lieu idéal pour la discussion en améliorant constamment le débat d'une certaine façon, même minime. Si vous n'êtes pas sûr que votre message soit utile à la discussion ou pourrait nuire à son utilité, pensez à ce que vous voulez dire et essayer de nouveau plus tard.\n\nLes sujets abordés ici sont importants pour nous et nous voulons que vous agissiez comme s'ils comptaient également pour vous. Soyez respectueux des sujets et des autres utilisateurs, même si vous êtes en désaccord avec une partie de ce qui est dit.\n\nUne façon d'améliorer la discussion est de découvrir celles qui sont déjà en cours. Essayez de passez un peu de temps à parcourir les sujets avant de répondre ou démarrer votre propre discussion. De fait, vous aurez de plus grandes chances de rencontrer d'autres personnes qui partagent vos intérêts.\n\n\n\n## [Soyez agréable, même si vous n'êtes pas d'accord](#agreeable)\n\nLa critique peut être constructive. Vous pouvez répondre à une personne en étant en désaccord avec elle. C'est très bien. Mais n'oubliez pas de *critiquer les idées, pas les gens*. Merci d'éviter :\n\n* les injures,\n* les attaques ad hominem,\n* de répondre à la tonalité d'un sujet plutôt qu'à son contenu réel,\n* les contradictions primaires.\n \nAu lieu de cela, fournissez des contre-arguments motivés qui améliorent la conversation.\n\n\n\n## [Votre participation compte](#participate)\n\nLes conversations que nous avons ici donnent le ton pour tout le monde. Aidez-nous à influencer l'avenir de cette communauté en choisissant de vous engager dans des discussions qui font de ce forum un lieu intéressant — et en évitant celles qui n'y participent pas.\n\nDiscourse fournit des outils qui permettent à la communauté d'identifier collectivement le meilleur (et le pire) des contributions : favoris, signets, des *J'aime*, des signalements, des réponses, des vérifications et ainsi de suite. Utilisez ces outils pour améliorer votre propre expérience et celle de tous les autres aussi.\n\nEssayons de laisser notre parc mieux que nous l'avons trouvé.\n\n\n\n## [Si vous voyez un problème, signaler le](#flag-problems)\n\nLes modérateurs ont un rôle spécial ; ils sont responsables de ce forum. Mais vous aussi. Avec votre aide, les modérateurs peuvent être des facilitateurs de la vie de la communauté et pas seulement des concierges ou des policiers.\n\nQuand vous voyez un mauvais comportement, ne répondez pas. Votre reconnaissance encourage le mauvais comportement, il consomme votre énergie et fait perdre du temps à chacun. *Signalez-le*. Si suffisamment de signalements s'accumulent, des mesures seront prises, automatiquement ou par l'intervention d'un modérateur.\n\nAfin de maintenir notre communauté, les modérateurs se réservent le droit de supprimer tout contenu et n'importe quel compte utilisateur pour une raison quelconque, et ce à n'importe quel moment. Les modérateurs ne disposent pas d'un aperçu des nouveaux messages avant leur publication, les modérateurs et opérateurs du site n'assument aucune responsabilité pour tout contenu affiché par la communauté.\n\n\n\n## [Soyez toujours civilisé](#be-civil)\n\nRien ne sabote une conversation saine mieux que la grossièreté :\n\n* Soyez civilisé. Ne postez pas ce qu'une personne raisonnable jugerait offensif, ni de discours violent ou haineux.\n* Gardez-le forum propre. Ne publiez rien d'obscène ou sexuellement explicite.\n* Se respecter mutuellement est primordial. Ne pas harceler ou chagriner quelqu'un, ni usurper l'identité de quelqu'un ou exposer des informations privées le concernant.\n* Respecter notre forum. Ne postez pas de spam ou tout autre forme de vandalisme.\n \nIl ne s'agit pas ici de choses concrètes avec des définitions précises - évitez *même d'avoir l'air* d'agir de la sorte. Si vous avez un doute, demandez-vous comment vous vous sentiriez si votre sujet était publié sur la première page du Monde.\n\nIl s'agit d'un forum public et les moteurs de recherche indexent ces discussions. Utilisez un langage, des liens et des images sans danger pour votre famille et vos amis.\n\n\n\n## [Gardez cet endroit propre](#keep-tidy)\n\nFaites l'effort de mettre les choses au bon endroit, afin que nous puissions passer plus de temps à discuter et moins à ranger. Ainsi :\n\n* Ne commencez pas un sujet dans la mauvaise catégorie.\n* Ne postez pas le même contenu dans plusieurs discussions.\n* Ne postez pas de message sans contenu.\n* Ne pas détourner un sujet en le changeant en cours de route.\n* Ne signez pas vos messages — chaque message dispose d'informations sur le profil qui s'y rattache.\n\nPlutôt que de poster \"+1\", \"lol\", \"mdr\" ou \"d'accord\", utilisez le bouton 'J'aime'. Plutôt que de faire prendre à une discussion existante une direction radicalement différente, utilisez \"Répondre en créant un sujet lié\". \n\n\n\n## [Postez seulement vos propres trucs](#stealing)\n\nVous ne pouvez pas poster n'importe quel contenu numérique s'il appartient à quelqu'un d'autre sans son autorisation. Vous ne pouvez pas poster des descriptions, des liens ou des méthodes pour voler la propriété intellectuelle de quelqu'un (logiciels, vidéo, audio, images), ou pour transgresser toute autre loi.\n\n\n\n## [Powered by You](#power)\n\nCe site est géré par votre [équipe de responsables](/about) ainsi que *vous*, la communauté. Si vous avez d'autres questions sur comment les choses devraient fonctionner ici, créez un nouveau sujet dans [la catégorie meta](/c/meta) et discutons-en ! S'il y un problème critique ou urgent qui ne peut pas être résolu par un sujet meta ou un signalement, contactez nous [ici](/about). \n\n\n\n## [Lisez les conditions générales d'utilisation](#tos)\n\nOui, le jargon juridique est ennuyeux, mais nous devons nous protéger – et par extension, vous et vos données – contre des gens hostiles. Nous avons des [Conditions générales d'utilisation](/tos) décrivant votre (et notre) comportement et les droits liés au contenu, la confidentialité et les lois. Pour utiliser ce service, vous devez accepter de respecter nos [CGU](/tos).\n" tos_topic: title: "Conditions générales d'utilisation" privacy_topic: @@ -1951,3 +1958,6 @@ fr: performance_report: initial_post_raw: Ce sujet comprend des rapports de performance journaliers concernant votre site. initial_topic_title: Rapports de performances du site + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.he.yml b/config/locales/server.he.yml index 42bb1f077c..02999a2aeb 100644 --- a/config/locales/server.he.yml +++ b/config/locales/server.he.yml @@ -21,7 +21,7 @@ he: purge_reason: "נמחק באופן אוטומטי כחשבון נטוש ולא פעיל" disable_remote_images_download_reason: "הורדת תמונות מרחוק נחסמה בשל היעדר מספיק שטח אכסון פנוי." anonymous: "אנונימי" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "מוגבל לאורך של %{max} תוים: את/ה הקשת %{length}." @@ -229,6 +229,7 @@ he: attributes: hex: invalid: "זהו אינו צבע תקני" + <<: *errors user_profile: no_info_me: "
    שדה האודות של הפרופיל שלך ריק כרגע, תרצה למלא אותו?
    " no_info_other: "
    %{name} עדיין לא הזין דבר בשדה אודות של הפרופיל שלהם
    " @@ -263,8 +264,6 @@ he: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "אודות הקטגוריה %{category}" - replace_paragraph: "[החלף את הפסקה הראשונה הזו עם תיאור קצר של הקטגוריה החדש שלך. התיאור הזה יופיע באיזור בחירת הקטגוריה, כך שיש לנסות לשמור עליו באורך פחות מ-200 תויים. עד שתעריך את המלל הזה או תיצור נושאים, הקטגוריה הזו לא תופיע בעמוד הקטגוריות.]" - post_template: "%{replace_paragraph}\n\nהשתמש בפסקאות הבאו עבור תיאור אורך יותר, כמו גם כדי להחיל כללים או חוקים על הקטגוריה.\n\nחלק מהנושאים שיש לשקול בכל דיון:\n\n- בשביל מה הקטגוריה הזו? למה שאנשים יבחרו בה בשביל הנושא שלהם?\n\n- איך היא שונה מקטגוריות אחרות שכבר יש לנו?\n\n- אנחנו צריכים את הקטגוריה הזו?\n\n- אולי כדאי לאחד אותה עם קטגוריה אחרת, או לפצל אותה לכמה קטגוריות?\n" errors: uncategorized_parent: "נטול קטגוריה לא יכול להיות עם קטגוריית אם" self_parent: "קטגוריית אם לא יכולה להיות הקטגוריה עצמה" @@ -732,7 +731,6 @@ he: summary_likes_required: "מינימום הלייקים לנושא לפני שהאפשרות \"סיכום נושא זה\" תתאפשר" summary_percent_filter: "כאשר משתמש/ת מקליקים על \"סיכום נושא זה\", הציגו את % o הפרסומים הראשונים" summary_max_results: "מספר הפרסומים שיוחזרו באמצעות \"סיכום נושא זה\"" - enable_private_messages: "אפשרו למשתמשים בעלי רמת_אמון 1 ליצור הודעות ולהגיב להודעות" enable_long_polling: "Message bus used for notification can use long polling" long_polling_base_url: "בסיס ה-URL שנמצא בשימוש עבור long polling (כאשר CDN מחזיר תוכן דינמי, זכרו להגדיר את ערך זה ל-Origin pull, דוגמת http://origin.site.com)" long_polling_interval: "כמות הזמן שהשרת צריך לחכות לפני שעונה ללקוחות, כאשר אין מידע לשליחה (משתמשים רשומים מחוברים למערכת בלבד)" @@ -1307,11 +1305,7 @@ he: subject_template: "הודעה הוסתרה בעקבות סימון" text_body_template: "שלום,\n\nזו הודעה אוטומטית מ %{site_name} לידע אותך שהפרסום שלך הוסתר. \n\n%{base_url}%{url}\n\n%{flag_reason}\n\nמספר חברי קהילה סימנו את הפרסום הזה לפני שהוסתר, אז בבקשה תשקול איך תוכל לשנות את הפרסום בהתאם להערותיהם. \n\n**תוכל לערוך את הפרסום אחרי %{edit_delay} דקות, והוא יוצג באופן אוומטי**\n\nאולם, אם הפרסום יוסתר על ידי הקהילה פעם נוספת, הוא ישאר מוסתר עד לטיפול של צוות האתר, ותתכן תגובה נוספת, כולל השהייה של חשבונך. \n\nלהדכה נוספת, [קווים מנחים](%{base_url}/guidelines).\n" usage_tips: - text_body_template: "הינה מספר טיפים קצרים לעזור לך להתחיל:\n\n## קריאה\n\nלקרוא יותר, **פשו המשך לגלול למטה**\n\nכשתגובות או נושאים חדשים יגיעו, הם יופיעו באוםן אוטומטי – אין צורך לרענן את העמוד.\n\n##ניווט\n\n-לחיפוש השתמש בעמוד משתמש או בתפריט , השתמש ב**כפתורי אייקון משמשאל למעלה**\n\n-בחירת כותרת נושא תמיד תקח אותך ל**תגובה אחרונה שלא נקראה** בנושא. להכנס ללמעלה או למטה, בחר בספירת תגובות או תאריך פרסום אחרון.\n\n\n\n-בעת קריאה נושא, בחר בסרגל התקדמות מימין למטה לשליטה מלאה בניווט. עבור במהירות חזרה למעלה על ידי בחירה בכותרת הנושא. לחץ ? לרשימה של קיצורי מקלדת מהירים. \n\n\n## תגובה\n\n-להגיב ל**נושא באופן כללי**, השתמש בתחתית הנושא.\n\n-להגיב ל**אדם מסוים**, השתמש בפרסום שלהם. \n\n-להגיב עם **נושא חדש** השתמש ב מימין לתגובה. הנושא החדש והישן יקושרו ביחד. \n\nלהכניס ציטוט, בחר בטקסט שברצונך לצטט, ואז בחר בכל כפתור תגובה. חזור על כך שוב למספר ציטוטים!\n\n\n\nלידע מישהו בנוגע לתגובה שלך, הזכר את שמם. הקלד @ להתחיל\ - \ בבחירת שם משתמש. \n\n\n\nלהשתמש ב [standard Emoji](http://www.emoji.codes/), הקלד ':' להתאים על ידי שם, או השתמש בסמיילים סטנדרטים ';)'\n\n\n\nליצר תקציר לקישור, הדבק אותו בשורה משל עצמו:\n\n\n\n##פעולות\n\nישנם כפתורי פעולות בתחתית כל פרסום:\n\n\n\nבשביל לידע מישהו/י שנהנת מפרסום שלו/ה, השתמש בכפתור **לייק**. \n\nאם יש בעיה בפרסום של מישהו/י ידע\ - \ אותם או [צוות האתר](%{base_url}/about) באופן פרטי באמצעות כפתור **דגל**. תוכל/י גם **לחלוק** קישור לפרסום, או **לסמן** לשימוש עתידי בעמוד המשתמש שלך.\n\n## התראות\n\nכשמגיבים לך, מצטטים את הפרסום שלך או מזכירים את '@שם המשתמש' שלך, מספר יופיע ישר בחלק השמאלי העליון של העמוד. השתמש בו לגשת ל**התראות**\n\n\n\nאל תדאגו בנוגע לפספוס תגובה, ישלח אליכם מייל עם התראות שהגיעו כשלא היית באתר.\n\n- כל הנושאים בני פחות מ**יומיים** נחשבים חדשים. \n\n- כל נושא שהשתתפת בו באופן אקטיבי יוגדר למעקב – רגיל+ באופן אוטומטי. \n\n- תראו את המספרים הכחולים לנושאים חדשים ושלא נקראו ליד נושאים אלו:\n\n \n\nתוכלו לשנות את ההתראות שלכם לכל נושא דרך שליטה בהתראות שתחתית הנושא. \n\n\n\nתוכלו גם לקבוע מצב התראות עבור קטגוריה, אם ברצונכם לעקוב אחרי כל נושא חדש בקטגוריה מסוימת. \n\nבשביל לשנות אחד מההגדרות האלה, גש ל [your user preferences](%{base_url}/my/preferences).\n\n\n## אמון קהילתי\n\nככל שתשתתפו כאן, לאורך הזמן תצברו את אמון הקהילה, תהפכו לאזרח מן השורה, והגבלות למשתמשים חדשים יוסרו. [בדרגת אמון ](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924) גבוהה, תקבלו יכולות לעזור לנו בטיפוח הקהילה. \n" + text_body_template: "הינה מספר טיפים קצרים לעזור לך להתחיל:\n\n## קריאה\n\nלקרוא יותר, **פשו המשך לגלול למטה**\n\nכשתגובות או נושאים חדשים יגיעו, הם יופיעו באוםן אוטומטי – אין צורך לרענן את העמוד.\n\n##ניווט\n\n-לחיפוש השתמש בעמוד משתמש או בתפריט , השתמש ב**כפתורי אייקון משמשאל למעלה**\n\n-בחירת כותרת נושא תמיד תקח אותך ל**תגובה אחרונה שלא נקראה** בנושא. להכנס ללמעלה או למטה, בחר בספירת תגובות או תאריך פרסום אחרון.\n\n\n\n-בעת קריאה נושא, בחר בסרגל התקדמות מימין למטה לשליטה מלאה בניווט. עבור במהירות חזרה למעלה על ידי בחירה בכותרת הנושא. לחץ ? לרשימה של קיצורי מקלדת מהירים. \n\n\n## תגובה\n\n-להגיב ל**נושא באופן כללי**, השתמש בתחתית הנושא.\n\n-להגיב ל**אדם מסוים**, השתמש בפרסום שלהם. \n\n-להגיב עם **נושא חדש** השתמש ב מימין לתגובה. הנושא החדש והישן יקושרו ביחד. \n\nלהכניס ציטוט, בחר בטקסט שברצונך לצטט, ואז בחר בכל כפתור תגובה. חזור על כך שוב למספר ציטוטים!\n\n\n\nלידע מישהו בנוגע לתגובה שלך, הזכר את שמם. הקלד @ להתחיל בבחירת שם משתמש. \n\n\n\nלהשתמש ב [standard Emoji](http://www.emoji.codes/), הקלד ':' להתאים על ידי שם, או השתמש בסמיילים סטנדרטים ';)'\n\n\n\nליצר תקציר לקישור, הדבק אותו בשורה משל עצמו:\n\n\n\n##פעולות\n\nישנם כפתורי פעולות בתחתית כל פרסום:\n\n\n\nבשביל לידע מישהו/י שנהנת מפרסום שלו/ה, השתמש בכפתור **לייק**. \n\nאם יש בעיה בפרסום של מישהו/י ידע אותם או [צוות האתר](%{base_url}/about) באופן פרטי באמצעות כפתור **דגל**. תוכל/י גם **לחלוק** קישור לפרסום, או **לסמן** לשימוש עתידי בעמוד המשתמש שלך.\n\n## התראות\n\nכשמגיבים לך, מצטטים את הפרסום שלך או מזכירים את '@שם המשתמש' שלך, מספר יופיע ישר בחלק השמאלי העליון של העמוד. השתמש בו לגשת ל**התראות**\n\n\n\nאל תדאגו בנוגע לפספוס תגובה, ישלח אליכם מייל עם התראות שהגיעו כשלא היית באתר.\n\n- כל הנושאים בני פחות מ**יומיים** נחשבים חדשים. \n\n- כל נושא שהשתתפת בו באופן אקטיבי יוגדר למעקב – רגיל+ באופן אוטומטי. \n\n- תראו את המספרים הכחולים לנושאים חדשים ושלא נקראו ליד נושאים אלו:\n\n \n\nתוכלו לשנות את ההתראות שלכם לכל נושא דרך שליטה בהתראות שתחתית הנושא. \n\n\n\nתוכלו גם לקבוע מצב התראות עבור קטגוריה, אם ברצונכם לעקוב אחרי כל נושא חדש בקטגוריה מסוימת. \n\nבשביל לשנות אחד מההגדרות האלה, גש ל [your user preferences](%{base_url}/my/preferences).\n\n\n## אמון קהילתי\n\nככל שתשתתפו כאן, לאורך הזמן תצברו את אמון הקהילה, תהפכו לאזרח מן השורה, והגבלות למשתמשים חדשים יוסרו. [בדרגת אמון ](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924) גבוהה, תקבלו יכולות לעזור לנו בטיפוח הקהילה. \n" welcome_user: subject_template: "ברוכים הבאים ל %{site_name}!" text_body_template: | @@ -1712,3 +1706,6 @@ he: performance_report: initial_post_raw: 'נושא זה כולל דוחות פעילות יומיים עבור האתר שלך. ' initial_topic_title: דוחות פעילות לאתר + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.id.yml b/config/locales/server.id.yml index 19c8c01db5..9988698026 100644 --- a/config/locales/server.id.yml +++ b/config/locales/server.id.yml @@ -74,7 +74,6 @@ id: no_info_other: "
    %{name} belum mengisi kolom Tentang Saya untuk profilnya
    " category: topic_prefix: "Tentang kategori %{category}" - replace_paragraph: "[Ganti paragraf pertama ini dengan deskripsi singkat mengenai kategori baru Anda. Panduan ini akan muncul dalam area pemilihan kategori, cobalah untuk membuatnya kurang dari 200 karakter. Kategori ini tidak akan muncul dalam halaman kategori hingga Anda mengubah teks ini atau membuat topik.]" trust_levels: newuser: title: "pengguna baru" diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml index ab6349b801..38f229be86 100644 --- a/config/locales/server.it.yml +++ b/config/locales/server.it.yml @@ -21,7 +21,7 @@ it: purge_reason: "Cancellato automaticamente come account abbandonato e mai attivato" disable_remote_images_download_reason: "Lo scaricamento delle immagini remote è stato disabilitato perché non c'è abbastanza spazio disco disponibile." anonymous: "Anonimo" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "è limitato a %{max} caratteri; tu ne hai inseriti %{length}." @@ -226,6 +226,7 @@ it: attributes: hex: invalid: "non è un colore valido" + <<: *errors user_profile: no_info_me: "
    il campo \"Su di me\" del tuo profilo è vuoto, vuoi compilarlo?
    " no_info_other: "
    %{name} non ha ancora compilato il campo \"Su di me\" del suo profilo
    " @@ -241,8 +242,8 @@ it: body: "\nCongratulazioni! :confetti_ball: \n\nSe vedi questo argomento, sei stato recentemente promosso a **esperto** (livello di esperienza 3). \n\nAdesso puoi … \n\n* Modificare il titolo di qualunque argomento \n* Cambiare la categoria di qualunque argomento \n* Seguire tutti i tuoi collegamenti (è rimosso il [nofollow automatico](http://it.wikipedia.org/wiki/Nofollow) ) \n* Accedere alla categoria privata Lounge visibile solo agli utenti con livello di esperienza 3 o superiore \n* Cancellare i messaggi spam con un singolo clic\n\nEcco l'elenco degli altri [utenti esperti](/badges/3/regular). Vai a salutarli. \n\nGrazie per essere una parte importante di questa comunità! \n\n(Per maggiori informazioni sui livelli di esperienza, [leggi questa discussione][trust]. Nota che possono rimanere utenti esperti solo quegli utenti che continuano a soddisfare i criteri di selezione)\n\n[trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924\n" category: topic_prefix: "Definizione della categoria %{category}" - replace_paragraph: "[Sostituisci questo primo paragrafo con una breve descrizione della nuova categoria. Questa guida apparirà nell'area di selezione della categoria, perciò cerca di stare sotto i 200 caratteri. Finché non modifichi questo testo o non crei argomenti, questa categoria non apparirà sulla pagina delle categorie.]" - post_template: "%{replace_paragraph}\n\nUsa i paragrafi seguenti per una descrizione più estesa, ed anche per stabilire delle regole per la categoria o delle linee guida.\n\nAlcune cose da considerare in qualunque discussione sono:\n\n- A che serve questa categoria? Perché la gente dovrebbe scegliere questa categoria per i loro argomenti?\n\n- In cosa questa categoria è diversa dalle altre categorie già esistenti?\n\n- C'è bisogno di questa categoria?\n\n- Dovremmo fondere questa categoria con un'altra, oppure dividerla in più categorie?\n" + replace_paragraph: "(Sostituisci questo primo paragrafo con una breve descrizione della nuova categoria. Questa guida apparirà nell'area di selezione della categoria, perciò cerca di stare sotto i 200 caratteri. **Finché non modifichi questo testo o non crei argomenti, questa categoria non apparirà sulla pagina delle categorie.**)" + post_template: "%{replace_paragraph}\n\nUsa i seguenti paragrafi per una descrizione più estesa, ed anche per stabilire delle regole o linee guida per la categoria:\n\n- Perché la gente dovrebbe usare questa categoria? A che serve? \n\n- In cosa esattamente questa categoria è diversa dalle altre categorie già esistenti? \n\n- Cosa dovrebbero contenere gli argomenti in questa categoria? \n\n- C'è bisogno di questa categoria? Possiamo fonderla con un'altra categoria o sottocategoria?\n" errors: uncategorized_parent: "La categoria \"Non classificato\" non può avere una categoria superiore." self_parent: "La categoria-genitore di una sottocategoria non può essere se stessa." @@ -693,7 +694,6 @@ it: summary_likes_required: "Minimo numero di \"Mi piace\" in un argomento affinché venga abilitato 'Riassumi Questo Argomento'" summary_percent_filter: "Quando un utente clicca su 'Riassumi Questo Argomento', mostra i primi % messaggi" summary_max_results: "Massimo numero di messaggi mostrati in 'Riassumi Argomento'" - enable_private_messages: "Autorizza gli utenti con livello di esperienza 1 a creare e rispondere ai messaggi" enable_long_polling: "Il message bus per le notifiche può usare il long polling" long_polling_base_url: "URL di base usato per il long polling (quando una CDN serve contenuto dinamico, bisogna impostarlo come origin pull) es. http://origin.site.com" long_polling_interval: "Tempo di attesa prima che il server risponda ai client che non ci sono dati da trasmettere (solo per utenti autenticati)" @@ -1255,7 +1255,7 @@ it: %{base_url}/users/authorize-email/%{email_token} signup_after_approval: subject_template: "Sei stato ammesso su %{site_name}!" - text_body_template: "Benvenuto su %{site_name}! \n\nUn membro dello staff ha approvato il tuo account su %{site_name}. \n\nClicca sul seguente collegamento per confermare e attivare il tuo nuovo account:\n%{base_url}/users/activate-account/%{email_token} \n\nSe il collegamento qui sopra non è cliccabile, prova a copiarlo e incollarlo nella barra degli indirizzi del tuo browser. \n\n%{new_user_tips}\n\nNoi crediamo fermamente in un [comportamento comunitario civile](%{base_url}/guidelines) sempre.\n\nBuona permanenza!\n\n(Se hai bisogno di comunicare privatamente con i [membri dello staff](%{base_url}/about) come nuovo utente, rispondi semplicemente a questo messaggio privato.)\n" + text_body_template: "Benvenuto su %{site_name}! \n\nUn membro dello staff ha approvato il tuo account su %{site_name}. \n\nClicca sul seguente collegamento per confermare e attivare il tuo nuovo account:\n%{base_url}/users/activate-account/%{email_token} \n\nSe il collegamento qui sopra non è cliccabile, prova a copiarlo e incollarlo nella barra degli indirizzi del tuo browser. \n\n%{new_user_tips}\n\nNoi crediamo in un [comportamento comunitario civile](%{base_url}/guidelines), sempre.\n\nBuona permanenza!\n\nps: se vuoi comunicare privatamente con i [membri dello staff](%{base_url}/about) come nuovo utente, rispondi semplicemente a questo messaggio.\n" signup: text_body_template: | Benvenuto su %{site_name}! @@ -1329,3 +1329,6 @@ it: error: "Errore!" email_input: "Email Amministratore" submit_button: "Invia Email" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.ja.yml b/config/locales/server.ja.yml index 2c2a0e80c9..58cc043598 100644 --- a/config/locales/server.ja.yml +++ b/config/locales/server.ja.yml @@ -21,7 +21,7 @@ ja: purge_reason: "アクティブでないアカウントは放棄されたとして削除されました" disable_remote_images_download_reason: "ディスク容量が不足しているため、リモートでの画像ダウンロードは無効になっています。" anonymous: "匿名" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "は、最大文字数(%{max}文字)を超えています。(入力したのは%{length}文字 ) " @@ -215,6 +215,7 @@ ja: attributes: hex: invalid: "は有効なカラーではありません" + <<: *errors user_profile: no_info_me: "
    プロフィールの自己紹介フィールドが空欄のようです。自己紹介をしてみませんか?
    " no_info_other: "
    %{name} は、まだプロフィールの自己紹介フィールドに何も書いていません
    " @@ -229,8 +230,6 @@ ja: title: "ラウンジへようこそ" category: topic_prefix: "%{category} カテゴリの定義" - replace_paragraph: "[この最初のパラグラフを、本カテゴリの簡単な紹介文に置き換えてください。このガイダンスはカテゴリ選択エリアに表示されるため、パラグラフは200文字以内にしてください。]" - post_template: "%{replace_paragraph}\n\nこれ以降のパラグラフに、カテゴリのガイドライン等を書いてください。\n\nいくつかのヒント:\n\n- このカテゴリは何か? どのようなトピックをこのカテゴリに入れるべきか?\n\n- 既に存在するカテゴリとの違いは何か?\n\n- このカテゴリはなぜ必要か?\n\n- 他のカテゴリとの統合や、複数カテゴリへの分割をするべきか?\n" errors: uncategorized_parent: "未分類カテゴリは親カテゴリに設定出来ません。" self_parent: "自分自身がサブカテゴリの親になることはできません" @@ -655,7 +654,6 @@ ja: summary_likes_required: "'トピックサマリー'が有効になるために必要な最小「いいね!」数" summary_percent_filter: "ユーザが'トピックサマリー'をクリックしたとき, 上位何パーセントのポストを表示するか" summary_max_results: "'トピックサマリー'として返却される最大ポスト数" - enable_private_messages: "トラストレベル1のユーザーにプライベートメッセージの作成と返信を許可する" enable_long_polling: "通知用のメッセージバスによるロングポーリングの利用を許可する" long_polling_base_url: "ロングポーリングのベースURL(CDNが動的コンテンツを配信している場合、これをoriginに指定してください) eg: http://origin.site.com" long_polling_interval: "ユーザに送信するデータが存在しないとき、サーバが待機する時間(ログインユーザーのみ)" @@ -1289,8 +1287,7 @@ ja: (もし[スタッフメンバー](%{base_url}/about) に新規ユーザーとして連絡する必要がある場合、このメッセージに返信してください) welcome_invite: subject_template: "%{site_name}へようこそ!" - text_body_template: "ようこそ%{site_name} へ!\nあなたのアカウント**%{username}** を作成して、あなたはログインしています。\n氏名の変更は [your user profile][prefs] より行ってください。\n\n次回ログインするときは、\n\n1. かならず招待をうけたメールアドレスを使ってログインしてください。\n\n2.[your user profile][prefs]でパスワードを設定して、ログインのときはそれを使用してください。\n\n%{new_user_tips} [civilized community behavior](%{base_url}/guidelines)をお守りいただき、健全なコミュニティとなるよう皆様のご協力をお願いいたします。 \n\nそれではお楽しみください! \n\n(もし個人的に [staff members](%{base_url}/about)\ - \ と連絡を取る必要がある場合、このメッセージに返信してください)\n\n[prefs]: %{user_preferences_url}\n" + text_body_template: "ようこそ%{site_name} へ!\nあなたのアカウント**%{username}** を作成して、あなたはログインしています。\n氏名の変更は [your user profile][prefs] より行ってください。\n\n次回ログインするときは、\n\n1. かならず招待をうけたメールアドレスを使ってログインしてください。\n\n2.[your user profile][prefs]でパスワードを設定して、ログインのときはそれを使用してください。\n\n%{new_user_tips} [civilized community behavior](%{base_url}/guidelines)をお守りいただき、健全なコミュニティとなるよう皆様のご協力をお願いいたします。 \n\nそれではお楽しみください! \n\n(もし個人的に [staff members](%{base_url}/about) と連絡を取る必要がある場合、このメッセージに返信してください)\n\n[prefs]: %{user_preferences_url}\n" backup_succeeded: subject_template: "バックアップは正常に完了しました" text_body_template: "バックアップが成功しました。\n [admin > backup section](%{base_url}/admin/backups) から、バックアップをダウンロードしてください" @@ -1639,3 +1636,6 @@ ja: performance_report: initial_post_raw: このトピックでは、あなたのサイトの毎日のパフォーマンスレポートが含まれています。 initial_topic_title: ウェブサイトパフォーマンスレポート + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.ko.yml b/config/locales/server.ko.yml index 050cabe74c..da5b16d870 100644 --- a/config/locales/server.ko.yml +++ b/config/locales/server.ko.yml @@ -21,7 +21,7 @@ ko: purge_reason: "비활성화된 계정은 자동적으로 삭제됩니다." disable_remote_images_download_reason: "디스크저장공간이 부족하여 원격 이미지 다운로드 기능이 비활성화 되었습니다." anonymous: "익명" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "%{length}자를 입력하셨습니다. 최대 %{max}자까지 입력 가능합니다. " @@ -225,6 +225,7 @@ ko: attributes: hex: invalid: "유효한 색상이 아닙니다." + <<: *errors user_profile: no_info_me: "
    프로필이 현재 비어있습니다. 지금 작성하시겠습니까?
    " no_info_other: "
    %{name}님께서는 아직 프로필을 작성하지 않으셨습니다
    " @@ -242,8 +243,6 @@ ko: 축하합니다! :confetti_ball: 당신의 회원등급이 **지도자** (회원등급 3등급)로 올라갔기 때문에 이 글타래를 볼 수 있게 되었습니다. 이제부터 아래의 행동들을 할 수 있습니다 … * 글타래를 제목을 수정할 수 있습니다 * 글타래의 카테고리를 수정할 수 있습니다 * 링크가 follow로 처리됩니다 ([automatic nofollow](http://en.wikipedia.org/wiki/Nofollow) 가 제거됩니다) * 회원등급 3 이상인 사용자가 접근할 수 있는 비공개 카테고리인 라운지에 접근할 수 있습니다 * 좋아요와 신고의 가중치가 높아집니다 [정규 멤버 목록](/badges/3/regular)을 확인할 수 있습니다. 인사하는 것을 잊지마세요. 이 커뮤니티의 중요한 역할을 해주신 것에 감사드립니다! (회원등급에 관한 더 자세한 정보를 보시려면, [이 글타래를 확인하세요][trust]. 기준에 맞는 사람만 정규 회원으로 자격이 유지됩니다.) [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "'%{category}' 카테고리의 설명" - replace_paragraph: "[이 첫번째 문단을 당신의 새로운 카테고리의 짧은 설명으로 바꿔주세요. 이 지침은 카테고리 선택 화면에 나타날 것입니다. 200자 이하로 적어주세요.]" - post_template: "%{replace_paragraph}\n\n이 공간은 긴 설명을 사용하여 주세요. 또한 카테고리 가이드라인이나 룰도 이 공간을 이용해주세요.\n\n몇 가지 답글에 관련하여 고려해봐야 할 것들:\n\n- 무엇을 위한 카테고리인가? 왜 사용자들이 이 카테고리를 필요로 하겠는가?\n\n- 이미 가지고있는 다른 카테고리와 어떻게 다른가?\n\n- 정말 이 카테고리가 필요한가?\n\n- 다른 카테고리와 합병이 필요한가 아니면 더욱 자세한 카테고리로 나눌 필요가 있는가?\n" errors: uncategorized_parent: "Uncategorized 카테고리는 부모 카테고리를 가질 수 없습니다." self_parent: "하위 카테고리의 부모는 자신이 될 수 없습니다." @@ -652,7 +651,6 @@ ko: summary_likes_required: "하나의 글타래에 대하여 요약본 보기 모드가 활성화되기 전까지 요구되는 최소 좋아요 수" summary_percent_filter: "요약본 보기를 클릭시, 글 중에 몇 %의 상위 글을 보여줄 것인가?" summary_max_results: "이 주제에 대한 요약 글 최대 갯수" - enable_private_messages: "회원등급 1인 유저들에게 메세지 작성과 메세지 답변을 허용하기" enable_long_polling: "Message bus used for notification can use long polling" long_polling_base_url: "long polling에 사용 될 Base URL (CDN이 동적 콘텐트를 제공할 시에는 origin pull로 설정) eg: http://origin.site.com" long_polling_interval: "보낼 데이터가 없을 때 응답 전에 서버가 기다려야하는 시간 (로그인된 유저 전용)" @@ -1621,3 +1619,6 @@ ko: performance_report: initial_post_raw: 이 글타래는 웹사이트의 일일 성능 보고를 포함하고 있습니다. initial_topic_title: 웹사이트 성능 보고 + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.nb_NO.yml b/config/locales/server.nb_NO.yml index a135e49860..afdf78a8d1 100644 --- a/config/locales/server.nb_NO.yml +++ b/config/locales/server.nb_NO.yml @@ -21,7 +21,7 @@ nb_NO: purge_reason: "Automatisk slettet som som forlatt, uaktivert konto" disable_remote_images_download_reason: "Nedlasting av bilder ble deaktivert grunnet mangel på tilgjengelig diskplass." anonymous: "Anonym" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "er begrenset til %{max} karakterer; du brukte %{length}." @@ -224,6 +224,7 @@ nb_NO: attributes: hex: invalid: "er ikke en gyldig farge" + <<: *errors user_profile: no_info_me: "
    Om meg-feltet på din profil er for øyeblikket blankt, ønsker du å fylle det ut?
    " no_info_other: "
    %{name} har ikke skrevet noe i Om meg-feltet på sin profil ennå
    " @@ -259,7 +260,6 @@ nb_NO: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Om kategorien %{category} " - replace_paragraph: "[Erstatt dette første avsnittet med en kort beskrivelse av din nye kategori. Denne veiledningen vil vises i kategorivelgeren så prøv å hold den kortere enn 200 tegn. Frem til du redigerer denne teksten eller oppretter emner vil ikke denne kategorien vises på kategorisiden.]" errors: uncategorized_parent: "Ukategorisert kan ikke ha en foreldrekategori" self_parent: "En underkategori kan ikke være underlagt seg selv" @@ -805,3 +805,6 @@ nb_NO: csv_export: boolean_yes: "Ja" boolean_no: "Nei" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml index 9e177d56b3..a6afb3a005 100644 --- a/config/locales/server.nl.yml +++ b/config/locales/server.nl.yml @@ -21,7 +21,7 @@ nl: purge_reason: "Automatisch verwijderd, account is nooit geactiveerd" disable_remote_images_download_reason: "Het downloaden van plaatjes is uitgeschakeld omdat er niet genoeg schijfruimte beschikbaar is." anonymous: "Anoniem" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "is beperkt tot %{max} tekens; je gebruikt %{length}." @@ -199,9 +199,9 @@ nl: Hou je in de gaten dat anderen ook de ruimte krijgen om hun visie te geven? too_many_replies: | - ### Je hebt de reactielimiet bereikt voor deze topic + ### Je hebt de reactielimiet voor deze topic bereikt - Sorry, maar nieuwe gebruikers mogen tijdelijk niet meer dan %{newuser_max_replies_per_topic} reacties plaatsen in hetzelfde topic. + Sorry, maar nieuwe gebruikers mogen tijdelijk niet meer dan %{newuser_max_replies_per_topic} reacties plaatsen in het desbetreffende topic. Overweeg een eerdere reactie te wijzigen in plaats van nog een nieuwe reactie te plaatsen. reviving_old_topic: | @@ -242,16 +242,17 @@ nl: attributes: hex: invalid: "is niet een geldige kleur" + <<: *errors user_profile: no_info_me: "
    Het Over Mij-profielveld is nog leeg, zou je deze willen invullen?
    " no_info_other: "
    %{name} heeft nog niks in zijn of haar Over Mij-profielveld ingevuld
    " vip_category_name: "Lounge" vip_category_description: "Een categorie exclusief voor leden met trust level 3 en hoger." - meta_category_name: "Over Deze Site" + meta_category_name: "Site Feedback" meta_category_description: "Discussies over deze site, de organisatie, hoe het werkt en hoe het verbeterd kan worden." staff_category_name: "Staf" staff_category_description: "Privécategorie voor stafgesprekken. Topics zijn alleen zichtbaar voor admins en moderatoren." - assets_topic_body: "Dit is een permanent topic, alleen zichtbaar voor de staf, gebruikt voor het opslaan van afbeeldingen en bestanden die gebruikt worden in het design van de site. Gooi deze niet weg!\n\n\nHoe te gebruiken:\n\n\n1. Antwoord op dit topic.\n2. Upload hier alle afbeeldingen die je wenst te gebruiken voor logo's, favicons enzovoort. (Gebruik het upload icoon in de toolbar of sleep danwel plak afbeeldingen.)\n3. Verzend je bericht om het te posten.\n4. Klik met de rechtermuisknop op de afbeeldingen in je nieuwe bericht om het pad naar de geüploade afbeelding te krijgen, of klik het bewerken icoon om je bericht te wijzigen en zo het pad naar de afbeeldingen te verkrijgen. Kopieer het pad naar de afbeeldingen.\n5. Plak deze paden naar de afbeeldingen in [basic settings](/admin/site_settings/category/required).\n\n\nAls je andere bestandstypen wilt kunnen uploaden, moet je dit instellen in `authorized_extensions` in de [file settings](/admin/site_settings/category/files)." + assets_topic_body: "Dit is een permanent topic, dat alleen zichtbaar is voor de staf, en dient als opslag voor afbeeldingen en documenten die worden gebruikt in het design van de site . Gooi deze niet weg!\n\n\nHoe het werkt:\n\n\n1. Antwoord op dit topic.\n2. Upload hier alle afbeeldingen die je wenst te gebruiken als logo's, favicons enzovoort. (Gebruik het upload icoon in de toolbar, sleep afbeeldingen, of plak afbeeldingen.)\n3. Verzend je bericht om het te posten.\n4. Klik met de rechtermuisknop op de afbeeldingen in je nieuwe bericht om het pad naar de geüploade afbeelding te verkrijgen, of klik het bewerken icoon om je bericht te wijzigen en zo het pad naar de afbeeldingen te verkrijgen. Kopieer het pad naar de afbeeldingen.\n5. Plak deze paden naar de afbeeldingen in [basic settings](/admin/site_settings/category/required).\n\n\nAls je andere bestandstypen wilt kunnen uploaden, moet je dit instellen in `authorized_extensions` in de [file settings](/admin/site_settings/category/files)." lounge_welcome: title: "Welkom in de Lounge" body: |2 @@ -277,8 +278,6 @@ 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 regel met een korte omschrijving van je nieuwe categorie. Deze regel verschijnt in het selectiemenu als iemand een categorie kiest, dus hou het kort (max. 200 tekens). Deze categorie zal niet in de lijst verschijnen totdat je deze tekst wijzigt of zelf een topic in de categorie plaatst.]" - post_template: "%{replace_paragraph}\n\nGebruik de volgende alinea's voor een lange omschrijving en om wat verwachtingen en regels van deze categorie uit te leggen.\n\nZaken waar je het over kan hebben in de reacties hieronder:\n\n- Waar is deze categorie voor? Waarom zouden mensen deze categorie moeten kiezen voor hun topic?\n\n- Waarin verschilt deze categorie van de andere categorien die we al hebben?\n\n- Hebben we deze categorie echt nodig?\n\n- Moeten we deze categorie samenvoegen met een andere categorie, of juist opsplitsen?\n" errors: uncategorized_parent: "Ongecategoriseerd kan geen bovenliggende categorie hebben" self_parent: "Een categorie kan niet zijn eigen bovenliggende categorie zijn" @@ -286,7 +285,7 @@ nl: email_in_already_exist: "Inkomend email-adres '%{email_in}' is al in gebruik voor '%{category_name}' categorie." cannot_delete: uncategorized: "De categorie Ongecategoriseerd kan niet verwijderd worden" - has_subcategories: "Deze categorie kan niet verwijderd worden, omdat deze subcategorieën heeft" + has_subcategories: "Deze categorie kan niet verwijderd worden, omdat deze subcategorieën bevat" topic_exists: one: "Categorie kan niet verwijderd worden omdat het 1 topic heeft. Het oudste topic is %{topic_link}." other: "Categorie kan niet verwijderd worden omdat het %{count} topics heeft. Het oudste topic is %{topic_link}." @@ -304,7 +303,15 @@ 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: "u heeft deze actie te vaak uitgevoerd, probeer het later nog eens." 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 " + create_topic: "Je maakt te snel topics aan. Wacht a.u.b. %{time_left} voordat je het opnieuw probeert. " + create_post: "Je reageert te snel. Wacht a.u.b. %{time_left} voordat je het opnieuw probeert. " + topics_per_day: "Je hebt het maximum aantal nieuwe topics bereikt voor vandaag. Wacht a.u.b. %{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." hours: one: "1 uur" other: "%{count} uren" @@ -425,7 +432,7 @@ nl: notify_user: title: 'Stuur @{{username}} een bericht' description: 'Dit bericht bevat iets waarover ik je graag persoonlijk en privé wil spreken. Dit zet geen vlag.' - long_form: 'een bericht gestuurd aan gebruiker ' + long_form: 'gebruiker gecontacteerd' email_title: 'Uw bericht in ''%{title}''' email_body: "%{link}\n\n%{message}" notify_moderators: @@ -453,7 +460,7 @@ nl: long_form: 'markeerde dit als spam' inappropriate: title: 'Ongepast' - description: 'Dit topic bevat inhoud dat iemand als beledigend, discriminerend of kwetsend kan ervaren. Ook kan het een overtreding van de regels zijn.' + description: 'Dit topic bevat inhoud die een gemiddeld persoon als beledigend, kwetsend, of als een overtreding van de regels zou beschouwen.' long_form: 'markeerde dit als ongepast' notify_moderators: title: "Iets anders" @@ -626,7 +633,7 @@ nl: yaxis: "Aantal bezoeken" dashboard: rails_env_warning: "Je server draait in %{env} modus." - ruby_version_warning: "Je gebruikt een versie van Ruby 2.0.0 met problemen. Upgrade naar patch level 247 of later." + ruby_version_warning: "Je gebruikt een versie van Ruby 2.0.0 die wel vaker problemen geeft. Upgrade naar patch level 247 of later." host_names_warning: "Het bestand config/database.yml heeft localhost als standaard hostname. Verander dat in de hostname van je site." 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.' @@ -735,7 +742,6 @@ nl: summary_likes_required: "Minimum aantal Likes in een topic voor weergave ´Samenvatting Topic´" summary_percent_filter: "Als iemand op 'Samenvatting Topic' klikt, laat dan de top % van de berichten zien" summary_max_results: "Maximaal aantal berichten in weergave ´Samenvatting Topic´" - enable_private_messages: "Sta toe dat trust level 1 gebruikers berichten kunnen maken en kunnen antwoorden op berichten" enable_long_polling: "De 'message bus' die gebruikt wordt voor notificaties kan 'long polling' gebruiken." long_polling_base_url: "Basis URL voor ´long polling´ (indien via een CDN dynamische content wordt toegepast, kies hier dan 'origin pull´) b.v. http://originele.website.com" long_polling_interval: "De hoeveelheid tijd die de server zou moeten wachten voordat het clients beantwoord als er geen data te verzenden is (alleen voor ingelogde gebruikers)" @@ -914,8 +920,14 @@ nl: delete_all_posts_max: "Het maximaal aantal berichten dat ineens verwijderd kan worden met de 'Verwijder alle berichten'-knop. Als een gebruiker meer berichten heeft, kunnen de berichten niet in een keer verwijderd worden en kan de gebruiker dus niet verwijderd worden." username_change_period: "The number of days after registration that accounts can change their username (0 om wijziging niet toe te staan)." email_editable: "Gebruikers mogen hun e-mailadres na registratie nog wijzigen." + allow_uploaded_avatars: "Sta gebruikers toe eigen profielfoto's te uploaden." + allow_animated_avatars: "Sta gebruikers toe gif animaties als profielfoto te gebruiken. WAARSCHUWING: draai de avatars:refresh rake task na het aanpassen van deze instelling. " + automatically_download_gravatars: "Download Gravatars voor gebruikers bij account creatie of aanpassing van email." digest_topics: "Het maximum aantal topics dat in de e-maildigest opgenomen wordt." digest_min_excerpt_length: "Hoeveel karakters er per bericht getoond worden in de mail digest" + detect_custom_avatars: "Wel of niet te verifiëren of gebruikers eigen profielfoto's hebben geüpload. " + allow_anonymous_posting: "Sta gebruikers toe naar de anonimiteitsmodus over te schakelen." + anonymous_posting_min_trust_level: "minimum vertrouwensniveau benodigd om anoniem posten in te kunnen schakelen." allow_profile_backgrounds: "Gebruikers mogen een profielachtergrond instellen." enable_mobile_theme: "Mobiele apparaten gebruiken een mobiel-vriendelijke theme met de mogelijkheid te schakelen naar de volledige site. Schakel deze optie uit als je een eigen stylesheet wil gebruiken die volledig responsive is." suppress_uncategorized_badge: "Laat de badge niet zien voor topics zonder categorie in de topiclijsten." @@ -1434,3 +1446,6 @@ nl: performance_report: initial_post_raw: Deze topic bevat dagelijkse performance rapporten van je site initial_topic_title: Website performance rapporten + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.pl_PL.yml b/config/locales/server.pl_PL.yml index 7bcde12cf4..ae689f5466 100644 --- a/config/locales/server.pl_PL.yml +++ b/config/locales/server.pl_PL.yml @@ -21,7 +21,7 @@ pl_PL: purge_reason: "Automatycznie usunięto jako porzucone, nieaktywne konto" disable_remote_images_download_reason: "Pobieranie zewnętrznych grafik zostało wyłączone z uwagi na niską ilość wolnego miejsca na dysku." anonymous: "Anonim" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "ograniczono do %{max} znaków, podano %{length}." @@ -75,6 +75,7 @@ pl_PL: max_username_length_exists: "Nie możesz ustawić maksymalnej długości nazwy użytkownika poniżej najdłuższej nazwy użytkownika." max_username_length_range: "Nie możesz ustawić maksimum poniżej minimum." default_categories_already_selected: "Nie możesz wybrać kategorii użytej w innej liście." + s3_upload_bucket_is_required: "Nie możesz wysyłać na S3 jeżeli nie podasz 's3_upload_bucket'." bulk_invite: file_should_be_csv: "Wysłany plik powinien być w formacie CSV lub TXT." backup: @@ -238,6 +239,7 @@ pl_PL: attributes: hex: invalid: "nie jest poprawnym kolorem" + <<: *errors user_profile: no_info_me: "
    Pole O mnie w Twoim profilu jest obecnie puste, czy chcesz je wypełnić?
    " no_info_other: "
    %{name} jeszcze nie podał swojego opisu w profilu
    " @@ -273,8 +275,6 @@ pl_PL: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "O kategorii %{category}" - replace_paragraph: "[Zamień ten pierwszy paragraf na krórki opis nowej kategorii. Opis ten będzie wyświetlany na karcie wyboru kategorii, więc postaraj się utrzymać go poniżej 200 znaków. Póki nie zmienisz tego tekstu, ani nie utworzysz tematu, kategoria nie będzie wyświetlana na liście kategorii.]" - post_template: "%{replace_paragraph}\n\nW kolejnych paragrafach możesz umieścić dłuższy opis, oraz opisać zasady i zwyczaje jakie będą obowiązywać w tej kategorii. \n\nKilka rzeczy do rozważenia:\n\n- Czemu ma służyć ta kategoria? Dlaczego inni powinni wybierać tę kategorię dla swoich tematów?\n\n- Czym się różni od innych kategorii, które już mamy?\n\n- Czy potrzebujemy tej kategorii?\n\n- Czy powinniśmy ją połączyć z jakąś inną kategorią, lub podzielić na więcej kategorii?\n" errors: uncategorized_parent: "Inne nie mogą być podkategorią innej kategorii." self_parent: "Podkategoria nie może być swoim rodzicem" @@ -618,7 +618,9 @@ pl_PL: xaxis: "Dzień" yaxis: "Urządzenie zalogowane w zapytaniach API" page_view_anon_mobile_reqs: + title: "Anonimowe zapytania do API" xaxis: "Dzień" + yaxis: "Mobilne anonimowe zapytania do API" http_background_reqs: title: "Tło" xaxis: "Dzień" @@ -758,7 +760,6 @@ pl_PL: summary_likes_required: "Minimalna liczba polubień w temacie zanim 'Podsumowanie tematu' jest dostępne" summary_percent_filter: "Gdy użytkownik kliknie na 'Podsumowaniu tematu', pokaż % najlepszych wpisów" summary_max_results: "Maksymalna liczba wpisów w 'Podsumowaniu tematu'" - enable_private_messages: "Zezwalaj użytkownikom o 1 poziomie zaufania na tworzenie wiadomości i odpowiadanie na nie." enable_long_polling: "Message bus used for notification can use long polling" anon_polling_interval: "How often should anonymous clients poll in milliseconds" flags_required_to_hide_post: "Number of flags that cause a post to be automatically hidden and PM sent to the user (0 for never)" @@ -1384,3 +1385,6 @@ pl_PL: performance_report: initial_post_raw: 'Ten temat zawiera codzienne raporty wydajności dla twojej witryny. ' initial_topic_title: 'Testy wydajności witryny. ' + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.pt.yml b/config/locales/server.pt.yml index 1732af7fe2..9920d0b3ff 100644 --- a/config/locales/server.pt.yml +++ b/config/locales/server.pt.yml @@ -21,7 +21,7 @@ pt: purge_reason: "Automaticamente eliminado devido a abandono, conta inativada" disable_remote_images_download_reason: "O download remoto de imagens foi desativado por não haver espaço disponível no disco." anonymous: "Anónimo" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "está limitado a %{max} caracteres; inseriu %{length}." @@ -251,6 +251,7 @@ pt: attributes: hex: invalid: "não é uma cor válida" + <<: *errors user_profile: no_info_me: "
    o campo Sobre Mim do seu perfil está em branco, quer preenchê-lo?
    " no_info_other: "
    %{name} ainda não colocou nada no campo Sobre Mim
    " @@ -287,8 +288,8 @@ pt: category: topic_prefix: "Acerca da categoria %{category}" - replace_paragraph: "[Substituir este primeiro parágrafo, com uma breve descrição de sua nova categoria. Esta orientação será exibida na área de seleção de categoria, por isso tente mantê-la abaixo de 200 caracteres. Até editar este texto ou criar tópicos, esta categoria não aparece na página de categorias.]" - post_template: "%{replace_paragraph}\n\nUse os seguintes parágrados para uma descrição longa, assim como para estabelecer diretrizes ou regras da categoria.\n\nAlguns pontos a ter em consideração em qualquer resposta a uma discussão:\n\n- Para que serve esta categoria? Porque alguém usaria esta categoria no seu tópico?\n\n- Como é que esta categoria se difere das demais categorias já existentes?\n\n- Precisamos desta categoria?\n\n- Deveríamos juntar esta categoria com outra, ou dividir esta categoria em mais categorias?\n" + replace_paragraph: "(Substitua este primeiro parágrafo com uma breve descrição da sua nova categoria. Este guia irá aparecer na área de seleção da categoria, por isso tente mantê-lo abaixo dos 200 caracteres. **Até editar esta descrição ou criar tópicos, esta categoria não irá aparecer na página das categorias.**)" + post_template: "%{replace_paragraph}\n\nUtilize os seguintes parágrafos para uma descrição mais longa, ou para estabelecer diretrizes ou regras da categoria:\n\n- Porque devem as pessoas utilizar esta categoria? Para que serve?\n\n- No que difere ao certo em relação às outras categorias que já temos?\n\n- O que devem conter, de maneira geral, os tópicos desta categoria?\n\n- Precisamos desta categoria? Podemos juntá-la com outra categoria, ou subcategoria?\n" errors: uncategorized_parent: "Sem categoria não podem ter categorias de nível superior" self_parent: "Uma subcategoria não pode ser superior a ela própria" @@ -757,7 +758,7 @@ pt: summary_likes_required: "Número mínimo de gostos num tópico antes que 'Resumir Este Tópico' seja ativo." summary_percent_filter: "Quando um utilizador clica em 'Resumir Este Tópico', mostrar as melhores % de mensagens" summary_max_results: "Número máximo de mensagens devolvidas por 'Resumo deste Tópico'" - enable_private_messages: "Permitir que utilizadores de nível de confiança 1 possam criar e responder a mensagens" + enable_private_messages: "Permitir que utilizadores de nível de confiança 1 (configurável através do nível de confiança mínimo para enviar mensagens) criem mensagens e respostas a mensagens." enable_long_polling: "O sistema de mensagens usado para notificações pode fazer solicitações longas" long_polling_base_url: "URL base usada para solicitação ao servidor (quando um CDN serve conteúdo dinâmico, certifique-se de configurá-lo para a 'pull' original) ex: http://origem.sítio.com" long_polling_interval: "Quantidade de tempo que um servidor deve esperar antes de notificar os clientes quando não há dados para serem enviados (apenas utilizadores ligados)" @@ -889,6 +890,7 @@ pt: avatar_sizes: "Lista de tamanhos de avatar gerados automaticamente." external_system_avatars_enabled: "Utilize o serviço do sistema externo de avatars." external_system_avatars_url: "URL do serviço do sistema externo de avatars. Substituições permitidas são {nome_de_utilizador} {primeira_letra} {cor} {tamanho}" + default_opengraph_image_url: "URL da imagem opengraph por defeito." enable_flash_video_onebox: "Ativar a incorporação de hiperligações swf e flv (Adobe Flash) em caixas únicas. AVISO: pode introduzir riscos de segurança." default_invitee_trust_level: "Nível de Confiança padrão (0-4) para utilizadores convidados." default_trust_level: "Nível de Confiança padrão (0-4) para todos os novos utilizadores. AVISO! Alterar isto irá colocá-lo em sério risco de spam." @@ -915,6 +917,7 @@ pt: tl3_links_no_follow: "Não remover rel=nofollow das hiperligações publicadas por utilizadores com Nível de Confiança 3." min_trust_to_create_topic: "O Nível de Confiança mínimo necessário para criar um novo tópico." min_trust_to_edit_wiki_post: "O nível mínimo de confiança necessário para editar mensagens marcadas como wiki." + min_trust_to_send_messages: "O nível de confiança mínimo necessário para criar mensagens privadas." newuser_max_links: "Quantas hiperligações um novo utilizador pode adicionar a uma mensagem." newuser_max_images: "Quantas imagens um novo utilizador pode adicionar a uma mensagem." newuser_max_attachments: "Quantos anexos um novo utilizador pode adicionar a uma mensagem." @@ -1011,6 +1014,7 @@ pt: allow_anonymous_posting: "Permitir que os utilizadores alterem para o modo anónimo" anonymous_posting_min_trust_level: "Nível de confiança mínimo necessário para ativar publicações anónimas" anonymous_account_duration_minutes: "Para proteger o anonimato crie uma nova conta anónima a cada N minutos para cada utilizador. Exemplo: se configurado para 600, assim que passarem 600 minutos desde a última mensagem E o utilizador altere para anónimo, uma nova conta anónima é criada." + hide_user_profiles_from_public: "Desativar cartões de utilizador, perfis de utilizador e diretoria de utilizadores para utilizadores anónimos." allow_profile_backgrounds: "Permitir que os utilizadores carreguem fundos de perfil." sequential_replies_threshold: "Número de mensagens que um utilizador tem que fazer em linha num tópico antes de ser relembrado acerca de demasiadas respostas sequenciais." enable_mobile_theme: "Os dispositivos móveis usam um tema mobile-friendly, com a possibilidade de mudar para o sítio completo. Desative isto se quer usar um estilo personalizado que é totalmente responsivo." @@ -1036,6 +1040,7 @@ pt: embed_username_key_from_feed: "Chave para recuperar o nome de utilizador discourse do feed." embed_truncate: "Truncar mensagens incorporadas." embed_post_limit: "Número máximo de mensagens a serem incorporadas." + embed_username_required: "O nome de utilizador para a criação de tópico é necessário." embed_whitelist_selector: "Seletor CSS para elementos permitidos em incorporações." embed_blacklist_selector: "Seletor CSS para elementos que foram removidos de incorporações." notify_about_flags_after: "Se houver sinalizações que não tenham sido tratadas após tantas horas, envie um email para 'contact_email'. Configurar a 0 para desativar." @@ -1240,8 +1245,7 @@ pt: (Se a hiperligação acima tiver expirado, escolha "Esqueci a minha palavra-passe" ao iniciar sessão com o seu endereço de email.) test_mailer: subject_template: "[%{site_name}] Teste de entrega de email" - text_body_template: "Este é um email de teste de\n\n[**%{base_url}**][0]\n\nA entrega do email é complicada. Aqui estão alguns pontos importantes a verificar primeiro:\n\n - *Certifique-se* que configurou o `email de notificação` de: endereço correto nas configurações do seu sítio. **O domínio especificado no endereço “de” nos emails que envia é o domínio que será validado**. \n\n- Conhecer como observar o código fonte dos emails no seu email cliente, de modo a que possa examinar cabeçalhos de email à procura de pistas importantes. No Gmail, é a opção “mostrar original” no menu drop down no canto superior direito de cada email.\n\n- **IMPORTANTE:** O seu ISP tem um registo de DNS inverso inserido para associar os nomes de domínio aos endereços IP de onde envia o seu email? [Teste o seu registo de PTR Inverso][2] aqui. Se o seu ISP não inserir o DNS inverso apropriado, é muito improvável que qualquer um dos seus emails seja entregue.\n\n- Estará o seu domínio [registo SPF][8] correto? [Teste o seu registo SPF][1] aqui. Note que TXT é o tipo de registo oficial para SPF. \n\n- Estará o seu domínio [registo DKIM][3] correto? Isto irá melhorar significativamente a entrega de emails. [Teste o seu registo DKIM][7] aqui.\n\n- Se correr o seu próprio servidor de email, certifique-se que os IPs do seu servidor de email não [estão em nenhuma lista negra de email] [4]. Verifique também que é enviado um nome de servidor qualificado que resolve o DNS na sua mensagem HELO. Se não for, isto irá fazer com que o seu email seja rejeitado por muitos serviços de email.\n\n(A maneira *fácil* é criar uma conta gratuita em [Mandrill][md] ou [Mailgun][mg] ou [Mailjet][mj], que tem vários planos de email gratuitos e será bom para pequenas comunidades. Irá precisar na mesma de configurar os registos SPF e o DKIM no seu DNS!) \n\nEsperamos que tenha recebido este teste de entrega de email sem problemas! \n\nBoa sorte, \n\nOs seus amigos em [Discourse](http://www.discourse.org)\n\n[0]: %{base_url}\n[1]: http://www.kitterman.com/spf/validate.html\n[2]: http://mxtoolbox.com/ReverseLookup.aspx\n[3]: http://www.dkim.org/\n[4]: http://whatismyipaddress.com/blacklist-check\n\ - [7]: http://dkimcore.org/tools/dkimrecordcheck.html\n[8]: http://www.openspf.org/SPF_Record_Syntax\n[md]: http://mandrill.com\n[mg]: http://www.mailgun.com/\n[mj]: https://www.mailjet.com/pricing\n" + text_body_template: "Este é um email de teste de\n\n[**%{base_url}**][0]\n\nA entrega do email é complicada. Aqui estão alguns pontos importantes a verificar primeiro:\n\n - *Certifique-se* que configurou o `email de notificação` de: endereço correto nas configurações do seu sítio. **O domínio especificado no endereço “de” nos emails que envia é o domínio que será validado**. \n\n- Conhecer como observar o código fonte dos emails no seu email cliente, de modo a que possa examinar cabeçalhos de email à procura de pistas importantes. No Gmail, é a opção “mostrar original” no menu drop down no canto superior direito de cada email.\n\n- **IMPORTANTE:** O seu ISP tem um registo de DNS inverso inserido para associar os nomes de domínio aos endereços IP de onde envia o seu email? [Teste o seu registo de PTR Inverso][2] aqui. Se o seu ISP não inserir o DNS inverso apropriado, é muito improvável que qualquer um dos seus emails seja entregue.\n\n- Estará o seu domínio [registo SPF][8] correto? [Teste o seu registo SPF][1] aqui. Note que TXT é o tipo de registo oficial para SPF. \n\n- Estará o seu domínio [registo DKIM][3] correto? Isto irá melhorar significativamente a entrega de emails. [Teste o seu registo DKIM][7] aqui.\n\n- Se correr o seu próprio servidor de email, certifique-se que os IPs do seu servidor de email não [estão em nenhuma lista negra de email] [4]. Verifique também que é enviado um nome de servidor qualificado que resolve o DNS na sua mensagem HELO. Se não for, isto irá fazer com que o seu email seja rejeitado por muitos serviços de email.\n\n(A maneira *fácil* é criar uma conta gratuita em [Mandrill][md] ou [Mailgun][mg] ou [Mailjet][mj], que tem vários planos de email gratuitos e será bom para pequenas comunidades. Irá precisar na mesma de configurar os registos SPF e o DKIM no seu DNS!) \n\nEsperamos que tenha recebido este teste de entrega de email sem problemas! \n\nBoa sorte, \n\nOs seus amigos em [Discourse](http://www.discourse.org)\n\n[0]: %{base_url}\n[1]: http://www.kitterman.com/spf/validate.html\n[2]: http://mxtoolbox.com/ReverseLookup.aspx\n[3]: http://www.dkim.org/\n[4]: http://whatismyipaddress.com/blacklist-check\n[7]: http://dkimcore.org/tools/dkimrecordcheck.html\n[8]: http://www.openspf.org/SPF_Record_Syntax\n[md]: http://mandrill.com\n[mg]: http://www.mailgun.com/\n[mj]: https://www.mailjet.com/pricing\n" new_version_mailer: subject_template: "[%{site_name}] Nova versão Discourse, atualização disponível" text_body_template: "Uma nova versão de [Discourse](http://www.discourse.org) está disponível. \n\nA sua versão: %{installed_version}\nNova versão: **%{new_version}**\n\nPode desejar: \n\n- Ver o que há de novo em [GitHub changelog](https://github.com/discourse/discourse/commits/master).\n\n- Atualizar a partir do seu navegador em [%{base_url}/admin/upgrade](%{base_url}/admin/upgrade).\n\n- Visitar [meta.discourse.org](http://meta.discourse.org) para notícias, debates, e suporte para o Discourse.\n" @@ -1283,9 +1287,7 @@ pt: subject_template: "Mensagem oculta devido a sinalizações da comunidade" text_body_template: "Olá,\n\nEsta é uma mensagem automática de %{site_name} para informá-lo que a sua mensagem foi oculta. \n\n%{base_url}%{url} \n\n%{flag_reason}\n\nMúltiplos membros da comunidade sinalizaram esta mensagem antes de ser escondida, por isso considere como poderá rever a sua mensagem para refletir o seu feedback. **Pode editar a sua mensagem após %{edit_delay} minutos, e esta será automaticamente exibida.**\n\nContudo, se a mensagem for escondida pela comunidade uma segunda vez, irá manter-se escondida até ser tratada pelo pessoal – e poderão ainda ocorrer ações, incluindo uma possível suspensão da sua conta.\n\nPara orientação adicional, por favor consulte as [diretrizes da comunidade](%{base_url}/guidelines).\n" usage_tips: - text_body_template: "Aqui ficam algumas dicas para que possa começar: \n\n## Leitura\n\nPara ler mais, **simplesmente continue a arrastar para baixo!**\n\nÀ medida que novas mensagens ou novos tópicos vão chegando, estes irão surgir automaticamente – não é necessário atualizar a página. \n\n## Navegação \n\n- Para pesquisar, a sua página de utilizador, ou o menu , utilize **o ícone no canto superior direito**. \n\n- Selecionar o título de um tópico irá levá-lo sempre à **próxima mensagem não lida** no tópico. Para inserir no início ou no final, selecione a contagem de respostas ou alternativamente, a data da última resposta. \n\n\n\n - Ao ler um tópico, selecione a barra de progresso no canto inferior direito para controlos de navegação completos. Salte rapidamente para o topo ao selecionar o título do tópico. Pressione ? para uma lista rápida de atalhos do teclado. \n\n\n\n## Responder \n\n– Para responder ao **tópico em geral**, utilize no final de cada tópico. \n\n- Para responder a uma **pessoa específica**, utilize nas suas mensagens. \n\n- Para responder com um **novo tópico**, utilize à direita desta mensagem. Tanto os tópicos antigos como os novos serão ligados automaticamente. \n\nPara inserir uma citação, selecione o texto que deseja citar e de seguida pressione qualquer botão de Resposta. Repetir para múltiplas citações! \n\n\n\nPara notificar alguém da sua resposta, mencione o seu nome. Digite `@` para começar a selecionar um nome de utilizador. \n\n\n\nPara utilizar [Emoji padrão](http://www.emoji.codes/), simplesmente digite `:` para encontrar por nome, ou os tradicionais risonhos `;)` \n\n\n\nPara gerar um sumário para uma hiperligação, cole-o numa linha por si só:\n\n\n\n## Ações \n\nExistem botões de ação no final de cada mensagem. \n\n\n\nPara deixar alguém saber que gostou e apreciou as suas mensagens, utilize o botão **gosto**. Partilhe o amor! \n\nSe vir um problema com uma mensagem de alguém, avise a pessoa em privado, ou avise [o nosso pessoal](%{base_url}/about), sobre a mesma utilizando o botão **sinalizar**. Pode também **partilhar** uma hiperligação para uma mensagem, ou **marcá-la** para mais tarde ter a referência na sua página de utilizador. \n\n## Notificações \n\nQuando alguém lhe responde, cita a sua mensagem ou menciona o seu `@nome-de-utilizador`, um número irá aparecer imediatamente no canto superior direito na página. Utilize-o para aceder às suas **notificações**. \n\n\n\n Não se preocupe em falhar uma resposta – irá receber notificações por email que chegam quando está ausente. \n\n## As Suas Preferências \n\n- Todos os tópicos com menos de **dois dias** são considerados novos. \n\n- Qualquer tópico em que tenha **participado ativamente** (respondido, criado, ou lido por um extenso período) será acompanhado automaticamente. \n\nVerá o indicador numérico e o indicador azul (novo) junto desses tópicos: \n\n \n\nPode alterar as suas notificações para qualquer tópico através do controlo de notificações no final do tópico.\n\n\n\nPode também configurar\ - \ estados de notificação por categoria, se quer observar cada novo tópico numa categoria específica. \n\nPara alterar qualquer uma destas configurações, consulte [as suas preferências] (%{base_url}/my/preferences). \n\n##Confiança da Comunidade \n\nÀ medida que for participando aqui, irá ganhar confiança por parte da comunidade, tornar-se um cidadão completo e limitações de novos utilizadores serão automaticamente removidas. Com um [nível de confiança] suficientemente alto (https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), irá ganhar novas capacidades para ajudar-nos a gerir a comunidade em conjunto.\n" + text_body_template: "Aqui ficam algumas dicas para que possa começar: \n\n## Leitura\n\nPara ler mais, **simplesmente continue a arrastar para baixo!**\n\nÀ medida que novas mensagens ou novos tópicos vão chegando, estes irão surgir automaticamente – não é necessário atualizar a página. \n\n## Navegação \n\n- Para pesquisar, a sua página de utilizador, ou o menu , utilize **o ícone no canto superior direito**. \n\n- Selecionar o título de um tópico irá levá-lo sempre à **próxima mensagem não lida** no tópico. Para inserir no início ou no final, selecione a contagem de respostas ou alternativamente, a data da última resposta. \n\n\n\n - Ao ler um tópico, selecione a barra de progresso no canto inferior direito para controlos de navegação completos. Salte rapidamente para o topo ao selecionar o título do tópico. Pressione ? para uma lista rápida de atalhos do teclado. \n\n\n\n## Responder \n\n– Para responder ao **tópico em geral**, utilize no final de cada tópico. \n\n- Para responder a uma **pessoa específica**, utilize nas suas mensagens. \n\n- Para responder com um **novo tópico**, utilize à direita desta mensagem. Tanto os tópicos antigos como os novos serão ligados automaticamente. \n\nPara inserir uma citação, selecione o texto que deseja citar e de seguida pressione qualquer botão de Resposta. Repetir para múltiplas citações! \n\n\n\nPara notificar alguém da sua resposta, mencione o seu nome. Digite `@` para começar a selecionar um nome de utilizador. \n\n\n\nPara utilizar [Emoji padrão](http://www.emoji.codes/), simplesmente digite `:` para encontrar por nome, ou os tradicionais risonhos `;)` \n\n\n\nPara gerar um sumário para uma hiperligação, cole-o numa linha por si só:\n\n\n\n## Ações \n\nExistem botões de ação no final de cada mensagem. \n\n\n\nPara deixar alguém saber que gostou e apreciou as suas mensagens, utilize o botão **gosto**. Partilhe o amor! \n\nSe vir um problema com uma mensagem de alguém, avise a pessoa em privado, ou avise [o nosso pessoal](%{base_url}/about), sobre a mesma utilizando o botão **sinalizar**. Pode também **partilhar** uma hiperligação para uma mensagem, ou **marcá-la** para mais tarde ter a referência na sua página de utilizador. \n\n## Notificações \n\nQuando alguém lhe responde, cita a sua mensagem ou menciona o seu `@nome-de-utilizador`, um número irá aparecer imediatamente no canto superior direito na página. Utilize-o para aceder às suas **notificações**. \n\n\n\n Não se preocupe em falhar uma resposta – irá receber notificações por email que chegam quando está ausente. \n\n## As Suas Preferências \n\n- Todos os tópicos com menos de **dois dias** são considerados novos. \n\n- Qualquer tópico em que tenha **participado ativamente** (respondido, criado, ou lido por um extenso período) será acompanhado automaticamente. \n\nVerá o indicador numérico e o indicador azul (novo) junto desses tópicos: \n\n \n\nPode alterar as suas notificações para qualquer tópico através do controlo de notificações no final do tópico.\n\n\n\nPode também configurar estados de notificação por categoria, se quer observar cada novo tópico numa categoria específica. \n\nPara alterar qualquer uma destas configurações, consulte [as suas preferências] (%{base_url}/my/preferences). \n\n##Confiança da Comunidade \n\nÀ medida que for participando aqui, irá ganhar confiança por parte da comunidade, tornar-se um cidadão completo e limitações de novos utilizadores serão automaticamente removidas. Com um [nível de confiança] suficientemente alto (https://meta.discourse.org/t/what-do-user-trust-levels-do/4924), irá ganhar novas capacidades para ajudar-nos a gerir a comunidade em conjunto.\n" welcome_user: subject_template: "Bem-vindo a %{site_name}!" text_body_template: | @@ -1301,7 +1303,7 @@ pt: welcome_invite: subject_template: "Bem-vindo a %{site_name}!" text_body_template: | - Obrigado por ter aceite o convite para %{site_name} -- bem-vindo! + Obrigado por ter aceitado o convite para %{site_name} -- bem-vindo! Criámos uma nova conta **%{username}** para si, e neste momento encontra-se com sessão iniciada. Pode mudar o seu nome ao visitar [o seu perfil de utilizador][prefs]. @@ -1739,25 +1741,13 @@ pt: Edite a primeira mensagem neste tópico para alterar os conteúdos da página %{page_name}. guidelines_topic: title: "FAQ/Diretrizes" - body: "\n\n## [Este é um Local Civilizado para Discussão Pública](#civilizado) \n\nPor favor trate este fórum de discussão com o mesmo respeito com que trataria um parque público. Nós somos também uma comunidade de partilha de recursos — um local para partilhar habilidades, conhecimento e interesses através de conversações. \n\nEstas não são regras rígidas e rápidas, meramente ajuda para o julgamento humano da nossa comunidade. Utilize estas diretrizes para manter este local limpo e iluminado para discussões públicas civilizadas. \n\n\n\n## [Melhorar a Discussão](#melhorar) \n\nAjude-nos a fazer deste um óptimo local para debates ao trabalhar constantemente para melhorar esses debates de alguma maneira, mesmo que pequena. Se não tem a certeza que a sua mensagem adiciona algo à conversação, pense novamente no que quer dizer e tente novamente mais tarde. \n\nOs tópicos discutidos aqui têm importância para nós, e queremos agir como se também fossem importantes para si. Seja respeitador dos tópicos e das pessoas que o debatem, mesmo que discorde do que está a ser dito. \n\nUma maneira de melhorar o debate é descobrindo os que já estão a ocorrer. Por favor perca algum tempo a pesquisar os tópicos existentes aqui antes de responder ou começar um novo, e terá melhores hipóteses de conhecer outros que partilhem os mesmos interesses que você. \n\n\n\n ## [Seja Agradável, Mesmo Que Discorde](#agradável) \n\nPode desejar responder a algo ao discordar do mesmo. Não há qualquer problema nisso. Mas lembre-se de _criticar ideias, não pessoas_. Por favor, evite: \n\n*Chamar Nomes. \n*Adicionar ataques pessoais. \n* Responder ao tom de uma mensagem e não ao seu conteúdo. \n*Contradições instintivas \n\nPelo contrário, forneça contra-argumentos que melhorem a conversação. \n\n\n\n## [A Sua Participação Conta](#participe) \n\nAs conversações que temos aqui definem o tom para toda a gente. Ajude-nos a influenciar o futuro desta comunidade ao escolher comprometer-se nos debates que tornam este fórum um local interessante\ - \ para se estar — e evite os que não o fazem. \n\nO Discourse fornece ferramentas que permitem que a comunidade identifique as melhores (e piores) contribuições: favoritos, marcadores, gostos, sinalizações, respostas, edições, e por aí em diante. Utilize estas ferramentas para melhorar a sua própria experiência e de todos os outros também.\n\nVamos tentar deixar o nosso parque melhor do que quando o encontrámos. \n\n\n\n ## [Se vir um Problema, Sinalize-o](#sinalize-problemas) \n\nOs moderadores têm uma autoridade especial; estes são responsáveis por este fórum. Assim como você o é. Com a sua ajuda, os moderadores podem ser facilitadores da comunidade, não apenas zeladores ou polícias. \n\nQuando vir mau comportamento, não responda. O reconhecimento encoraja o mau comportamento, consome a sua energia e gasta o tempo de todos. Apenas sinalize-o. Se houver sinalizações suficientes, ações irão ser tomadas, seja automaticamente ou por intervenção dos moderadores.\n\nDe maneira a manter a ordem da comunidade, os moderadores reservam-se ao direito de remover qualquer conteúdo e qualquer conta de utilizador por qualquer razão em qualquer altura. Os moderadores não prevêem novas mensagens em qualquer maneira; os moderadores e os operadores do sítio não têm qualquer responsabilidade por qualquer conteúdo publicado pela comunidade. \n\n\n\n## [Seja sempre civilizado](#seja-civilizado) \n\nNada estraga mais uma conversação saudável do que insolências: \n\n*Seja civilizado. Não publique nada que uma pessoa sensata consideraria ofensiva, abusiva ou de ódio. \n*Mantenha-o limpo. Não publique nada obsceno ou sexualmente explicito.\n*Respeite os outros. Não assedie ou magoe ninguém, não personifique pessoas, e não exponha as suas informações pessoais. \n*Respeite o fórum. Não publique spam ou qualquer outra coisa que vandalize o fórum. \n\nEstes não são termos concretos com definições precisas — evite até a _aparência_ de qualquer uma destas coisas. Se não tem certeza, pergunte-se a si próprio como se sentiria se a sua mensagem fosse capa do New York Times.\ - \ \n\nEste é um fórum público, e motores de pesquisa indexam estes debates. Mantenha a linguagem, hiperligações e imagens seguras para família e amigos. \n\n\n\n## [Mantenha-o Organizado](#manter-organizado) \n\nFaça o esforço para colocar as coisas no local certo, para que possamos passar mais tempo a debater e menos a limpar. Por isso: \n\n*Não comece um tópico na categoria errada. \n*Não cruze mensagens sobre o mesmo tema em múltiplos tópicos. \n*Não publique respostas sem conteúdo. \n*Não desvie um tópico ao mudar o seu centro de atenção. \n*Não assine as suas mensagens — qualquer mensagem tem a sua informação de perfil anexada à mesma. \n\nEm vez de publicar “+1” ou “Concordo”, utilize o botão Gosto. Em vez de levar um tópico existente para uma direção completamente diferente, utilize Responder como Novo Tópico. \n\n\n \n## [Publique Apenas As Suas Próprias Coisas](#roubo) \n\nNão pode publicar nada digital que pertença a qualquer outra pessoa, sem a sua permissão. Não pode publicar descrições de, hiperligações a, ou métodos para roubar propriedade intelectual de outras pessoas (software, vídeo, áudio, imagens), ou para quebrar qualquer outra lei. \n\n\n## [Patrocinado Por Si](#poder) \n\nEste sítio é operado pelos seus [membros locais amigáveis](/sobre) e por *si*, a comunidade. Se tem alguma questão adicional sobre como as coisas funcionam por aqui, abra um novo tópico em [site feedbackcategory](/c/site-feedback) e iremos debatê-lo. Se ocorrer algum assunto crítico ou urgente que pode ser tratado por um tópico meta ou por uma sinalização, contacte-nos através do [página do pessoal](/sobre). \n\n \n\n## [Termos de Serviço](#tds) \n\nSim, a legalidade é chata, mas temos que nos proteger – e por extensão, protegê-lo a si e aos seus dados – contra companheiros inimigos. Temos os [Termos de Serviço](/tds) que descrevem o seu (e o nosso) comportamento e direitos relativamente a conteúdo, privacidade e leis. Para usar este serviço tem que concordar em cumprir os nossos [TDS](/tds).\n" + body: "\n\n## [Este é um Local Civilizado para Discussão Pública](#civilizado) \n\nPor favor trate este fórum de discussão com o mesmo respeito com que trataria um parque público. Nós somos também uma comunidade de partilha de recursos — um local para partilhar habilidades, conhecimento e interesses através de conversações. \n\nEstas não são regras rígidas e rápidas, meramente ajuda para o julgamento humano da nossa comunidade. Utilize estas diretrizes para manter este local limpo e iluminado para discussões públicas civilizadas. \n\n\n\n## [Melhorar a Discussão](#melhorar) \n\nAjude-nos a fazer deste um óptimo local para debates ao trabalhar constantemente para melhorar esses debates de alguma maneira, mesmo que pequena. Se não tem a certeza que a sua mensagem adiciona algo à conversação, pense novamente no que quer dizer e tente novamente mais tarde. \n\nOs tópicos discutidos aqui têm importância para nós, e queremos agir como se também fossem importantes para si. Seja respeitador dos tópicos e das pessoas que o debatem, mesmo que discorde do que está a ser dito. \n\nUma maneira de melhorar o debate é descobrindo os que já estão a ocorrer. Por favor perca algum tempo a pesquisar os tópicos existentes aqui antes de responder ou começar um novo, e terá melhores hipóteses de conhecer outros que partilhem os mesmos interesses que você. \n\n\n\n ## [Seja Agradável, Mesmo Que Discorde](#agradável) \n\nPode desejar responder a algo ao discordar do mesmo. Não há qualquer problema nisso. Mas lembre-se de _criticar ideias, não pessoas_. Por favor, evite: \n\n*Chamar Nomes. \n*Adicionar ataques pessoais. \n* Responder ao tom de uma mensagem e não ao seu conteúdo. \n*Contradições instintivas \n\nPelo contrário, forneça contra-argumentos que melhorem a conversação. \n\n\n\n## [A Sua Participação Conta](#participe) \n\nAs conversações que temos aqui definem o tom para toda a gente. Ajude-nos a influenciar o futuro desta comunidade ao escolher comprometer-se nos debates que tornam este fórum um local interessante para se estar — e evite os que não o fazem. \n\nO Discourse fornece ferramentas que permitem que a comunidade identifique as melhores (e piores) contribuições: favoritos, marcadores, gostos, sinalizações, respostas, edições, e por aí em diante. Utilize estas ferramentas para melhorar a sua própria experiência e de todos os outros também.\n\nVamos tentar deixar o nosso parque melhor do que quando o encontrámos. \n\n\n\n ## [Se vir um Problema, Sinalize-o](#sinalize-problemas) \n\nOs moderadores têm uma autoridade especial; estes são responsáveis por este fórum. Assim como você o é. Com a sua ajuda, os moderadores podem ser facilitadores da comunidade, não apenas zeladores ou polícias. \n\nQuando vir mau comportamento, não responda. O reconhecimento encoraja o mau comportamento, consome a sua energia e gasta o tempo de todos. Apenas sinalize-o. Se houver sinalizações suficientes, ações irão ser tomadas, seja automaticamente ou por intervenção dos moderadores.\n\nDe maneira a manter a ordem da comunidade, os moderadores reservam-se ao direito de remover qualquer conteúdo e qualquer conta de utilizador por qualquer razão em qualquer altura. Os moderadores não prevêem novas mensagens em qualquer maneira; os moderadores e os operadores do sítio não têm qualquer responsabilidade por qualquer conteúdo publicado pela comunidade. \n\n\n\n## [Seja sempre civilizado](#seja-civilizado) \n\nNada estraga mais uma conversação saudável do que insolências: \n\n*Seja civilizado. Não publique nada que uma pessoa sensata consideraria ofensiva, abusiva ou de ódio. \n*Mantenha-o limpo. Não publique nada obsceno ou sexualmente explicito.\n*Respeite os outros. Não assedie ou magoe ninguém, não personifique pessoas, e não exponha as suas informações pessoais. \n*Respeite o fórum. Não publique spam ou qualquer outra coisa que vandalize o fórum. \n\nEstes não são termos concretos com definições precisas — evite até a _aparência_ de qualquer uma destas coisas. Se não tem certeza, pergunte-se a si próprio como se sentiria se a sua mensagem fosse capa do New York Times. \n\nEste é um fórum público, e motores de pesquisa indexam estes debates. Mantenha a linguagem, hiperligações e imagens seguras para família e amigos. \n\n\n\n## [Mantenha-o Organizado](#manter-organizado) \n\nFaça o esforço para colocar as coisas no local certo, para que possamos passar mais tempo a debater e menos a limpar. Por isso: \n\n*Não comece um tópico na categoria errada. \n*Não cruze mensagens sobre o mesmo tema em múltiplos tópicos. \n*Não publique respostas sem conteúdo. \n*Não desvie um tópico ao mudar o seu centro de atenção. \n*Não assine as suas mensagens — qualquer mensagem tem a sua informação de perfil anexada à mesma. \n\nEm vez de publicar “+1” ou “Concordo”, utilize o botão Gosto. Em vez de levar um tópico existente para uma direção completamente diferente, utilize Responder como Novo Tópico. \n\n\n \n## [Publique Apenas As Suas Próprias Coisas](#roubo) \n\nNão pode publicar nada digital que pertença a qualquer outra pessoa, sem a sua permissão. Não pode publicar descrições de, hiperligações a, ou métodos para roubar propriedade intelectual de outras pessoas (software, vídeo, áudio, imagens), ou para quebrar qualquer outra lei. \n\n\n## [Patrocinado Por Si](#poder) \n\nEste sítio é operado pelos seus [membros locais amigáveis](/sobre) e por *si*, a comunidade. Se tem alguma questão adicional sobre como as coisas funcionam por aqui, abra um novo tópico em [site feedbackcategory](/c/site-feedback) e iremos debatê-lo. Se ocorrer algum assunto crítico ou urgente que pode ser tratado por um tópico meta ou por uma sinalização, contacte-nos através do [página do pessoal](/sobre). \n\n \n\n## [Termos de Serviço](#tds) \n\nSim, a legalidade é chata, mas temos que nos proteger – e por extensão, protegê-lo a si e aos seus dados – contra companheiros inimigos. Temos os [Termos de Serviço](/tds) que descrevem o seu (e o nosso) comportamento e direitos relativamente a conteúdo, privacidade e leis. Para usar este serviço tem que concordar em cumprir os nossos [TDS](/tds).\n" tos_topic: title: "Termos de Serviço" - body: "Os seguintes termos e condições governam todo o uso do sítio %{company_domain} e todo o conteúdo, serviços e produtos disponíveis no ou através do sítio, incluindo mas não limitado a, %{company_domain} Software do Fórum, %{company_domain} Fóruns de Suporte e serviço de alojamento %{company_domain} (\"Alojamento\"), (em conjunto, o Sítio). O Sítio é propriedade e operado por %{company_full_name} (\"%{company_name}\"). O Sítio oferecido está sujeito à sua aprovação sem nenhuma modificação de todos os termos e condições contidos aqui e todas as outras regras de operação políticas (incluindo, sem limitação, %{company_domain}’s [Política de Privacidade](/privacy) e [Diretrizes da Comunidade](/faq)) e procedimentos que possam ser publicados de tempos em tempos neste Sítio por %{company_name} (coletivamente, the \"Acordo\"). \n\nPor favor leia este Acordo com cuidado antes de aceder ou usar o Sítio. Ao aceder ou usar qualquer parte do Sítio, concorda em estar limitado pelos termos e condições deste acordo. Se não concorda com todos os termos e condições deste acordo, então não deve aceder ao Sítio ou usar qualquer um dos serviços. Se estes termos e condições são considerados uma oferta de %{company_name}, a sua aceitação é expressamente limitada a estes termos. O Sítio está disponível apenas a indíviduos que têm pelo menos 13 anos de idade. \n\n \n\n## [1. A Sua Conta %{company_domain} ](#1) \n\nSe criar uma conta no Sítio, será responsável por manter a segurança da sua conta e será totalmente responsável por todas as atividades que ocorrerem sob a sua conta. Deve notificar imediatamente %{company_name} de qualquer uso não autorizado da sua conta ou qualquer outra falha de segurança. %{company_name} não será passível de quaisquer atos ou omissões da sua parte, incluindo danos de qualquer tipo que incorram como resultado de tais atos ou omissões. \n\n \n\n## [2.Responsabilidade dos Participantes](#2) \n\nSe publicar material no Sítio, publicar hiperligações no Sítio, ou de outra maneira disponibilizar (ou permitir que qualquer terceira parte o faça) material no Sítio (qualquer\ - \ material, “Conteúdo”), será inteiramente responsável pelo conteúdo de, e qualquer dano resultante de tal Conteúdo. Esse é o caso independentemente de o Conteúdo em questão constituir texto, gráficos, ficheiros áudio, ou programas de computadores. Ao tornar o Conteúdo disponível, está a representar e garantir que: \n\n* o descarregamento, cópia e uso do Conteúdo não irá infringir os direitos do proprietário, incluindo mas não limitado aos direitos de autor, patentes, marcas registadas ou direitos de segredos de troca, de qualquer terceira parte; \n* se o seu empregado tem direitos sob a propriedade intelectual que criou, terá que (i) ou ter recebido permissões do seu empregado para publicar ou tornar o Conteúdo disponível, incluindo mas não limitado a qualquer software, ou (ii) ter garantido uma renúncia do seu empregado a todos os direitos no e para o Conteúdo; \n* está de acordo com licenças de qualquer terceira-parte relacionada com o Conteúdo, e fez todas as coisas necessárias para passar corretamente quaisquer termos requeridos aos utilizadores finais; \n* o Conteúdo não contém ou instala quaisquer vírus, minhocas ou malware, cavalos de Tróia ou outro conteúdo destrutivo; \n* o Conteúdo não é spam, não é gerado por máquina, e não contém conteúdo indesejado sem ética ou comercial com intuito de conduzir o tráfico de sítios terceiros ou aumentar a posição de sítios terceiros em motores de pesquisa, ou ainda outros atos ilegais (tais como phishing) ou destinatários enganadores relativamente à origem do material (tais como spoofing); \n* o Conteúdo não é pornográfico, nem contém ameaças ou incita violência, e não viola os direitos de privacidade ou publicidade de qualquer terceira parte; \n* o conteúdo não está a ser anunciado através de quaisquer mensagens eletrónicas tais como hiperligações de spam ou grupos de notícias, listas de email, blogs e sítios, e similares métodos promocionais não solicitados; \n* o seu conteúdo não está nomeado de nenhuma maneira que leve os seus leitores a pensarem que é outra pessoa ou empresa; e \n* terá, no caso do Conteúdo incluir código de computador, categorizado e/ou\ - \ descrito o tipo, natureza, uso e efeito dos materiais, quer tenha sido pedido para fazê-lo por %{company_name} ou pelo contrário. \n\n \n\n## [3. Licença do Conteúdo do Utilizador](#3) \n\nAs contribuições dos utilizadores estão licenciadas sob a [Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US). Sem qualquer limitação de qualquer dessas representações ou garantias, %{company_name} tem o direito (embora não tenha a obrigação) de, em critério exclusivo de %{company_name} (i) recusar ou remover qualquer conteúdo que, na sensata opinião de %{company_name} viola qualquer política de %{company_name} ou é de alguma maneira prejudicial ou censurável, ou (ii) terminar ou negar acesso ao Sítio e ao uso do mesmo a qualquer indivíduo ou entidade por alguma razão, em critério exclusivo de %{company_name}. %{company_name} não terá obrigação de fornecer uma compensação de quaisquer montantes previamente pagos. \n\n \n\n## [4. Pagamento e Renovação](#4) \n\n### Termos Gerais \n\nAtualizações ou serviços opcionais pagos podem estar disponíveis no Sítio. Ao utilizar uma atualização ou serviço opcional pago, está a concordar em pagar a %{company_name} as taxas de subscrição mensais ou anuais indicadas. Os pagamentos serão cobrados numa base pré-paga no dia em que utilizar o serviço ou a atualização e irá cobrir o uso desse serviço ou atualização por um período de subscrição mensal ou anual tal como indicado. Estas taxas não são reembolsáveis. \n\n### Renovação Automática \n\nA não ser que notifique %{company_name} antes do final do período da subscrição que quer cancelar, a sua subscrição será automaticamente renovada e você autoriza-nos a colecionar as taxas anuais ou mensais (assim como outras taxas) usando qualquer cartão de crédito ou outro mecanismo de pagamento que tivermos no seu registo. As subscrições podem ser canceladas em qualquer altura. \n\n \n\n## [5. Serviços](#5) \n\n### Serviços de Alojamento, Suporte \n\nServiços opcionais de Alojamento e Suporte podem ser fornecidos\ - \ por %{company_name} sob os termos e condições para cada serviço. Ao inscrever-se numa conta com serviços de Alojamento ou Suporte, irá concordar e agir sob tais termos e condições. \n\n \n\n## [6. Responsabilidade dos Visitantes do Sítio](#6) \n\n%{company_name} não reviu, nem pode rever, todo o material, incluindo programas de computador, publicado no Sítio, e não pode portanto ser responsável pelo conteúdo do mesmo, pelo seu uso ou efeitos. Ao operar o Sítio, %{company_name} não representa ou implica que corrobora com o material publicado, ou que acredita que o material seja preciso, útil e não prejudicial. Será responsável por tomar as precauções necessárias para proteger-se a si próprio e o seu sistema computacional de vírus, minhocas, cavalos de Tróia e outros conteúdos destrutivos. O Sítio pode ter conteúdo ofensivo, indecente assim como também imprecisões técnicas, erros tipográficos entre outros erros. O Sítio pode também ter material que viola os direitos de privacidade e publicidade, ou que infringe a propriedade intelectual e outros direitos do proprietário, de terceiras partes, ou o descarregamento, cópia ou uso que é sujeito a termos e condições adicionais, estabelecidos ou não. %{company_name} está isenta de qualquer responsabilidade de qualquer dano resultante do uso por parte dos visitantes do Sítio, ou de qualquer descarregamento feito por esses visitantes do conteúdo lá publicado. \n\n \n\n## [7. Conteúdo Publicado Noutros Sítios](#7) \n\nNão revimos nem podemos rever todo o material, incluindo programas de computador, disponibilizado através de sítios e páginas em %{company_domain} no qual existem hiperligações e que se hiperligam a %{company_domain}. %{company_name} não tem qualquer controlo dos sítios e páginas não-%{company_domain}, e não é responsável pelo seu conteúdo ou o seu uso. Ao clicar num sítio ou página não--%{company_domain}, %{company_name} não representa ou implica que corrobora com tais sítios ou páginas. Você é responsável por tomar ações necessárias para proteger-se a si próprio ou o seu sistema computacional de vírus, minhocas,\ - \ cavalos de Tróia e outros conteúdos destrutivos. %{company_name} renuncia qualquer responsabilidade por qualquer dano resultante do uso de sítios e páginas não-%{company_domain}. \n\n \n\n## [8. Violação de Direitos de Autor e Política DCMA](#8) \n\nAssim como %{company_name} pede aos outros para respeitarem os direitos de propriedade intelectual, a mesma respeita os direitos de propriedade intelectual dos outros. Se acredita que material localizado em ou com hiperligação para, por %{company_domain} viola os seus direitos de autor, e se este sítio reside nos EUA, encorajamo-lo a notificar a %{company_name} em concordância com a Política (“DMCA”) [Digital Millennium Copyright Act](http://en.wikipedia.org/wiki/Digital_Millennium_Copyright_Act) da %{company_name}. %{company_name} irá responder por tais notícias, incluindo tal como requerido ou apropriado por remover o material ilícito ou desativando as hiperligações para o material ilícito. %{company_name} irá terminar o acesso a e o uso do Sítio se, sob circunstâncias apropriadas, o visitante é determinado como sendo um infrator repetido dos direitos de autor e de outros direitos de propriedade intelectual de %{company_name} ou outros. No caso de tal terminação, %{company_name} não terá qualquer obrigação de fornecer uma compensação de qualquer valor previamente pago a %{company_name}. \n\n \n\n## [9. Propriedade Intelectual](#9) \n\nEste Acordo não transfere totalmente de %{company_name} para si qualquer propriedade intelectual de %{company_name} ou de terceiras partes, e todos os direitos, títulos e interesse na e para a propriedade irá permanecer (entre as partes) apenas com %{company_name}. %{company_name}, %{company_domain}, o logótipo %{company_domain} e todos as outras marcas, marcas de serviço, gráficos, logótipos usados na ligação com %{company_domain}, ou o Sítio é marca registada de %{company_name} ou licenciadores de %{company_name}. Outras marcas, marcas de serviço, gráficos e logótipos usados na hiperligação com o Sítio podem ser marcas de terceiras partes. O seu uso do Sítio não lhe concede direitos ou\ - \ licença para reproduzir ou de outra forma usar quaisquer marcas de %{company_name} ou de terceiras partes. \n\n \n\n## [10. Anúncios](#10) \n\n%{company_name} reserva-se ao direito de mostrar anúncios no seu conteúdo a não ser que tenha comprado a Atualização Ad-free ou uma conta de Serviços. \n\n \n\n## [11. Atribuição](#11) \n\n%{company_name} reserva-se ao direito de mostrar hiperligações de atribuição tais como ‘Patrocinado por %{company_domain},’ e atribuição de fontes ao conteúdo do rodapé ou da sua ferramenta. Os créditos do rodapé e a ferramenta de %{company_domain} não poderão ser removidas independentemente das atualizações compradas. \n\n \n\n## [12. Alterações](#12) \n\n%{company_name} reserva-se ao direito, por critério exclusivo, de modificar ou substituir qualquer parte deste Acordo. É sua responsabilidade verificar periodicamente o Acordo e verificar as suas alterações. O seu uso ou acesso contínuo ao Sítio seguido da publicação de qualquer alteração a este Acordo constitui aceitação a essas mudanças. %{company_name} pode também, no futuro, oferecer novos serviços e/ou funcionalidades através do Sítio (incluindo, o lançamento de novas ferramentas e recursos). Estas novas funcionalidades e/ou serviços devem ser sujeitos aos termos e condições deste Acordo. \n\n \n\n## [13. Terminação](#13) \n\n%{company_name} pode terminar o seu acesso a todas ou alguma parte do Sítio em qualquer altura, com ou sem motivo, com ou sem aviso, com efeitos imediatos. Se desejar terminar este Acordo ou a sua conta %{company_domain} (se tiver uma), pode simplesmente deixar de usar o Sítio. Todas as provisões para este Acordo que pela sua natureza deverão sobreviver à terminação, incluindo, sem limitações, provisões de propriedade, isenções de garantia, indemnizações e limitações de responsabilidade. \n\n \n\n## [14. Isenção de Garantias](#14) \n\nO Sítio é fornecido “tal como está”. %{company_name} e os seus fornecedores e licenciadores ficam aqui isentos de garantias de qualquer tipo, expressas ou implícitas, sem\ - \ limitação, as garantias de comerciabilidade, adequadas a uma finalidade específica. Nem %{company_name} nem os seus fornecedores e licenciadores, fazem garantias de que o Sítio está livre de erros ou que o acesso seja contínuo e ininterrupto. Se está a ler isto, aqui está [uma ajuda] (http://www.newyorker.com/online/blogs/shouts/2012/12/the-hundred-best-lists-of-all-time.html). Compreende que descarregou de, ou de outra maneira obteve conteúdo ou serviços através do Sítio a seu próprio risco e descrição. \n\n \n\n## [15. Limitação da Responsabilidade](#15) \n\nEm nenhum evento %{company_name} ou os seus fornecedores ou licenciadores, serão responsáveis em respeito a qualquer assunto deste acordo sob qualquer contrato, negligência, estrita responsabilidade ou outras teorias legais para: (i) quaisquer danos especiais, de incidentes ou consequenciais; (ii) o custo de procura de produtos ou serviços substitutos; (iii) por interrupção do uso, perda ou corrupção dos dados; ou (iv) por quaisquer valores que excedem as taxas pagas por si a %{company_name} sob este acordo durante um período doze (12) meses anterior à causa da ação. %{company_name} não deverá ter qualquer responsabilidade de qualquer falha ou atraso devido a matérias para além do seu razoável controlo. O disposto neste artigo não se aplica nas medidas proibidas pela lei aplicável. \n\n \n\n## [16. Representações Gerais e Garantia](#16) \n\nRepresenta e garante que (i) o seu uso do Sítio irá estar em estrita concordância com a [Política de Privacidade](/privacy) e das [Diretrizes da Comunidade](/diretrizes) da %{company_name}, com este Acordo e com as leis e regulações aplicáveis (incluindo sem limitação de quaisquer leis ou regulações locais no seu país, estado, cidade ou outras áreas governamentais, relativamente à conduta online e ao conteúdo aceitável, e incluindo quaisquer leis aplicáveis relativamente à transmissão de dados técnicos exportados de qualquer país em que o sítio reside ou do país em que você reside) e (ii) o seu uso do Sítio não irá infringir os direitos de propriedade intelectual de qualquer\ - \ terceira parte. \n\n \n\n## [17. Indemnização](#17) \n\nConcorda em indemnizar e não prejudicar %{company_name}, os seus contratados, e os seus licenciadores, os seus respetivos diretores, empregados e agentes de e contra quaisquer reivindicações e despesas, incluindo taxas de advogados, decorrentes do seu uso do Sítio, incluindo mas não limitado à sua violação deste Acordo. \n\n \n\n## [18. Diversos](#18) \n\nEste Acordo constitui o acordo integral entre si e %{company_name} em relação ao assunto em questão, e poderá ser modificado apenas por uma emenda escrita assinada por um executivo autorizado da %{company_name}, ou pela publicação por parte da %{company_name}, de uma versão revista. Excepto o definido na lei, se houver, disposição em contrário, o presente Acordo, qualquer acesso ou uso do sítio será governado pelas leis do estado da Califórnia, E.U.A, excluindo aos conflitos das disposições da lei, e a receita própria por qualquer disputa emergente de ou relativa a qualquer do mesmo será o tribunal federal e estatal localizado em São Francisco, Califórnia. Exceto para os pedidos de medida cautelar ou equitativa ou reclamações relativas aos direitos de propriedade intelectual (que podem ser introduzidos em qualquer tribunal competente, sem a prestação de uma caução), qualquer litígio decorrente do presente acordo será resolvido de acordo com as Regras de Arbitragem de \"Judicial Arbitration and Mediation Service, Inc.” (“JAMS”) por três árbitros apontados em concordância com tais Regras. A arbitragem deverá ter lugar em São Francisco, Califórnia, em língua Inglesa e a decisão arbitral pode ser forçada em qualquer tribunal. A parte prevalecente em qualquer ação ou processo para executar este Acordo terá direito a custos e honorários dos advogados. Se qualquer parte deste Acordo for considerada inválida ou inexequível, essa parte será interpretada de forma a refletir a intenção original das partes e as porções restantes permanecerão em pleno vigor e efeito. A renúncia por qualquer das partes de qualquer termo ou condição deste Acordo ou qualquer violação dos mesmos,\ - \ em qualquer instância, não vai renunciar a tal termo ou condição ou qualquer violação subsequente. Pode atribuir os seus direitos sob este acordo a qualquer parte que consente a, e concorda em ficar vinculado pelos seus termos e condições; %{company_name} pode assignar os seus direitos sob este Acordo sem condição. O presente Acordo será vinculativo e reverterá em benefício das partes, dos seus sucessores e signatários autorizados. \n\nEste documento é CC-BY-SA. Foi atualizado pela última vez em 31 de Maio de 2013. \n\nOriginalmente adaptado de [Termos de Serviço WordPress](http://en.wordpress.com/tos/).\n" + body: "Os seguintes termos e condições governam todo o uso do sítio %{company_domain} e todo o conteúdo, serviços e produtos disponíveis no ou através do sítio, incluindo mas não limitado a, %{company_domain} Software do Fórum, %{company_domain} Fóruns de Suporte e serviço de alojamento %{company_domain} (\"Alojamento\"), (em conjunto, o Sítio). O Sítio é propriedade e operado por %{company_full_name} (\"%{company_name}\"). O Sítio oferecido está sujeito à sua aprovação sem nenhuma modificação de todos os termos e condições contidos aqui e todas as outras regras de operação políticas (incluindo, sem limitação, %{company_domain}’s [Política de Privacidade](/privacy) e [Diretrizes da Comunidade](/faq)) e procedimentos que possam ser publicados de tempos em tempos neste Sítio por %{company_name} (coletivamente, the \"Acordo\"). \n\nPor favor leia este Acordo com cuidado antes de aceder ou usar o Sítio. Ao aceder ou usar qualquer parte do Sítio, concorda em estar limitado pelos termos e condições deste acordo. Se não concorda com todos os termos e condições deste acordo, então não deve aceder ao Sítio ou usar qualquer um dos serviços. Se estes termos e condições são considerados uma oferta de %{company_name}, a sua aceitação é expressamente limitada a estes termos. O Sítio está disponível apenas a indíviduos que têm pelo menos 13 anos de idade. \n\n \n\n## [1. A Sua Conta %{company_domain} ](#1) \n\nSe criar uma conta no Sítio, será responsável por manter a segurança da sua conta e será totalmente responsável por todas as atividades que ocorrerem sob a sua conta. Deve notificar imediatamente %{company_name} de qualquer uso não autorizado da sua conta ou qualquer outra falha de segurança. %{company_name} não será passível de quaisquer atos ou omissões da sua parte, incluindo danos de qualquer tipo que incorram como resultado de tais atos ou omissões. \n\n \n\n## [2.Responsabilidade dos Participantes](#2) \n\nSe publicar material no Sítio, publicar hiperligações no Sítio, ou de outra maneira disponibilizar (ou permitir que qualquer terceira parte o faça) material no Sítio (qualquer material, “Conteúdo”), será inteiramente responsável pelo conteúdo de, e qualquer dano resultante de tal Conteúdo. Esse é o caso independentemente de o Conteúdo em questão constituir texto, gráficos, ficheiros áudio, ou programas de computadores. Ao tornar o Conteúdo disponível, está a representar e garantir que: \n\n* o descarregamento, cópia e uso do Conteúdo não irá infringir os direitos do proprietário, incluindo mas não limitado aos direitos de autor, patentes, marcas registadas ou direitos de segredos de troca, de qualquer terceira parte; \n* se o seu empregado tem direitos sob a propriedade intelectual que criou, terá que (i) ou ter recebido permissões do seu empregado para publicar ou tornar o Conteúdo disponível, incluindo mas não limitado a qualquer software, ou (ii) ter garantido uma renúncia do seu empregado a todos os direitos no e para o Conteúdo; \n* está de acordo com licenças de qualquer terceira-parte relacionada com o Conteúdo, e fez todas as coisas necessárias para passar corretamente quaisquer termos requeridos aos utilizadores finais; \n* o Conteúdo não contém ou instala quaisquer vírus, minhocas ou malware, cavalos de Tróia ou outro conteúdo destrutivo; \n* o Conteúdo não é spam, não é gerado por máquina, e não contém conteúdo indesejado sem ética ou comercial com intuito de conduzir o tráfico de sítios terceiros ou aumentar a posição de sítios terceiros em motores de pesquisa, ou ainda outros atos ilegais (tais como phishing) ou destinatários enganadores relativamente à origem do material (tais como spoofing); \n* o Conteúdo não é pornográfico, nem contém ameaças ou incita violência, e não viola os direitos de privacidade ou publicidade de qualquer terceira parte; \n* o conteúdo não está a ser anunciado através de quaisquer mensagens eletrónicas tais como hiperligações de spam ou grupos de notícias, listas de email, blogs e sítios, e similares métodos promocionais não solicitados; \n* o seu conteúdo não está nomeado de nenhuma maneira que leve os seus leitores a pensarem que é outra pessoa ou empresa; e \n* terá, no caso do Conteúdo incluir código de computador, categorizado e/ou descrito o tipo, natureza, uso e efeito dos materiais, quer tenha sido pedido para fazê-lo por %{company_name} ou pelo contrário. \n\n \n\n## [3. Licença do Conteúdo do Utilizador](#3) \n\nAs contribuições dos utilizadores estão licenciadas sob a [Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US). Sem qualquer limitação de qualquer dessas representações ou garantias, %{company_name} tem o direito (embora não tenha a obrigação) de, em critério exclusivo de %{company_name} (i) recusar ou remover qualquer conteúdo que, na sensata opinião de %{company_name} viola qualquer política de %{company_name} ou é de alguma maneira prejudicial ou censurável, ou (ii) terminar ou negar acesso ao Sítio e ao uso do mesmo a qualquer indivíduo ou entidade por alguma razão, em critério exclusivo de %{company_name}. %{company_name} não terá obrigação de fornecer uma compensação de quaisquer montantes previamente pagos. \n\n \n\n## [4. Pagamento e Renovação](#4) \n\n### Termos Gerais \n\nAtualizações ou serviços opcionais pagos podem estar disponíveis no Sítio. Ao utilizar uma atualização ou serviço opcional pago, está a concordar em pagar a %{company_name} as taxas de subscrição mensais ou anuais indicadas. Os pagamentos serão cobrados numa base pré-paga no dia em que utilizar o serviço ou a atualização e irá cobrir o uso desse serviço ou atualização por um período de subscrição mensal ou anual tal como indicado. Estas taxas não são reembolsáveis. \n\n### Renovação Automática \n\nA não ser que notifique %{company_name} antes do final do período da subscrição que quer cancelar, a sua subscrição será automaticamente renovada e você autoriza-nos a colecionar as taxas anuais ou mensais (assim como outras taxas) usando qualquer cartão de crédito ou outro mecanismo de pagamento que tivermos no seu registo. As subscrições podem ser canceladas em qualquer altura. \n\n \n\n## [5. Serviços](#5) \n\n### Serviços de Alojamento, Suporte \n\nServiços opcionais de Alojamento e Suporte podem ser fornecidos por %{company_name} sob os termos e condições para cada serviço. Ao inscrever-se numa conta com serviços de Alojamento ou Suporte, irá concordar e agir sob tais termos e condições. \n\n \n\n## [6. Responsabilidade dos Visitantes do Sítio](#6) \n\n%{company_name} não reviu, nem pode rever, todo o material, incluindo programas de computador, publicado no Sítio, e não pode portanto ser responsável pelo conteúdo do mesmo, pelo seu uso ou efeitos. Ao operar o Sítio, %{company_name} não representa ou implica que corrobora com o material publicado, ou que acredita que o material seja preciso, útil e não prejudicial. Será responsável por tomar as precauções necessárias para proteger-se a si próprio e o seu sistema computacional de vírus, minhocas, cavalos de Tróia e outros conteúdos destrutivos. O Sítio pode ter conteúdo ofensivo, indecente assim como também imprecisões técnicas, erros tipográficos entre outros erros. O Sítio pode também ter material que viola os direitos de privacidade e publicidade, ou que infringe a propriedade intelectual e outros direitos do proprietário, de terceiras partes, ou o descarregamento, cópia ou uso que é sujeito a termos e condições adicionais, estabelecidos ou não. %{company_name} está isenta de qualquer responsabilidade de qualquer dano resultante do uso por parte dos visitantes do Sítio, ou de qualquer descarregamento feito por esses visitantes do conteúdo lá publicado. \n\n \n\n## [7. Conteúdo Publicado Noutros Sítios](#7) \n\nNão revimos nem podemos rever todo o material, incluindo programas de computador, disponibilizado através de sítios e páginas em %{company_domain} no qual existem hiperligações e que se hiperligam a %{company_domain}. %{company_name} não tem qualquer controlo dos sítios e páginas não-%{company_domain}, e não é responsável pelo seu conteúdo ou o seu uso. Ao clicar num sítio ou página não--%{company_domain}, %{company_name} não representa ou implica que corrobora com tais sítios ou páginas. Você é responsável por tomar ações necessárias para proteger-se a si próprio ou o seu sistema computacional de vírus, minhocas, cavalos de Tróia e outros conteúdos destrutivos. %{company_name} renuncia qualquer responsabilidade por qualquer dano resultante do uso de sítios e páginas não-%{company_domain}. \n\n \n\n## [8. Violação de Direitos de Autor e Política DCMA](#8) \n\nAssim como %{company_name} pede aos outros para respeitarem os direitos de propriedade intelectual, a mesma respeita os direitos de propriedade intelectual dos outros. Se acredita que material localizado em ou com hiperligação para, por %{company_domain} viola os seus direitos de autor, e se este sítio reside nos EUA, encorajamo-lo a notificar a %{company_name} em concordância com a Política (“DMCA”) [Digital Millennium Copyright Act](http://en.wikipedia.org/wiki/Digital_Millennium_Copyright_Act) da %{company_name}. %{company_name} irá responder por tais notícias, incluindo tal como requerido ou apropriado por remover o material ilícito ou desativando as hiperligações para o material ilícito. %{company_name} irá terminar o acesso a e o uso do Sítio se, sob circunstâncias apropriadas, o visitante é determinado como sendo um infrator repetido dos direitos de autor e de outros direitos de propriedade intelectual de %{company_name} ou outros. No caso de tal terminação, %{company_name} não terá qualquer obrigação de fornecer uma compensação de qualquer valor previamente pago a %{company_name}. \n\n \n\n## [9. Propriedade Intelectual](#9) \n\nEste Acordo não transfere totalmente de %{company_name} para si qualquer propriedade intelectual de %{company_name} ou de terceiras partes, e todos os direitos, títulos e interesse na e para a propriedade irá permanecer (entre as partes) apenas com %{company_name}. %{company_name}, %{company_domain}, o logótipo %{company_domain} e todos as outras marcas, marcas de serviço, gráficos, logótipos usados na ligação com %{company_domain}, ou o Sítio é marca registada de %{company_name} ou licenciadores de %{company_name}. Outras marcas, marcas de serviço, gráficos e logótipos usados na hiperligação com o Sítio podem ser marcas de terceiras partes. O seu uso do Sítio não lhe concede direitos ou licença para reproduzir ou de outra forma usar quaisquer marcas de %{company_name} ou de terceiras partes. \n\n \n\n## [10. Anúncios](#10) \n\n%{company_name} reserva-se ao direito de mostrar anúncios no seu conteúdo a não ser que tenha comprado a Atualização Ad-free ou uma conta de Serviços. \n\n \n\n## [11. Atribuição](#11) \n\n%{company_name} reserva-se ao direito de mostrar hiperligações de atribuição tais como ‘Patrocinado por %{company_domain},’ e atribuição de fontes ao conteúdo do rodapé ou da sua ferramenta. Os créditos do rodapé e a ferramenta de %{company_domain} não poderão ser removidas independentemente das atualizações compradas. \n\n \n\n## [12. Alterações](#12) \n\n%{company_name} reserva-se ao direito, por critério exclusivo, de modificar ou substituir qualquer parte deste Acordo. É sua responsabilidade verificar periodicamente o Acordo e verificar as suas alterações. O seu uso ou acesso contínuo ao Sítio seguido da publicação de qualquer alteração a este Acordo constitui aceitação a essas mudanças. %{company_name} pode também, no futuro, oferecer novos serviços e/ou funcionalidades através do Sítio (incluindo, o lançamento de novas ferramentas e recursos). Estas novas funcionalidades e/ou serviços devem ser sujeitos aos termos e condições deste Acordo. \n\n \n\n## [13. Terminação](#13) \n\n%{company_name} pode terminar o seu acesso a todas ou alguma parte do Sítio em qualquer altura, com ou sem motivo, com ou sem aviso, com efeitos imediatos. Se desejar terminar este Acordo ou a sua conta %{company_domain} (se tiver uma), pode simplesmente deixar de usar o Sítio. Todas as provisões para este Acordo que pela sua natureza deverão sobreviver à terminação, incluindo, sem limitações, provisões de propriedade, isenções de garantia, indemnizações e limitações de responsabilidade. \n\n \n\n## [14. Isenção de Garantias](#14) \n\nO Sítio é fornecido “tal como está”. %{company_name} e os seus fornecedores e licenciadores ficam aqui isentos de garantias de qualquer tipo, expressas ou implícitas, sem limitação, as garantias de comerciabilidade, adequadas a uma finalidade específica. Nem %{company_name} nem os seus fornecedores e licenciadores, fazem garantias de que o Sítio está livre de erros ou que o acesso seja contínuo e ininterrupto. Se está a ler isto, aqui está [uma ajuda] (http://www.newyorker.com/online/blogs/shouts/2012/12/the-hundred-best-lists-of-all-time.html). Compreende que descarregou de, ou de outra maneira obteve conteúdo ou serviços através do Sítio a seu próprio risco e descrição. \n\n \n\n## [15. Limitação da Responsabilidade](#15) \n\nEm nenhum evento %{company_name} ou os seus fornecedores ou licenciadores, serão responsáveis em respeito a qualquer assunto deste acordo sob qualquer contrato, negligência, estrita responsabilidade ou outras teorias legais para: (i) quaisquer danos especiais, de incidentes ou consequenciais; (ii) o custo de procura de produtos ou serviços substitutos; (iii) por interrupção do uso, perda ou corrupção dos dados; ou (iv) por quaisquer valores que excedem as taxas pagas por si a %{company_name} sob este acordo durante um período doze (12) meses anterior à causa da ação. %{company_name} não deverá ter qualquer responsabilidade de qualquer falha ou atraso devido a matérias para além do seu razoável controlo. O disposto neste artigo não se aplica nas medidas proibidas pela lei aplicável. \n\n \n\n## [16. Representações Gerais e Garantia](#16) \n\nRepresenta e garante que (i) o seu uso do Sítio irá estar em estrita concordância com a [Política de Privacidade](/privacy) e das [Diretrizes da Comunidade](/diretrizes) da %{company_name}, com este Acordo e com as leis e regulações aplicáveis (incluindo sem limitação de quaisquer leis ou regulações locais no seu país, estado, cidade ou outras áreas governamentais, relativamente à conduta online e ao conteúdo aceitável, e incluindo quaisquer leis aplicáveis relativamente à transmissão de dados técnicos exportados de qualquer país em que o sítio reside ou do país em que você reside) e (ii) o seu uso do Sítio não irá infringir os direitos de propriedade intelectual de qualquer terceira parte. \n\n \n\n## [17. Indemnização](#17) \n\nConcorda em indemnizar e não prejudicar %{company_name}, os seus contratados, e os seus licenciadores, os seus respetivos diretores, empregados e agentes de e contra quaisquer reivindicações e despesas, incluindo taxas de advogados, decorrentes do seu uso do Sítio, incluindo mas não limitado à sua violação deste Acordo. \n\n \n\n## [18. Diversos](#18) \n\nEste Acordo constitui o acordo integral entre si e %{company_name} em relação ao assunto em questão, e poderá ser modificado apenas por uma emenda escrita assinada por um executivo autorizado da %{company_name}, ou pela publicação por parte da %{company_name}, de uma versão revista. Excepto o definido na lei, se houver, disposição em contrário, o presente Acordo, qualquer acesso ou uso do sítio será governado pelas leis do estado da Califórnia, E.U.A, excluindo aos conflitos das disposições da lei, e a receita própria por qualquer disputa emergente de ou relativa a qualquer do mesmo será o tribunal federal e estatal localizado em São Francisco, Califórnia. Exceto para os pedidos de medida cautelar ou equitativa ou reclamações relativas aos direitos de propriedade intelectual (que podem ser introduzidos em qualquer tribunal competente, sem a prestação de uma caução), qualquer litígio decorrente do presente acordo será resolvido de acordo com as Regras de Arbitragem de \"Judicial Arbitration and Mediation Service, Inc.” (“JAMS”) por três árbitros apontados em concordância com tais Regras. A arbitragem deverá ter lugar em São Francisco, Califórnia, em língua Inglesa e a decisão arbitral pode ser forçada em qualquer tribunal. A parte prevalecente em qualquer ação ou processo para executar este Acordo terá direito a custos e honorários dos advogados. Se qualquer parte deste Acordo for considerada inválida ou inexequível, essa parte será interpretada de forma a refletir a intenção original das partes e as porções restantes permanecerão em pleno vigor e efeito. A renúncia por qualquer das partes de qualquer termo ou condição deste Acordo ou qualquer violação dos mesmos, em qualquer instância, não vai renunciar a tal termo ou condição ou qualquer violação subsequente. Pode atribuir os seus direitos sob este acordo a qualquer parte que consente a, e concorda em ficar vinculado pelos seus termos e condições; %{company_name} pode assignar os seus direitos sob este Acordo sem condição. O presente Acordo será vinculativo e reverterá em benefício das partes, dos seus sucessores e signatários autorizados. \n\nEste documento é CC-BY-SA. Foi atualizado pela última vez em 31 de Maio de 2013. \n\nOriginalmente adaptado de [Termos de Serviço WordPress](http://en.wordpress.com/tos/).\n" privacy_topic: title: "Política de Privacidade" - body: " \n\n## [Que informações reunimos?](#reunião) \n\nReunimos informação sobre si assim que se regista no nosso sítio e juntamos dados quando participa no fórum ao ler, escrever e avaliar o conteúdo aqui partilhado. \n\nAo inscrever-se no nosso sítio, pode ser-lhe pedido para inserir o seu nome e endereço de email. Pode contudo, visitar o nosso sítio sem se registar. O seu endereço de email será verificado por um email contendo uma hiperligação única. Se essa hiperligação for visitada, sabemos que tem controlo do seu endereço de email. \n\nAo inscrever-se e publicar, recordamos o endereço IP de onde a publicação é originária. Podemos também reter logs de servidores que incluem endereços IP de todos os pedidos feitos ao servidor. \n\n \n\n## [Para que usamos as suas informações?](#usar) \n\nTodas as informações que reunimos sobre si podem ser usadas numa das seguintes maneiras: \n\n* Para personalizar a sua experiência — a sua informação ajuda-nos a responder melhor às suas necessidades individuais. \n* Para melhorar o nosso sítio — continuamos a lutar por melhorar as ofertas do nosso sítio com base na informação e feedback que recebemos de si. \n* Para melhorar o serviço ao cliente — a sua informação ajuda-nos a responder mais eficazmente aos pedidos de serviço ao cliente e pedidos de suporte. \n* Para enviar emails periodicamente — O endereço de email que nos fornece pode ser usado para lhe enviar informação, notificações que peça sobre mudanças em tópicos ou em resposta ao seu nome de utilizador, respostas a inquéritos e/ou outros pedidos ou questões. \n\n \n\n## [Como protegemos a sua informação?](#protect)\n\nImplementamos uma variedade de medidas de precaução para manter as suas informações pessoais em segurança quando insere, submete ou acede à sua informação pessoal. \n\n \n\n## [Qual é a sua política de retenção de dados?](#retenção-dados)\n\nIremos fazer um esforço de boa fé para: \n\n* Reter logs de servidores contendo o endereço IP de todos os pedidos para este servidor\ - \ não mais que 90 dias. \n* Reter endereços IP associados a utilizadores registados e às suas publicações por não mais que 5 anos. \n\n \n\n## [Usamos cookies?](#cookies) \n\nSim. Os cookies são pequenos ficheiros que um sítio ou um fornecedor de serviços transfere para o disco do seu computador através do navegador de Internet (se assim o permitir). Estes cookies permitem que o sítio reconheça o seu navegador e, se tiver uma conta registada, associá-lo a essa. \n\nUsamos cookies para entender e guardar as suas preferências para visitas futuras e compilar dados agregados sobre o tráfego do sítio e a interação com o mesmo para lhe podermos oferecer as melhores experiências e ferramentas no futuro. Podemos contratar fornecedores de serviços para nos ajudarem a entender melhor os visitantes do nosso sítio. Estes fornecedores de serviços não têm permissão para usar a informação reunida em nosso nome excepto para nos ajudar a conduzir e melhorar o nosso negócio. \n\n \n\n## [Divulgamos informação com partes exteriores?](#divulgar) \n\nNão vendemos, trocamos ou de outra maneira transferimos a sua informação pessoal para partes exteriores. Isto não inclui terceiras partes confiáveis que nos ajudam a operar sítio, conduzir o nosso negócio, ou servi-lo, enquanto estas partes acordarem em manter a informação confidencial. Podemos também partilhar a sua informação quando acreditamos que é apropriado para estar de acordo com a lei, reforçar as políticas do nosso sítio ou proteger os nossos, ou de outros, direitos, propriedades ou segurança. Contudo, informação não-pessoal do visitante pode ser fornecida a outras partes para marketing, publicidade ou outros usos. \n\n \n\n## [Hiperligações de Terceiras Partes](#terceira-parte) \n\nOcasionalmente, à nossa descrição, podemos incluir ou oferecer serviços ou produtos de terceiros no nosso sítio. Estes sítios de terceiros têm políticas de privacidade separadas e independentes. Por este motivo, não temos responsabilidade no conteúdo ou atividades destes sítios hiperligados. No entanto, procuramos\ - \ proteger a integridade do nosso sítio e damos as boas-vindas a qualquer feedback sobre estes sítios. \n\n \n\n## [Cumprimento da Proteção da Privacidade Online Infantil](#coppa) \n\nO nosso sítio, produtos e serviços são direcionados a pessoas com pelo menos 13 anos de idade. Se este servidor está nos EUA e tem menos de 13 anos de idade, como parte dos requisitos do COPPA ([Proteção da Privacidade Online Infantil]( https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act)), não utilize este sítio. \n\n \n\n## [Política de Privacidade Online](#online) \n\nEstas políticas de privacidade online aplicam-se apenas à informação reunida através do nosso sítio e não à informação reunida offline. \n\n \n\n## [O seu consentimento](#consentimento) \n\nAo utilizar o nosso sítio, está a consentir a política de privacidade do nosso sítio. \n\n \n\n## [Mudanças à nossa Política de Privacidade](#mudanças) \n\nSe decidirmos alterar a nossa política de privacidade, iremos publicar as mudanças nesta página. \n\nEste documento é CC-BY-SA. Foi atualizado pela última vez em 31 de Maio de 2013.\n" + body: " \n\n## [Que informações reunimos?](#reunião) \n\nReunimos informação sobre si assim que se regista no nosso sítio e juntamos dados quando participa no fórum ao ler, escrever e avaliar o conteúdo aqui partilhado. \n\nAo inscrever-se no nosso sítio, pode ser-lhe pedido para inserir o seu nome e endereço de email. Pode contudo, visitar o nosso sítio sem se registar. O seu endereço de email será verificado por um email contendo uma hiperligação única. Se essa hiperligação for visitada, sabemos que tem controlo do seu endereço de email. \n\nAo inscrever-se e publicar, recordamos o endereço IP de onde a publicação é originária. Podemos também reter logs de servidores que incluem endereços IP de todos os pedidos feitos ao servidor. \n\n \n\n## [Para que usamos as suas informações?](#usar) \n\nTodas as informações que reunimos sobre si podem ser usadas numa das seguintes maneiras: \n\n* Para personalizar a sua experiência — a sua informação ajuda-nos a responder melhor às suas necessidades individuais. \n* Para melhorar o nosso sítio — continuamos a lutar por melhorar as ofertas do nosso sítio com base na informação e feedback que recebemos de si. \n* Para melhorar o serviço ao cliente — a sua informação ajuda-nos a responder mais eficazmente aos pedidos de serviço ao cliente e pedidos de suporte. \n* Para enviar emails periodicamente — O endereço de email que nos fornece pode ser usado para lhe enviar informação, notificações que peça sobre mudanças em tópicos ou em resposta ao seu nome de utilizador, respostas a inquéritos e/ou outros pedidos ou questões. \n\n \n\n## [Como protegemos a sua informação?](#protect)\n\nImplementamos uma variedade de medidas de precaução para manter as suas informações pessoais em segurança quando insere, submete ou acede à sua informação pessoal. \n\n \n\n## [Qual é a sua política de retenção de dados?](#retenção-dados)\n\nIremos fazer um esforço de boa fé para: \n\n* Reter logs de servidores contendo o endereço IP de todos os pedidos para este servidor não mais que 90 dias. \n* Reter endereços IP associados a utilizadores registados e às suas publicações por não mais que 5 anos. \n\n \n\n## [Usamos cookies?](#cookies) \n\nSim. Os cookies são pequenos ficheiros que um sítio ou um fornecedor de serviços transfere para o disco do seu computador através do navegador de Internet (se assim o permitir). Estes cookies permitem que o sítio reconheça o seu navegador e, se tiver uma conta registada, associá-lo a essa. \n\nUsamos cookies para entender e guardar as suas preferências para visitas futuras e compilar dados agregados sobre o tráfego do sítio e a interação com o mesmo para lhe podermos oferecer as melhores experiências e ferramentas no futuro. Podemos contratar fornecedores de serviços para nos ajudarem a entender melhor os visitantes do nosso sítio. Estes fornecedores de serviços não têm permissão para usar a informação reunida em nosso nome excepto para nos ajudar a conduzir e melhorar o nosso negócio. \n\n \n\n## [Divulgamos informação com partes exteriores?](#divulgar) \n\nNão vendemos, trocamos ou de outra maneira transferimos a sua informação pessoal para partes exteriores. Isto não inclui terceiras partes confiáveis que nos ajudam a operar sítio, conduzir o nosso negócio, ou servi-lo, enquanto estas partes acordarem em manter a informação confidencial. Podemos também partilhar a sua informação quando acreditamos que é apropriado para estar de acordo com a lei, reforçar as políticas do nosso sítio ou proteger os nossos, ou de outros, direitos, propriedades ou segurança. Contudo, informação não-pessoal do visitante pode ser fornecida a outras partes para marketing, publicidade ou outros usos. \n\n \n\n## [Hiperligações de Terceiras Partes](#terceira-parte) \n\nOcasionalmente, à nossa descrição, podemos incluir ou oferecer serviços ou produtos de terceiros no nosso sítio. Estes sítios de terceiros têm políticas de privacidade separadas e independentes. Por este motivo, não temos responsabilidade no conteúdo ou atividades destes sítios hiperligados. No entanto, procuramos proteger a integridade do nosso sítio e damos as boas-vindas a qualquer feedback sobre estes sítios. \n\n \n\n## [Cumprimento da Proteção da Privacidade Online Infantil](#coppa) \n\nO nosso sítio, produtos e serviços são direcionados a pessoas com pelo menos 13 anos de idade. Se este servidor está nos EUA e tem menos de 13 anos de idade, como parte dos requisitos do COPPA ([Proteção da Privacidade Online Infantil]( https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act)), não utilize este sítio. \n\n \n\n## [Política de Privacidade Online](#online) \n\nEstas políticas de privacidade online aplicam-se apenas à informação reunida através do nosso sítio e não à informação reunida offline. \n\n \n\n## [O seu consentimento](#consentimento) \n\nAo utilizar o nosso sítio, está a consentir a política de privacidade do nosso sítio. \n\n \n\n## [Mudanças à nossa Política de Privacidade](#mudanças) \n\nSe decidirmos alterar a nossa política de privacidade, iremos publicar as mudanças nesta página. \n\nEste documento é CC-BY-SA. Foi atualizado pela última vez em 31 de Maio de 2013.\n" static: search_help: |

    Dicas

    @@ -1844,3 +1834,6 @@ pt: performance_report: initial_post_raw: Este tópico inclui relatórios diários de desempenho para o seu sítio. initial_topic_title: Relatórios de desempenho do sítio + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.pt_BR.yml b/config/locales/server.pt_BR.yml index 69cc53f99a..13abfa24ca 100644 --- a/config/locales/server.pt_BR.yml +++ b/config/locales/server.pt_BR.yml @@ -21,7 +21,7 @@ pt_BR: purge_reason: "A conta não verificada, foi excluída." disable_remote_images_download_reason: "Download de imagens remotas foi desativado porque não havia espaço suficiente em disco disponível." anonymous: "Anônimo" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "está limitado para %{max} caracteres; você entrou com %{length}." @@ -231,6 +231,7 @@ pt_BR: attributes: hex: invalid: "Não é uma cor válida" + <<: *errors user_profile: no_info_me: "
    o campo Sobre mim do seu perfil está em branco, quer completar?
    " no_info_other: "
    %{name} ainda não colocou nada no campo Sobre Mim
    " @@ -266,8 +267,6 @@ pt_BR: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Sobre a categoria %{category} " - replace_paragraph: "[Substitua este primeiro parágrafo com uma breve descrição de sua nova categoria. Esta orientação será exibida na área de seleção de categoria, assim, tente mantê-lo abaixo de 200 caracteres. Até que você edite o texto ou crie tópicos, esta categoria não aparecerá na página de categorias.]" - post_template: "%{replace_paragraph}\n\nUse os parágrafos a seguir para uma descrição longa, assim como para estabelecer diretrizes ou regras da categoria.\n\nAlgumas coisas para se considerar em qualquer resposta de discussão:\n\n- Para que serve esta categoria? Porque algum usaria esta categoria para seu tópico?\n\n- Como esta categoria se difere das demais categorias já existentes?\n\n- Nós precisamos desta categoria?\n\n- Deveríamos mesclar esta categoria com outra, ou dividir esta categoria em mais categorias?\n" errors: uncategorized_parent: "Sem categoria não pode ter uma categoria pai" self_parent: "A subcategoria mãe não pode ser ela mesma" @@ -717,7 +716,6 @@ pt_BR: summary_likes_required: "Curtidas mínimas em um tópico antes de 'Resumir este tópico, ficar habilitado" summary_percent_filter: "Quando um usuário clicar em 'Resumor este tópico', mostrar os melhores % mensagens" summary_max_results: "Máximo número de posts quando resumidos por Categoria " - enable_private_messages: "Permitir a usuários de nível 1 criar e responder mensagens" enable_long_polling: "O sistema de mensagens das notificações pode fazer solicitações longas." long_polling_base_url: "URL Utilizada para \"long polling\" ( Quando um CDN for configurado, tenha certeza que essa configuração seja a padrão) ex: http://origin.site.com" long_polling_interval: "Tempo que o servidor deve aguardar antes de responder quando não existe nenhum dado para ser enviado. (apenas usuários logados)" @@ -1683,3 +1681,6 @@ pt_BR: performance_report: initial_post_raw: Este tópico inclui relatórios de performance diários de seu site. initial_topic_title: Relatórios de performance do Site + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.ro.yml b/config/locales/server.ro.yml index e132b92755..97611308dc 100644 --- a/config/locales/server.ro.yml +++ b/config/locales/server.ro.yml @@ -21,7 +21,7 @@ ro: purge_reason: "Cont automat şters ca abandonat, neactivat" disable_remote_images_download_reason: "Descărcarea de imagini la distanţă a fost dezactivată deoarece nu mai era spaţiu pe disc suficient." anonymous: "Anonim" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "este limitat la %{max} de caractere; ați introdus %{length}." @@ -212,6 +212,7 @@ ro: attributes: hex: invalid: "nu este o culoare validă" + <<: *errors user_profile: no_info_me: "
    câmpul despre mine din profilul dvs este gol momentan, Doriți să-l completați?
    " no_info_other: "
    %{name} nu a introdus înca nimic în câmpul despre mine din profil
    " @@ -247,8 +248,6 @@ ro: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Despre categoria %{category}" - replace_paragraph: "[Înlocuiește acest paragraf cu o scurtă descriere despre categorie. Acest îndemn va apărea în aria de selectare a categoriei, deci încercați să aibă sub 200 caractere. Pană nu editați acest text sau creați o nouă discuție, Această categorie nu v-a apărea în pagina de categorii.]" - post_template: "%{replace_paragraph}\n\n Folosește următoarele paragrafe pentru o descriere mai lungă, cât și pentru a stabili orice regulă de bază sau de ajutor a categoriei.\n\n Câteva lucruri de avut în vedere în orice discuție mai jos: \n\n- Pentru ce este această categorie? De ce ar selecta alte persoane această categorie pentru discuțiile lor?\n\n- În ce fel este diferită față de celălalte existente?\n\n- Avem nevoie de această categorie?\n\n- Ar trebuii unită cu o altă categorie, sau divizată în alte 2?\n" errors: uncategorized_parent: "ce nu este categorisit nu poate avea categorie părinte" self_parent: "Părintele unei subcategorii nu poate fi ea însăși" @@ -1185,3 +1184,6 @@ ro: error: "Eroare!" email_input: "Email Admin" submit_button: "Trimite Email" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.ru.yml b/config/locales/server.ru.yml index bbf01e3039..626a8141e7 100644 --- a/config/locales/server.ru.yml +++ b/config/locales/server.ru.yml @@ -21,7 +21,7 @@ ru: purge_reason: "Автоматически удален, как неактивная, неактивированная учетная запись" disable_remote_images_download_reason: "Загрузка картинок была отключена из-за недостаточности места на диске." anonymous: "Гость" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "не может быть длиннее %{max} символов, а введено %{length}." @@ -263,6 +263,7 @@ ru: attributes: hex: invalid: "не является цветом" + <<: *errors user_profile: no_info_me: "
    Поле Обо мне в вашем профиле не заполнено, не желаете ли что-нибудь написать в нем?
    " no_info_other: "
    %{name} еще не заполнил поле «Обо мне» в своём профайле.
    " @@ -275,12 +276,9 @@ ru: assets_topic_body: "Это постоянная тема, для хранения изображений и файлов, используемых в дизайне сайта, доступная только сотрудникам. Не удаляйте её! \n\n\nВаши действия:\n\n\n1. Ответьте в эту тему.\n2. Загрузите все изображения, которые вы хотите использовать для логотипов, значков и т.д. сюда. (Используйте значок на панели инструментов в редакторе сообщений, перетащите мышкой, или вставьте изображения из буфера.) \n3. Сохраните свое сообщение.\n4. Щелкните правой кнопкой мыши изображении в новом сообщении, чтобы получить путь к загруженным изображениям, или щелкните значок редактирования и получите путь к изображениям. Скопируйте пути к изображениям.\n5. Вставьте эти пути в [Настройки сайта] (/admin/site_settings/category/required) .\n\n\nЕсли Вам нужно активировать дополнительные типы файлов, отредактируйте `authorized_extensions` во вкладке [Файлы] (/admin/site_settings/category/files)." lounge_welcome: title: "Добро пожаловать в Фойе" - body: "\nПоздравляем! :confetti_ball:\n\nЕсли вы видите данное сообщение, вы достигли уровня **regular** (уровень доверия 3).\n\nУвас появились новые возможности …\n\n* Вы можете редактировать заголовок любого обсуждения\n* Вы можете менять категорию обсуждения\n* С ваших ссылок снимается ограничения nofollow ([automatic nofollow](http://en.wikipedia.org/wiki/Nofollow) is removed)\n* Вы получили доступ к закрытым категориям, которые доступны только для уровня доверия 3 и выше \n* Вы можете скрывать нежелательные сообщения в один клик\n\nС полным списком привелегий вы можете ознакомиться тут [current list of fellow regulars](/badges/3/regular). Пожалуйста прочитайте это.\n\nСпасибо Вам за то что являетесь важным членом нашего сообщества!\n\n(Для получения более детальной информации об уронях доверия посмотрите тут [see this topic][trust]. Напоминаем что данный уровень доверия сохраняется\ - \ до тех пор пока вы придерживаетесь этих правил.)\n\n[trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924\n" + body: "\nПоздравляем! :confetti_ball:\n\nЕсли вы видите данное сообщение, вы достигли уровня **regular** (уровень доверия 3).\n\nУвас появились новые возможности …\n\n* Вы можете редактировать заголовок любого обсуждения\n* Вы можете менять категорию обсуждения\n* С ваших ссылок снимается ограничения nofollow ([automatic nofollow](http://en.wikipedia.org/wiki/Nofollow) is removed)\n* Вы получили доступ к закрытым категориям, которые доступны только для уровня доверия 3 и выше \n* Вы можете скрывать нежелательные сообщения в один клик\n\nС полным списком привелегий вы можете ознакомиться тут [current list of fellow regulars](/badges/3/regular). Пожалуйста прочитайте это.\n\nСпасибо Вам за то что являетесь важным членом нашего сообщества!\n\n(Для получения более детальной информации об уронях доверия посмотрите тут [see this topic][trust]. Напоминаем что данный уровень доверия сохраняется до тех пор пока вы придерживаетесь этих правил.)\n\n[trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924\n" category: topic_prefix: "Описание раздела %{category}" - replace_paragraph: "[Замените данный текст кратким описанием нового раздела. Это описание будет отображаться в списке разделов, поэтому постарайтесь сделать его коротким (не более 200 символов).]" - post_template: "%{replace_paragraph}\n\nВ следующих абзацах введите более подробное описание раздела, а также возможные правила опубликования тем в нем.\n\nНесколько аспектов, которые следует учитывать:\n\n- Для чего нужен этот раздел? Почему люди выберут этот раздел для размещения своей темы?\n\n- Чем данные раздел отличается от тех, которые у нас уже есть?\n\n- Нужен ли нам этот раздел?\n\n- Стоит ли нам объединить его с другим разделом или разбить на несколько?\n" errors: uncategorized_parent: "Разделу для тем вне разделов нельзя назначать родительский раздел." self_parent: "Подраздел не может быть родительским для самого себя." @@ -780,7 +778,6 @@ ru: summary_likes_required: "Минимальное количество симпатий в теме для активации кнопки \"Сводка по теме\"" summary_percent_filter: "При нажатии на кнопку \"Сводка по теме\", показывать лучшие % сообщений" summary_max_results: "Максимальное количество сообщений, выводимых в 'Обзоре темы'" - enable_private_messages: "Разрешить пользователям 1-го уровеня доверия писать и отвечать на личные сообщения" enable_long_polling: "Использовать механизм long polling для уведомлений о событиях" long_polling_base_url: "Базовый URL, используемый для long polling (при использовании CDN для раздачи динамического контента установите в этом параметре адрес origin pull), например: http://origin.site.com" long_polling_interval: "Время, которое ожидает сервер до ответа клиентам, когда нет данных для отправки (только для пользователей, вошедших на сайт)" @@ -1834,3 +1831,6 @@ ru: performance_report: initial_post_raw: Эта тема содержит ежедневные отчеты активности форума. initial_topic_title: Отчеты активности форума + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.sq.yml b/config/locales/server.sq.yml index 0ade7295f1..f255a925a9 100644 --- a/config/locales/server.sq.yml +++ b/config/locales/server.sq.yml @@ -21,7 +21,7 @@ sq: purge_reason: "Automatically deleted as abandoned, unactivated account" disable_remote_images_download_reason: "Remote images download was disabled because there wasn't enough disk space available." anonymous: "Anonim" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "is limited to %{max} characters; you entered %{length}." @@ -242,6 +242,7 @@ sq: attributes: hex: invalid: "nuk është një ngjyrë e vlefshme" + <<: *errors user_profile: no_info_me: "
    the About Me field of your profile is currently blank, would you like to fill it out?
    " no_info_other: "
    %{name} hasn't entered anything in the About Me field of their profile yet
    " @@ -277,8 +278,6 @@ sq: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "Rreth kategorisë %{category}" - replace_paragraph: "[Replace this first paragraph with a short description of your new category. This guidance will appear in the category selection area, so try to keep it below 200 characters. Until you edit this text or create topics, this category won't appear on the categories page.]" - post_template: "%{replace_paragraph}\n\nUse the following paragraphs for a longer description, as well as to establish any category guidelines or rules.\n\nSome things to consider in any discussion replies below:\n\n- What is this category for? Why should people select this category for their topic?\n\n- How is this different than the other categories we already have?\n\n- Do we need this category?\n\n- Should we merge this with another category, or split it into more categories?\n" errors: uncategorized_parent: "Uncategorized can't have a parent category" self_parent: "A subcategory's parent cannot be itself" @@ -729,7 +728,6 @@ sq: summary_likes_required: "Minimum likes in a topic before 'Summarize This Topic' is enabled" summary_percent_filter: "When a user clicks 'Summarize This Topic', show the top % of posts" summary_max_results: "Maximum posts returned by 'Summary This Topic'" - enable_private_messages: "Allow trust level 1 users to create messages and reply to messages" enable_long_polling: "Message bus used for notification can use long polling" long_polling_base_url: "Base URL used for long polling (when a CDN is serving dynamic content, be sure to set this to origin pull) eg: http://origin.site.com" long_polling_interval: "Amount of time the server should wait before responding to clients when there is no data to send (logged on users only)" @@ -2122,3 +2120,6 @@ sq: performance_report: initial_post_raw: This topic includes daily performance reports for your site. initial_topic_title: Raportet e performancës se faqes + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.sv.yml b/config/locales/server.sv.yml index f7b517db82..ace9e69175 100644 --- a/config/locales/server.sv.yml +++ b/config/locales/server.sv.yml @@ -21,7 +21,7 @@ sv: purge_reason: "Automatiskt raderat i och med att kontot var övergivet och icke-aktiverat" disable_remote_images_download_reason: "Fjärrbilds nedladdning är inaktiverad eftersom det inte fanns tillräckligt mycket lagringsutrymme tillgängligt." anonymous: "Anonym" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "är begränsad till %{max} karaktärer; du skrev in %{length}. " @@ -231,6 +231,7 @@ sv: attributes: hex: invalid: "är inte en giltig färg" + <<: *errors user_profile: no_info_me: "
    Din profils Om Mig-fält är för närvarande tomt, skulle du vilja fylla i det?
    " no_info_other: "
    %{name} har inte skrivit någonting i dess profils Om Mig-fält ännu
    " @@ -244,7 +245,6 @@ sv: title: "Välkommen till loungen" category: topic_prefix: "Om kategorin %{category}" - post_template: "%{replace_paragraph}\n\nUse the following paragraphs for a longer description, as well as to establish any category guidelines or rules.\n\nSome things to consider in any discussion replies below:\n\n- What is this category for? Why should people select this category for their topic?\n\n- How is this different than the other categories we already have?\n\n- Do we need this category?\n\n- Should we merge this with another category, or split it into more categories?\n" errors: uncategorized_parent: "Kategorin \"Okategoriserat\" kan inte ha en föräldrar kategori." self_parent: "En underkategori kan inte ha sig själv som förälder." @@ -1100,3 +1100,6 @@ sv: error: "Fel!" email_input: "E-post till administratör" submit_button: "Skicka e-post" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.te.yml b/config/locales/server.te.yml index 51f6e5885e..a9190f5369 100644 --- a/config/locales/server.te.yml +++ b/config/locales/server.te.yml @@ -20,7 +20,7 @@ te: is_reserved: "రక్షితము" purge_reason: "వదిలేసినదిగా స్వీయంగా కనుగొను, చేతనం చేయని ఖాతా" disable_remote_images_download_reason: "సుదూర బొమ్మల దిగుమతి అచేతనమైంది ఎందుకంటే డిస్క్ జాగా తక్కువగా ఉంది." - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "%{max} అక్షరాలకే పరిమితము. మీరు %{length} అక్షరాలు రాసారు." @@ -191,6 +191,7 @@ te: attributes: hex: invalid: "ఇది చెల్లని రంగు" + <<: *errors user_profile: no_info_other: "
    %{పేరు} ఇంకా వారి ప్రొఫైల్ లో ఎబౌట్ మీ స్థానంలో ఏమీ చేర్చలేదు
    " vip_category_name: "అడ్డా" @@ -692,3 +693,6 @@ te: title: "సేవా నిబంధనలు" privacy_topic: title: "ప్రైవసీ పోలసీ" + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.tr_TR.yml b/config/locales/server.tr_TR.yml index 3ecd3d87ae..260ee8a710 100644 --- a/config/locales/server.tr_TR.yml +++ b/config/locales/server.tr_TR.yml @@ -21,7 +21,7 @@ tr_TR: purge_reason: "Bırakılmış, etkinleştirilmemiş hesap olarak otomatik silindi" disable_remote_images_download_reason: "Yeterli disk alanı kalmaması sebebiyle uzaktan görüntü indirme devre dışı bırakıldı." anonymous: "Anonim" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "%{max} karakter ile limitli; siz %{length} karakter girdiniz." @@ -214,6 +214,7 @@ tr_TR: attributes: hex: invalid: "geçerli bir renk değil" + <<: *errors user_profile: no_info_me: "
    Profilinizdeki Hakkımda bölümü boş, doldurmak ister misiniz?
    " no_info_other: "
    %{name} profilinde Hakkımda kısmına henüz bir şey girmedi
    " @@ -249,8 +250,6 @@ tr_TR: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "%{category} kategorisi hakkında " - replace_paragraph: "[Bu paragrafın yerine kategorinizin kısa bir açıklamasını girin. Buraya yazılanlar kategori seçim alanında görüneceği için, açıklamanızı 200 karakterin altında tutmaya çalışın. Siz bu metni düzenleyene veya herhangi bir konu yaratana kadar bu kategori, kategoriler sayfasında gözükmeyecek.]" - post_template: "%{replace_paragraph}\n\nDaha uzun bir açıklama, kategori yönergeleri veya kuralları oluşturmak için aşağıdaki paragrafları kullanın.\n\nHerhangi bir tartışma için düşünülebilecek bazı maddeler:\n\n- Bu kategorinin amacı ne? İnsanlar konu oluştururken neden bu kategoriyi seçmeliler?\n\n- Bu kategorinin sahip olduğumuz diğer mevcut kategorilerden farkı ne?\n\n- Bu kategoriye ihtiyacımız var mı?\n\n- Bunu başka bir kategoriyle birleştirmeli miyiz, yoksa daha fazla kategoriye mi bölmeli miyiz?\n" errors: uncategorized_parent: "Kategorisizin üst kategorisi olamaz" self_parent: "Alt kategorinin üst kategorisi kendisi olamaz" @@ -439,6 +438,8 @@ tr_TR: title: "Yeni Kullanıcılar" xaxis: "Gün" yaxis: "Yeni kullanıcı sayısı" + profile_views: + xaxis: "Gün" topics: title: "Konular" xaxis: "Gün" @@ -677,7 +678,6 @@ tr_TR: summary_likes_required: "'Bu Konuyu Özetle'nin etkinleştirilmesi için konuda olması gereken en az beğeni sayısı" summary_percent_filter: "Kullanıcı 'Bu Konuyu Özetle'ye tıkladığında, gönderinin ilk % kısmını göster" summary_max_results: "'Bu Konuyu Özetle'den dönen en fazla gönderi sayısı" - enable_private_messages: "Güven seviyesi 1 olan kullanıcıların mesaj oluşturmasına ve mesajlara cevap vermesine izin ver" enable_long_polling: "Bildiri için kullanılan message bus uzun sorgular yapabilir" long_polling_base_url: "Uzun sorgular için kullanılan baz URL (CDN dinamik içerik sunuyorsa, bunu origin olarak ayarladığına emin ol) ör: http://origin.site.com" long_polling_interval: "Gönderilecek bilgi olmadığı zaman sunucunun kullanıcılara geri dönmeden önce beklemesi gereken zaman (sadece giriş yapmış kullanıcın için)" @@ -1130,9 +1130,7 @@ tr_TR: (Eğer yukarıdaki bağlantının süresi dolmuşsa e-posta adresinizle giriş yaparken "Parolamı unuttum" bağlantısına tıklayınız.) test_mailer: subject_template: "[%{site_name}] E-posta Ulaştırma Testi" - text_body_template: "Bu aşağıdaki adresten gönderilen bir test e-postasıdır.\n\n[**%{base_url}**][0]\n\nE-postaların ulaştırılması karışık bir meseledir. Öncelikle dikkat etmeniz gereken bir kaç önemli nokta:\n\n- Site ayarlarınızda 'bildiri e-postaları' için gönderen adresini doğru ayarladığınıza emin olun. **Yolladığınız e-postalarda \"gönderen\" adresi olarak belirlediğiniz alan adı, e-postalarınızın doğrulanacağı alan adıdır.**\n\n- E-posta başlıklarındaki önemli ipuçlarını yakalayabilmek için e-posta istemcinizde e-postaların kaynak kodunu nasıl görüntüleyebileceğinizi öğrenin. Gmail'da, her e-postanın sağ üstündeki açılır menüden \"show original\" opsiyonuna tıklayabilirsiniz.\n\n- **ÖNEMLİ:** ISP'nizde e-posta yollamak için kullanıdığınız alan adlarıyla IP adreslerinin eşleşmesini sağlayacak bir reverse DNS kaydı var mı? Buradan [reverse PTR kayıtlarınızı test edin][2]. Eğer ISP'niz doğru\ - \ reverse DNS pointer kaydı girmezse, büyük ihtimal e-postalarınızın hiç biri yerine ulaşmayacaktır.\n\n- Alan adınızın [SPF kaydı][8] doğru mu? Buradan [SPF kaydınızı test edin][1]. SPF için doğru resmi kayıt tipinin TXT olduğunu unutmayın. \n\n- Alan adınızın [DKIM kaydı][3] doğru mu? Bu e-postaların ulaştırılabilirliğini ciddi şekilde artıracaktır. Buradan [DKIM kaydınızı test edin][7].\n\n- Kendi e-posta sunucunuzu kullanıyorsanız, e-posta sunucunuzun IPlerinin [hiç bir e-posta karalistesine][4] alınmadığına emin olun. Sunucunuzun, kesinlikle, HELO mesajında DNS olarak çözümlenen tam tanımlanmış bilgisayar adı da gönderdiğinden emin olun. Göndermemesi, e-postanızın bir çok e-posta servisi tarafından reddedilmesine sebep olacaktır. \n\n(En kolayı, küçük topluluklar için rahat rahat yetecek sayıda bedava email yollama paketleri içeren, [Mandrill][md] veya [Mailgun][mg] veya [Mailjet][mj]'te\ - \ ücretsiz hesap açmak. Tabi, gene, DNS ayarlarınızda SPF ve DKIM kayıtlarını oluşturmanız gerekecek!) \n\nUmarız bu e-posta ulaştırma testini başarıyla atlatmışsınızdır. \n\nİyi şanslar, \n\n[Discourse](http://www.discourse.org)'tan arkadaşlarınız \n\n[0]: %{base_url} \n[1]: http://www.kitterman.com/spf/validate.html \n[2]: http://mxtoolbox.com/ReverseLookup.aspx \n[3]: http://www.dkim.org/ \n[4]: http://whatismyipaddress.com/blacklist-check \n[7]: http://dkimcore.org/tools/dkimrecordcheck.html \n[8]: http://www.openspf.org/SPF_Record_Syntax [md]: http://mandrill.com [mg]: http://www.mailgun.com/ [mj]: https://www.mailjet.com/pricing\n" + text_body_template: "Bu aşağıdaki adresten gönderilen bir test e-postasıdır.\n\n[**%{base_url}**][0]\n\nE-postaların ulaştırılması karışık bir meseledir. Öncelikle dikkat etmeniz gereken bir kaç önemli nokta:\n\n- Site ayarlarınızda 'bildiri e-postaları' için gönderen adresini doğru ayarladığınıza emin olun. **Yolladığınız e-postalarda \"gönderen\" adresi olarak belirlediğiniz alan adı, e-postalarınızın doğrulanacağı alan adıdır.**\n\n- E-posta başlıklarındaki önemli ipuçlarını yakalayabilmek için e-posta istemcinizde e-postaların kaynak kodunu nasıl görüntüleyebileceğinizi öğrenin. Gmail'da, her e-postanın sağ üstündeki açılır menüden \"show original\" opsiyonuna tıklayabilirsiniz.\n\n- **ÖNEMLİ:** ISP'nizde e-posta yollamak için kullanıdığınız alan adlarıyla IP adreslerinin eşleşmesini sağlayacak bir reverse DNS kaydı var mı? Buradan [reverse PTR kayıtlarınızı test edin][2]. Eğer ISP'niz doğru reverse DNS pointer kaydı girmezse, büyük ihtimal e-postalarınızın hiç biri yerine ulaşmayacaktır.\n\n- Alan adınızın [SPF kaydı][8] doğru mu? Buradan [SPF kaydınızı test edin][1]. SPF için doğru resmi kayıt tipinin TXT olduğunu unutmayın. \n\n- Alan adınızın [DKIM kaydı][3] doğru mu? Bu e-postaların ulaştırılabilirliğini ciddi şekilde artıracaktır. Buradan [DKIM kaydınızı test edin][7].\n\n- Kendi e-posta sunucunuzu kullanıyorsanız, e-posta sunucunuzun IPlerinin [hiç bir e-posta karalistesine][4] alınmadığına emin olun. Sunucunuzun, kesinlikle, HELO mesajında DNS olarak çözümlenen tam tanımlanmış bilgisayar adı da gönderdiğinden emin olun. Göndermemesi, e-postanızın bir çok e-posta servisi tarafından reddedilmesine sebep olacaktır. \n\n(En kolayı, küçük topluluklar için rahat rahat yetecek sayıda bedava email yollama paketleri içeren, [Mandrill][md] veya [Mailgun][mg] veya [Mailjet][mj]'te ücretsiz hesap açmak. Tabi, gene, DNS ayarlarınızda SPF ve DKIM kayıtlarını oluşturmanız gerekecek!) \n\nUmarız bu e-posta ulaştırma testini başarıyla atlatmışsınızdır. \n\nİyi şanslar, \n\n[Discourse](http://www.discourse.org)'tan arkadaşlarınız \n\n[0]: %{base_url} \n[1]: http://www.kitterman.com/spf/validate.html \n[2]: http://mxtoolbox.com/ReverseLookup.aspx \n[3]: http://www.dkim.org/ \n[4]: http://whatismyipaddress.com/blacklist-check \n[7]: http://dkimcore.org/tools/dkimrecordcheck.html \n[8]: http://www.openspf.org/SPF_Record_Syntax [md]: http://mandrill.com [mg]: http://www.mailgun.com/ [mj]: https://www.mailjet.com/pricing\n" new_version_mailer: subject_template: "[%{site_name}] Yeni Discourse versiyonu, güncelleme var" text_body_template: | @@ -1185,12 +1183,7 @@ tr_TR: Daha fazla bilgi için, lütfen [topluluk yönergelerine bakın](%{base_url}/guidelines). usage_tips: - text_body_template: "Hemen başlayabilmeniz için bir kaç pratik tavsiye: \n\n## Okuma\n\nDaha fazla okumak için, **sayfayı aşağı kaydırmanız yeterli!** \n\nYeni cevaplar ve konular oluşturuldukça, otomatik olarak görünecekler. \n\n## Gezinme\n\n- Arama, kullanıcı sayfanız veya menü için **sağ üstteki ikonlu butona** tıklayın. \n\n- Herhangi bir konu başlığı sizi bir sonraki okunmamış gönderiye götürür. En üst veya en alta gitmek için gönderi sayısına veya son cevap tarihini tıklayın.\n\n \n\n- Bir konuyu okurken, tüm navigasyonla ilgili kontroller için sağ alttaki yeşil ilerleme barını seçin. Hızlıca en yukarıya gitmek için konu başlığına tıklayın. Klavye kısayollarını görüntülemek için ? tuşuna basın. \n\n \n\n## Cevaplama \n\n- **Genel olarak konuya** cevap vermek için, sayfanın en altındaki Cevapla butonunu kullanın. \n\n- **Belirli bir kişiye** cevap vermek için, o gönderinin altında bulunan Cevapla butonunu kullanın. \n\n- **Yeni bir konu\" oluşturarak cevaplamak için, gönderinin sağında çıkan ikonuna tıklayın. Eski ve yeni konular birbirleriyle otomatik olarak ilişkilendirilecek.\n\nAlıntı yapmak için, alıntı yapmak istediğiniz metni seçin ve sonrasında herhangi bir Cevapla butonuna tıklayın. Çoklu alıntılar için adımları tekrarlayın! \n\n \n\nBirine cevabınızla ilgili bildiri gitmesini istiyorsanız, o kişinin isminden bahsedin. Kullanıcı adı seçimine başlamak için `@` yazın. \n\n \n\n[Standart Emoji](http://www.emoji.codes/) için, `:` yazın ya da gülücük `;)` atın \n\nBir bağlantı için özet oluşturmak istiyorsanız, bağlantıyı kopyalayıp tek başına bir satıra yapıştırın:\n\n\n\n## Aksiyonlar\n\nHer gönderinin altında aksiyon butonları vardır. \n\nBirine gönderisini beğendiğinizi belirtmek istiyorsanız, **beğen** butonunu\ - \ kullanın. Sevginizi paylaşın!\n\nBirinin gönderisiyle ilgili bir sorun görüyorsanız, özelden bu kişileri veya [görevlileri](%{base_url}/about) uyarmak için **bayrakla** butonunu kullanın. **Paylaş** butonu aracılığıyla gönderiye bir bağlantı paylaşabilir, veya **işaretle** butonu ile gönderiyi işaretleyip sonrasında kullanıcı sayfanızdan kolayca ulaşabilirsiniz. \n\n## Bildiriler \n\nBiri gönderinize cevap verir, gönderinizi alıntılar ya da `@kullanıcıadı` nızdan bahsederse, sayfanızın en sağ üstünde bir sayı hemen beliriverir. Bu sayıya tıklayarak **bildiriler**inize ulaşabilirsiniz. \n\n\n\nBir cevabı kaçıracaksınız diye kaygılanmayın – çevrimiçi olmadığınız zaman gelen bildiriler size e-postalanır.\n\n## Seçenekleriniz\n\nÜzerinden henüz **iki gün geçmemiş** tüm konular yeni sayılır. \n\n**Aktif\ - \ olarak katıldığınız** (oluşturduğunuz, cevapladığınız, veya uzun bir süre okuduğunuz) tüm sohbetler otomatik olarak takip edilir. \n\nBu konuların yanında, yeni ve okunmamışlar gönderilerin sayılarını gösteren mavi işaretler göreceksiniz: \n\n \n\nHerhangi bir konunun bildiri ayarını o konunun altında bulunan bildiri kontrolü aracılığıyla değiştirebilirsiniz. \n\n \n\nBildiri ayarlarını kategori bazında da değiştirebilirsiniz, eğer belirli bir kategorideki her yeni konuyu gözlemek istiyorsanız. Bu ayarların herhangi birini değiştirmek için, [kullanıcı ayarlarınıza](%{base_url}/my/preferences) göz atın. \n\n## Topluluğun Güveni\n\nBurada sohbetlere katıldıkça, topluluğun güvenini kazanırsınız,\ - \ onun tam bir parçası haline gelirsiniz ve yeni kullanıcılar için konulan limitler kalkar. Yeterli yükseklikteki [güvenlik seviyelerinde](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924) ise topluluğumuzu birlikte yönetmemize yardımcı olabilmenizi sağlayacak yetkiler kazanırsınız.\n" + text_body_template: "Hemen başlayabilmeniz için bir kaç pratik tavsiye: \n\n## Okuma\n\nDaha fazla okumak için, **sayfayı aşağı kaydırmanız yeterli!** \n\nYeni cevaplar ve konular oluşturuldukça, otomatik olarak görünecekler. \n\n## Gezinme\n\n- Arama, kullanıcı sayfanız veya menü için **sağ üstteki ikonlu butona** tıklayın. \n\n- Herhangi bir konu başlığı sizi bir sonraki okunmamış gönderiye götürür. En üst veya en alta gitmek için gönderi sayısına veya son cevap tarihini tıklayın.\n\n \n\n- Bir konuyu okurken, tüm navigasyonla ilgili kontroller için sağ alttaki yeşil ilerleme barını seçin. Hızlıca en yukarıya gitmek için konu başlığına tıklayın. Klavye kısayollarını görüntülemek için ? tuşuna basın. \n\n \n\n## Cevaplama \n\n- **Genel olarak konuya** cevap vermek için, sayfanın en altındaki Cevapla butonunu kullanın. \n\n- **Belirli bir kişiye** cevap vermek için, o gönderinin altında bulunan Cevapla butonunu kullanın. \n\n- **Yeni bir konu\" oluşturarak cevaplamak için, gönderinin sağında çıkan ikonuna tıklayın. Eski ve yeni konular birbirleriyle otomatik olarak ilişkilendirilecek.\n\nAlıntı yapmak için, alıntı yapmak istediğiniz metni seçin ve sonrasında herhangi bir Cevapla butonuna tıklayın. Çoklu alıntılar için adımları tekrarlayın! \n\n \n\nBirine cevabınızla ilgili bildiri gitmesini istiyorsanız, o kişinin isminden bahsedin. Kullanıcı adı seçimine başlamak için `@` yazın. \n\n \n\n[Standart Emoji](http://www.emoji.codes/) için, `:` yazın ya da gülücük `;)` atın \n\nBir bağlantı için özet oluşturmak istiyorsanız, bağlantıyı kopyalayıp tek başına bir satıra yapıştırın:\n\n\n\n## Aksiyonlar\n\nHer gönderinin altında aksiyon butonları vardır. \n\nBirine gönderisini beğendiğinizi belirtmek istiyorsanız, **beğen** butonunu kullanın. Sevginizi paylaşın!\n\nBirinin gönderisiyle ilgili bir sorun görüyorsanız, özelden bu kişileri veya [görevlileri](%{base_url}/about) uyarmak için **bayrakla** butonunu kullanın. **Paylaş** butonu aracılığıyla gönderiye bir bağlantı paylaşabilir, veya **işaretle** butonu ile gönderiyi işaretleyip sonrasında kullanıcı sayfanızdan kolayca ulaşabilirsiniz. \n\n## Bildiriler \n\nBiri gönderinize cevap verir, gönderinizi alıntılar ya da `@kullanıcıadı` nızdan bahsederse, sayfanızın en sağ üstünde bir sayı hemen beliriverir. Bu sayıya tıklayarak **bildiriler**inize ulaşabilirsiniz. \n\n\n\nBir cevabı kaçıracaksınız diye kaygılanmayın – çevrimiçi olmadığınız zaman gelen bildiriler size e-postalanır.\n\n## Seçenekleriniz\n\nÜzerinden henüz **iki gün geçmemiş** tüm konular yeni sayılır. \n\n**Aktif olarak katıldığınız** (oluşturduğunuz, cevapladığınız, veya uzun bir süre okuduğunuz) tüm sohbetler otomatik olarak takip edilir. \n\nBu konuların yanında, yeni ve okunmamışlar gönderilerin sayılarını gösteren mavi işaretler göreceksiniz: \n\n \n\nHerhangi bir konunun bildiri ayarını o konunun altında bulunan bildiri kontrolü aracılığıyla değiştirebilirsiniz. \n\n \n\nBildiri ayarlarını kategori bazında da değiştirebilirsiniz, eğer belirli bir kategorideki her yeni konuyu gözlemek istiyorsanız. Bu ayarların herhangi birini değiştirmek için, [kullanıcı ayarlarınıza](%{base_url}/my/preferences) göz atın. \n\n## Topluluğun Güveni\n\nBurada sohbetlere katıldıkça, topluluğun güvenini kazanırsınız, onun tam bir parçası haline gelirsiniz ve yeni kullanıcılar için konulan limitler kalkar. Yeterli yükseklikteki [güvenlik seviyelerinde](https://meta.discourse.org/t/what-do-user-trust-levels-do/4924) ise topluluğumuzu birlikte yönetmemize yardımcı olabilmenizi sağlayacak yetkiler kazanırsınız.\n" welcome_user: subject_template: "%{site_name} sitesine hoşgeldiniz!" text_body_template: "%{site_name} sitesine katıldığınız için teşekkür ederiz, hoşgeldiniz!\n\n%{new_user_tips}\n\nBiz her zaman [medeni topluluk davranışına](%{base_url}/guidelines) inanıyoruz. \n\nZiyaretinizin keyfini çıkarın!\n\n(Eğer yeni bir kullanıcı olarak [görevlilerle](%{base_url}/about) iletişim kurmak isterseniz, bu mesajı cevaplamanız yeterli.)\n" @@ -1647,3 +1640,6 @@ tr_TR: performance_report: initial_post_raw: Bu konu siteniz hakkında günlük performans raporlarını içerir. initial_topic_title: Site performansı raporları + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.uk.yml b/config/locales/server.uk.yml index b187edd567..63111f3a9e 100644 --- a/config/locales/server.uk.yml +++ b/config/locales/server.uk.yml @@ -115,8 +115,6 @@ uk: staff_category_description: "Закрита категорія для обговорень між персоналом. Теми бачать тільки адміністратори та модератори." category: topic_prefix: "Про категорію %{category}" - replace_paragraph: "[Замініть цей перший абзац коротким описом Вашої нової категорії. Він з'являтиметься в області вибору категорій, тому намагайтеся, щоб він був коротшим за 200 символів. Поки Ви не відредагуєте цей текст або не створите тем, ця категорія не з'явиться на сторінці категорій.]" - post_template: "%{replace_paragraph}\n\nВикористовуйте наступні абзаци для довшого опису, а також для того, щоб встановити якісь правила категорії.\n\nДеякі речі, які можна обговорити у відповідях на цей допис:\n\n- Для чого потрібна ця категорія? Чому людям слід обирати цю категорію для своїх тем?\n\n- Чим вона відрізняється від інших категорій, що в нас є?\n\n- Чи потрібна нам ця категорія?\n\n- Чи потрібно об'єднати цю категорію з якоюсь іншою, або розбити її на декілька?\n" errors: depth: "Ви не можете вкладати підкатегорію під іншу" trust_levels: diff --git a/config/locales/server.zh_CN.yml b/config/locales/server.zh_CN.yml index 84e37cf5b6..2eab02b0a6 100644 --- a/config/locales/server.zh_CN.yml +++ b/config/locales/server.zh_CN.yml @@ -21,7 +21,7 @@ zh_CN: purge_reason: "自动删除被遗弃、未激活账户" disable_remote_images_download_reason: "磁盘空间不足,远程图像下载已经被禁用。" anonymous: "匿名" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "最多只能有 %{max} 个字符;你已经输入了 %{length} 个字符。" @@ -241,6 +241,7 @@ zh_CN: attributes: hex: invalid: "不是有效颜色值" + <<: *errors user_profile: no_info_me: "
    你的资料中,关于我部分目前还是空白,你想要写些什么吗?
    " no_info_other: "
    %{name} 尚未在他们的资料中的关于我部分填写任何信息
    " @@ -276,8 +277,6 @@ zh_CN: [trust]: https://meta.discourse.org/t/what-do-user-trust-levels-do/4924 category: topic_prefix: "关于分类:%{category}" - replace_paragraph: "[用一段简短的话描述分类,并替换这第一段的内容。这段文字将出现在分类选择区域,所以尽量不要超过200个字符。当你编辑了这段文字或者再次分类创建了一个主题后,分类才会出现在分类列表中。]" - post_template: "%{replace_paragraph}\n\n在接下来的一段文字中输入分类的详细描述信息,可以在这里包含在此分类下讨论的规则、内容导向等等。\n\n考虑这些事情:\n\n- 这个分类用来做什么? 为什么人们选择这个分类寻找主题?\n\n- 这个分类和其他已有分类有什么不同?\n\n- 我们需要这个分类么?\n\n- 我们应该和已有分类合并吗?还是分离成更多的分类?\n" errors: uncategorized_parent: "未分类不能有一个父分类" self_parent: "一个子分类不能属于它自己。" @@ -720,7 +719,6 @@ zh_CN: summary_likes_required: "在一个主题启用'摘要模式'的最小赞的数量" summary_percent_filter: "当用户点击摘要,显示前 % 几的帖子" summary_max_results: "“概括主题”返回的最大帖子数量" - enable_private_messages: "允许信任等级1的用户创建消息或者以消息回复" enable_long_polling: "启用 Message bus 使通知功能可以使用长轮询(long polling)" long_polling_base_url: "长轮询的基本 URL(当用 CDN 分发动态能让时,请设置此至原始拉取地址)例如:http://origin.site.com" long_polling_interval: "当没有数据向客户端发送时服务器端应等待的时间(仅对已登录用户有效)" @@ -1827,8 +1825,7 @@ zh_CN: 编辑本主题的第一帖以改变 %{page_name} 页面的内容。 guidelines_topic: title: "FAQ/指引" - body: "\n\n## [这是一个文明讨论的地方](#civilized)\n\n在论坛上请表现得像在公共公园一样得体。我们一群人共享着一个公共社群资源 — 一个通过不断进行讨论以分享我们技能、知识和兴趣的地方。\n\n这些都不是死规矩或者是草率决定,只是一些帮助社群的人们来判断的规定。试用这些指引来保持干净和充满灵感的文明的公开论坛。 \n\n\n\n## [改善讨论](#improve)\n\n帮助我们让这个地方变成一个讨论的好地方。你可以总是一致的做一些帮助改善讨论的事,即使是小事也行。如果你不确定你的帖子有益于讨论,认真想一想你要说什么再发布。\n\n这里讨论的主题对我们很重要,并且我们希望你也觉得这些内容对你很重要。尊重这些讨论的主题,以及讨论他们的人们,特别是当你不同意他们所说的时候。\n\n改善讨论的一种方法是找一找已经发生过的事。请在发帖或创建你自己的主题前,花一些时间浏览这些主题,这样你更有机会遇见和你有共同爱好的人。 \n\n\n\n## [即使你不同意他人时,尊重他人](#agreeable)\n\n你可能想表达你的不同意。这没问题。但是,记住_批评观点,而不是人_。请避免:\n\n* 指名道姓。\n* 人生攻击。\n* 回复帖子无关于帖子的内容。\n* 下意识的反驳。\n\n相反,提供合理的观点改善讨论。 \n\n\n\n## [你的参与有意义](#participate)\n\n我们在这儿的讨论为大家树立了榜样。通过选择参与有意义的讨论,帮助我们将论坛变成一个有意思的地方 — 并且避免那些没有帮助的行为。\n\nDiscourse 提供了让社群共同鉴别最棒(或最差)的贡献的工具:收藏、书签、赞、标记、回复和编辑等等。使用这些工具不仅能改善你自己的体验,也能改善其他人的体验。\n\n让我们创造一个更美好的社群。\n\n\n\n## [如果你发现问题了,标记它](#flag-problems)\n版主有特别的权力;他们对论坛负责。但是你也是。有了你的帮助,版主能成为社群监察者,而不仅是守卫或者警察。\n\n当你见到不合适的行为,不要回复。这种承认变相鼓励了这种不合适的行为,浪费了你的精力,并且浪费了每一个人的时间。_只要标记它。_如果收到了足够的标记,将会有相应的处理,这个处理可能是自动地,也可能由版主介入。\n\n为了维护我们的社群,版主保留了任何情况下删除任何内容和任何用户的权力。版主没有预先审核任何新帖子;版主和站点维护人员对社群里发表的任何言论均不负责任。 \n\n\n\n## [永远保持文明](#be-civil)\n\n粗鲁这样的行为会破坏健康的讨论:\n\n* 文明。不要发表任何理智的人会认为冒犯的、过分的或招致怨恨的言论。\n* 拒绝色情。不要发表任何淫秽或性暗示的东西。\n* 尊重每一个人。不要骚扰或者让别人难过,检视别人,或暴露他们的个人信息。\n* 尊重我们的论坛。不要发表广告或者其他垃圾信息。\n\n这些条款不是法律条文,并且没有准确的定义 — 避免任何做关于他们的_可能擦边_的事。如果你不确定,问问自己的帖子是否能出现在纽约时报的头版头条上。\n\n这是一个公共论坛,并且搜索引擎会索引这些讨论。注意发表的语言、链接和图片,不要在其中包含你的家庭和朋友。 \n\n\n\n## [保持整洁](#keep-tidy)\n\n花一点时间让东西出现在正确的位置,这样我们能花更多的时间在讨论上而非清理格式。所以:\n\n* 不要在错误的分类发表新主题。\n* 不要在多个主题中回复同样的内容。\n* 不要发布没有内容的回复。\n* 不要在中途改变主题。\n* 不要在你的帖子中签名 — 每一贴都附有你的个人信息。\n\n比起发表“+1”或者“同意”,使用赞按钮。比起将帖子带向一个决然不同的方向,使用“回复为关联主题”。\n\n\n\n## [只发表你自己的东西](#stealing)\n\n你不能在没有他人授权的情况下发表任何属于他人的数字资产。你可能不能发表关于窃据他人知识产权(软件、视频、音频和图像)的任何简介、链接或方法,或其他任何违反法律的内容。 \n\n\n\n## [有你参与](#power)\n\n这个站点由[一群友善的职员](/about)、你和社群一起运营。如果你对这里的事情仍有疑问,在[站点反馈](/c/site-feedback)分类新建一个主题并且开始讨论!如果遇到了重要或紧急的事情,并且不能用站务分类的主题或标记解决,通过[职员页面](/about)联系我们。\n\ - \n\n\n## [使用条款](#tos)\n\n是的,法律很无聊,但是我们必须保护我们自己 – 引申开来,你和你的数据 – 用于针对不友好的家伙们。我们有一个[使用条款](/tos)描述你的(以及我们)关于内容、隐私和法律的行为和权力。要使用我们的服务,你必须同意遵守[使用条款](/tos)。\n" + body: "\n\n## [这是一个文明讨论的地方](#civilized)\n\n在论坛上请表现得像在公共公园一样得体。我们一群人共享着一个公共社群资源 — 一个通过不断进行讨论以分享我们技能、知识和兴趣的地方。\n\n这些都不是死规矩或者是草率决定,只是一些帮助社群的人们来判断的规定。试用这些指引来保持干净和充满灵感的文明的公开论坛。 \n\n\n\n## [改善讨论](#improve)\n\n帮助我们让这个地方变成一个讨论的好地方。你可以总是一致的做一些帮助改善讨论的事,即使是小事也行。如果你不确定你的帖子有益于讨论,认真想一想你要说什么再发布。\n\n这里讨论的主题对我们很重要,并且我们希望你也觉得这些内容对你很重要。尊重这些讨论的主题,以及讨论他们的人们,特别是当你不同意他们所说的时候。\n\n改善讨论的一种方法是找一找已经发生过的事。请在发帖或创建你自己的主题前,花一些时间浏览这些主题,这样你更有机会遇见和你有共同爱好的人。 \n\n\n\n## [即使你不同意他人时,尊重他人](#agreeable)\n\n你可能想表达你的不同意。这没问题。但是,记住_批评观点,而不是人_。请避免:\n\n* 指名道姓。\n* 人生攻击。\n* 回复帖子无关于帖子的内容。\n* 下意识的反驳。\n\n相反,提供合理的观点改善讨论。 \n\n\n\n## [你的参与有意义](#participate)\n\n我们在这儿的讨论为大家树立了榜样。通过选择参与有意义的讨论,帮助我们将论坛变成一个有意思的地方 — 并且避免那些没有帮助的行为。\n\nDiscourse 提供了让社群共同鉴别最棒(或最差)的贡献的工具:收藏、书签、赞、标记、回复和编辑等等。使用这些工具不仅能改善你自己的体验,也能改善其他人的体验。\n\n让我们创造一个更美好的社群。\n\n\n\n## [如果你发现问题了,标记它](#flag-problems)\n版主有特别的权力;他们对论坛负责。但是你也是。有了你的帮助,版主能成为社群监察者,而不仅是守卫或者警察。\n\n当你见到不合适的行为,不要回复。这种承认变相鼓励了这种不合适的行为,浪费了你的精力,并且浪费了每一个人的时间。_只要标记它。_如果收到了足够的标记,将会有相应的处理,这个处理可能是自动地,也可能由版主介入。\n\n为了维护我们的社群,版主保留了任何情况下删除任何内容和任何用户的权力。版主没有预先审核任何新帖子;版主和站点维护人员对社群里发表的任何言论均不负责任。 \n\n\n\n## [永远保持文明](#be-civil)\n\n粗鲁这样的行为会破坏健康的讨论:\n\n* 文明。不要发表任何理智的人会认为冒犯的、过分的或招致怨恨的言论。\n* 拒绝色情。不要发表任何淫秽或性暗示的东西。\n* 尊重每一个人。不要骚扰或者让别人难过,检视别人,或暴露他们的个人信息。\n* 尊重我们的论坛。不要发表广告或者其他垃圾信息。\n\n这些条款不是法律条文,并且没有准确的定义 — 避免任何做关于他们的_可能擦边_的事。如果你不确定,问问自己的帖子是否能出现在纽约时报的头版头条上。\n\n这是一个公共论坛,并且搜索引擎会索引这些讨论。注意发表的语言、链接和图片,不要在其中包含你的家庭和朋友。 \n\n\n\n## [保持整洁](#keep-tidy)\n\n花一点时间让东西出现在正确的位置,这样我们能花更多的时间在讨论上而非清理格式。所以:\n\n* 不要在错误的分类发表新主题。\n* 不要在多个主题中回复同样的内容。\n* 不要发布没有内容的回复。\n* 不要在中途改变主题。\n* 不要在你的帖子中签名 — 每一贴都附有你的个人信息。\n\n比起发表“+1”或者“同意”,使用赞按钮。比起将帖子带向一个决然不同的方向,使用“回复为关联主题”。\n\n\n\n## [只发表你自己的东西](#stealing)\n\n你不能在没有他人授权的情况下发表任何属于他人的数字资产。你可能不能发表关于窃据他人知识产权(软件、视频、音频和图像)的任何简介、链接或方法,或其他任何违反法律的内容。 \n\n\n\n## [有你参与](#power)\n\n这个站点由[一群友善的职员](/about)、你和社群一起运营。如果你对这里的事情仍有疑问,在[站点反馈](/c/site-feedback)分类新建一个主题并且开始讨论!如果遇到了重要或紧急的事情,并且不能用站务分类的主题或标记解决,通过[职员页面](/about)联系我们。\n\n\n\n## [使用条款](#tos)\n\n是的,法律很无聊,但是我们必须保护我们自己 – 引申开来,你和你的数据 – 用于针对不友好的家伙们。我们有一个[使用条款](/tos)描述你的(以及我们)关于内容、隐私和法律的行为和权力。要使用我们的服务,你必须同意遵守[使用条款](/tos)。\n" tos_topic: title: "服务条款" body: | @@ -2135,3 +2132,6 @@ zh_CN: performance_report: initial_post_raw: 这个主题包括你网站的每日性能报告 initial_topic_title: 网站性能报告 + activemodel: + errors: + <<: *errors diff --git a/config/locales/server.zh_TW.yml b/config/locales/server.zh_TW.yml index 36b8da5627..f3eeeac7f6 100644 --- a/config/locales/server.zh_TW.yml +++ b/config/locales/server.zh_TW.yml @@ -21,7 +21,7 @@ zh_TW: purge_reason: "自動刪除被遺棄、未啟用賬戶" disable_remote_images_download_reason: "磁盤空間不足,圖像下載已被禁用。" anonymous: "匿名" - errors: + errors: &errors format: '%{attribute} %{message}' messages: too_long_validation: "限制 %{max} 個字元,你已經輸入了 %{length} 個字元" @@ -193,6 +193,7 @@ zh_TW: attributes: hex: invalid: "不是一個有效顏色" + <<: *errors user_profile: no_info_me: "
    你的自我簡介中,“關於我” 部分目前還沒有內容,不如來自我介紹一下?
    " no_info_other: "
    %{name} 尚未在他/她自我簡介中的“關於我”部分填寫任何資訊
    " @@ -205,8 +206,6 @@ zh_TW: title: "歡迎來到貴賓室" category: topic_prefix: "對於分類:%{category} 的定義" - replace_paragraph: "[ 將此首段文字替換為描述新分類的簡短說明。說明將會出現在分類選擇區裡,故請盡量少於 200 個字元。在你編輯此處文字或者新增討論話題之前,此分類將不會顯示在分類頁面上。]" - post_template: "%{replace_paragraph}\n\n在下面的空格輸入分類的詳細描述, 可以包括在此分類下討論的規則、內容主題等等。" errors: uncategorized_parent: "未分類不能有一個父分類" self_parent: "一個子分類的上層不能是自己" @@ -1129,3 +1128,6 @@ zh_TW: error: "錯誤" email_input: "管理者郵件" submit_button: "送出電子郵件" + activemodel: + errors: + <<: *errors diff --git a/config/routes.rb b/config/routes.rb index cc55476b0a..0af5799a22 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -60,6 +60,9 @@ Discourse::Application.routes.draw do resources :groups, constraints: AdminConstraint.new do collection do post "refresh_automatic_groups" => "groups#refresh_automatic_groups" + get 'bulk' + get 'bulk-complete' => 'groups#bulk' + put 'bulk' => 'groups#bulk_perform' end member do put "members" => "groups#add_members" diff --git a/config/site_settings.yml b/config/site_settings.yml index 73c801b2c9..1497138727 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -342,6 +342,9 @@ users: client: true anonymous_account_duration_minutes: default: 10080 + hide_user_profiles_from_public: + default: false + client: true posting: min_post_length: diff --git a/db/migrate/20151103233815_add_lower_title_index_on_topics.rb b/db/migrate/20151103233815_add_lower_title_index_on_topics.rb new file mode 100644 index 0000000000..bdd93fd533 --- /dev/null +++ b/db/migrate/20151103233815_add_lower_title_index_on_topics.rb @@ -0,0 +1,9 @@ +class AddLowerTitleIndexOnTopics < ActiveRecord::Migration + def up + execute "CREATE INDEX index_topics_on_lower_title ON topics (LOWER(title))" + end + + def down + execute "DROP INDEX index_topics_on_lower_title" + end +end diff --git a/docs/INSTALL-cloud.md b/docs/INSTALL-cloud.md index 96a4a3fdea..d3387f1df5 100644 --- a/docs/INSTALL-cloud.md +++ b/docs/INSTALL-cloud.md @@ -1,8 +1,8 @@ -**Set up Discourse in the cloud in under 30 minutes** with zero knowledge of Rails or Linux shell using our [Discourse Docker image][dd]. We recommend [Digital Ocean][do], but these steps will work on any Docker-compatible cloud provider or local server. +**Set up Discourse in the cloud in under 30 minutes** with zero knowledge of Rails or Linux shell using our [Discourse Docker image][dd]. We recommend [DigitalOcean][do], but these steps will work on any Docker-compatible cloud provider or local server. # Create New Cloud Server -[Sign up for Digital Ocean][do], update billing info, then create your new cloud server. +[Sign up for DigitalOcean][do], update billing info, then create your new cloud server. - Enter your domain `discourse.example.com` as the name. @@ -22,7 +22,7 @@ Connect to your server via SSH, or use [Putty][put] on Windows: Replace `192.168.1.1` with the IP address of your server. -You will be asked for permission to connect, type `yes`, then enter the root password from the email Digital Ocean sent you when the server was set up. You may be prompted to change the root password, too. +You will be asked for permission to connect, type `yes`, then enter the root password from the email DigitalOcean sent you when the server was set up. You may be prompted to change the root password, too. diff --git a/lib/auth/result.rb b/lib/auth/result.rb index 461c8f7c9f..3c78b2cf5f 100644 --- a/lib/auth/result.rb +++ b/lib/auth/result.rb @@ -46,15 +46,18 @@ class Auth::Result } end else - { - email: email, - name: User.suggest_name(name || username || email), - username: UserNameSuggester.suggest(username || name || email), - # this feels a tad wrong - auth_provider: authenticator_name.capitalize, - email_valid: !!email_valid, - omit_username: !!omit_username - } + result = { email: email, + username: UserNameSuggester.suggest(username || name || email), + # this feels a tad wrong + auth_provider: authenticator_name.capitalize, + email_valid: !!email_valid, + omit_username: !!omit_username } + + if SiteSetting.enable_names? + result[:name] = User.suggest_name(name || username || email) + end + + result end end end diff --git a/lib/autospec/manager.rb b/lib/autospec/manager.rb index 45256015d6..cf06e80068 100644 --- a/lib/autospec/manager.rb +++ b/lib/autospec/manager.rb @@ -148,8 +148,7 @@ class Autospec::Manager puts "@@@@@@@@@@@@ listen_for_changes" if @debug options = { - ignore: /^public|^lib\/autospec/, - relative_paths: true, + ignore: /^lib\/autospec/, } if @opts[:force_polling] @@ -157,11 +156,20 @@ class Autospec::Manager options[:latency] = @opts[:latency] || 3 end - Thread.start do - Listen.to('.', options) do |modified, added, _| - process_change([modified, added].flatten.compact) + path = File.expand_path(File.dirname(__FILE__) + "../../..") + + # to speed up boot we use a thread + Thread.new do + ["spec", "lib", "app", "config", "test", "vendor", "plugins"].each do |watch| + Listen.to("#{path}/#{watch}", options) do |modified, added, _| + paths = [modified, added].flatten + paths.compact! + paths.map!{|long| long[(path.length+1)..-1]} + process_change(paths) + end end end + end def process_change(files) diff --git a/lib/email/message_builder.rb b/lib/email/message_builder.rb index bacc5f1cf1..f805328795 100644 --- a/lib/email/message_builder.rb +++ b/lib/email/message_builder.rb @@ -68,7 +68,7 @@ module Email html_override.gsub!("%{unsubscribe_link}", unsubscribe_link) end - styled = Email::Styles.new(html_override) + styled = Email::Styles.new(html_override, @opts) styled.format_basic if style = @opts[:style] diff --git a/lib/email/renderer.rb b/lib/email/renderer.rb index 4f21cb8bf7..9b209781ff 100644 --- a/lib/email/renderer.rb +++ b/lib/email/renderer.rb @@ -16,11 +16,11 @@ module Email def html if @message.html_part - style = Email::Styles.new(@message.html_part.body.to_s) + style = Email::Styles.new(@message.html_part.body.to_s, @opts) style.format_basic style.format_html else - style = Email::Styles.new(PrettyText.cook(text)) + style = Email::Styles.new(PrettyText.cook(text), @opts) style.format_basic end diff --git a/lib/email/sender.rb b/lib/email/sender.rb index d1720aedd9..8e0080c9a2 100644 --- a/lib/email/sender.rb +++ b/lib/email/sender.rb @@ -87,12 +87,12 @@ module Email # http://www.ietf.org/rfc/rfc2919.txt if topic && topic.category && !topic.category.uncategorized? - list_id = "<#{topic.category.name.downcase}.#{host}>" + list_id = "<#{topic.category.name.downcase.gsub(' ', '-')}.#{host}>" # subcategory case if !topic.category.parent_category_id.nil? parent_category_name = Category.find_by(id: topic.category.parent_category_id).name - list_id = "<#{topic.category.name.downcase}.#{parent_category_name.downcase}.#{host}>" + list_id = "<#{topic.category.name.downcase.gsub(' ', '-')}.#{parent_category_name.downcase.gsub(' ', '-')}.#{host}>" end else list_id = "<#{host}>" diff --git a/lib/email/styles.rb b/lib/email/styles.rb index 22f9ffe1e8..6f0dd6c2b2 100644 --- a/lib/email/styles.rb +++ b/lib/email/styles.rb @@ -6,8 +6,9 @@ module Email class Styles @@plugin_callbacks = [] - def initialize(html) + def initialize(html, opts=nil) @html = html + @opts = opts || {} @fragment = Nokogiri::HTML.fragment(@html) end @@ -30,7 +31,6 @@ module Email # images @fragment.css('img').each do |img| - next if img['class'] == 'site-logo' if img['class'] == "emoji" || img['src'] =~ /plugins\/emoji/ @@ -42,7 +42,6 @@ module Email img['width'] = 'auto' img['height'] = 'auto' end - add_styles(img, 'max-width:100%;') if img['style'] !~ /max-width/ end # ensure all urls are absolute @@ -56,9 +55,16 @@ module Email end end + # add max-width to big images + big_images = @fragment.css('img[width="auto"][height="auto"]') - + @fragment.css('aside.onebox img') - + @fragment.css('img.site-logo, img.emoji') + big_images.each do |img| + add_styles(img, 'max-width: 100%;') if img['style'] !~ /max-width/ + end + # attachments @fragment.css('a.attachment').each do |a| - # ensure all urls are absolute if a['href'] =~ /^\/[^\/]/ a['href'] = "#{Discourse.base_url}#{a['href']}" @@ -92,11 +98,15 @@ module Email def onebox_styles # Links to other topics - style('aside.quote', 'border-left: 5px solid #bebebe; background-color: #f1f1f1; padding: 12px 25px 2px 12px; margin-bottom: 10px;') - style('aside.quote blockquote', 'border: 0px; padding: 0; margin: 7px 0') + style('aside.quote', 'border-left: 5px solid #e9e9e9; background-color: #f8f8f8; padding: 12px 25px 2px 12px; margin-bottom: 10px;') + style('aside.quote blockquote', 'border: 0px; padding: 0; margin: 7px 0; background-color: clear;') + style('aside.quote blockquote > p', 'padding: 0;') style('aside.quote div.info-line', 'color: #666; margin: 10px 0') style('aside.quote .avatar', 'margin-right: 5px; width:20px; height:20px') + style('blockquote', 'border-left: 5px solid #e9e9e9; background-color: #f8f8f8; margin: 0;') + style('blockquote > p', 'padding: 1em;') + # Oneboxes style('aside.onebox', "padding: 12px 25px 2px 12px; border-left: 5px solid #bebebe; background: #eee; margin-bottom: 10px;") style('aside.onebox img', "max-height: 80%; max-width: 25%; height: auto; float: left; margin-right: 10px; margin-bottom: 10px") @@ -146,7 +156,7 @@ module Email # this method is reserved for styles specific to plugin def plugin_styles - @@plugin_callbacks.each { |block| block.call(@fragment) } + @@plugin_callbacks.each { |block| block.call(@fragment, @opts) } end def to_html diff --git a/lib/email_cook.rb b/lib/email_cook.rb index 33693190cb..48aea34454 100644 --- a/lib/email_cook.rb +++ b/lib/email_cook.rb @@ -1,6 +1,11 @@ # A very simple formatter for imported emails + class EmailCook + def self.url_regexp + /[^\>]*((?:https?:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.])(?:[^\s()<>]+|\([^\s()<>]+\))+(?:\([^\s()<>]+\)|[^`!()\[\]{};:'".,<>?«»\s]))/ + end + def initialize(raw) @raw = raw end @@ -20,6 +25,11 @@ class EmailCook quote_buffer = "" in_quote = false else + + l.scan(EmailCook.url_regexp).each do |m| + url = m[0] + l.gsub!(url, "#{url}") + end result << l << "
    " end end @@ -29,7 +39,6 @@ class EmailCook end result.gsub!(/(
    ){3,10}/, '

    ') - result end diff --git a/lib/guardian.rb b/lib/guardian.rb index 3896a02c12..78dcee9cd5 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -212,7 +212,7 @@ class Guardian def can_invite_to?(object, group_ids=nil) return false if ! authenticated? - return false unless ( SiteSetting.enable_local_logins && (!SiteSetting.must_approve_users? || is_staff?) ) + return false unless (!SiteSetting.must_approve_users? || is_staff?) return true if is_admin? return false if (SiteSetting.max_invites_per_day.to_i == 0 && !is_staff?) return false if ! can_see?(object) diff --git a/lib/locale_file_walker.rb b/lib/locale_file_walker.rb new file mode 100644 index 0000000000..4f11ea9ff8 --- /dev/null +++ b/lib/locale_file_walker.rb @@ -0,0 +1,49 @@ +require 'psych' +require 'set' + +class LocaleFileWalker + protected + + def handle_document(document) + # we want to ignore the language (first key), so let's start at -1 + handle_nodes(document.root.children, -1, []) + end + + def handle_nodes(nodes, depth, parents) + if nodes + consecutive_scalars = 0 + nodes.each do |node| + consecutive_scalars = handle_node(node, depth, parents, consecutive_scalars) + end + end + end + + def handle_node(node, depth, parents, consecutive_scalars) + node_is_scalar = node.is_a?(Psych::Nodes::Scalar) + + if node_is_scalar + handle_scalar(node, depth, parents) if valid_scalar?(depth, consecutive_scalars) + elsif node.is_a?(Psych::Nodes::Alias) + handle_alias(node, depth, parents) + elsif node.is_a?(Psych::Nodes::Mapping) + handle_mapping(node, depth, parents) + handle_nodes(node.children, depth + 1, parents.dup) + end + + node_is_scalar ? consecutive_scalars + 1 : 0 + end + + def valid_scalar?(depth, consecutive_scalars) + depth >= 0 && consecutive_scalars.even? + end + + def handle_scalar(node, depth, parents) + parents[depth] = node.value + end + + def handle_alias(node, depth, parents) + end + + def handle_mapping(node, depth, parents) + end +end diff --git a/lib/memory_diagnostics.rb b/lib/memory_diagnostics.rb index d79d84407b..a49480677a 100644 --- a/lib/memory_diagnostics.rb +++ b/lib/memory_diagnostics.rb @@ -21,7 +21,8 @@ module MemoryDiagnostics require 'objspace' diff = diff.map do |id| ObjectSpace._id2ref(id) rescue nil - end.compact! + end + diff.compact! report = "#{diff.length} objects have leaked\n" diff --git a/lib/middleware/anonymous_cache.rb b/lib/middleware/anonymous_cache.rb index a65eb2df1a..a79b422566 100644 --- a/lib/middleware/anonymous_cache.rb +++ b/lib/middleware/anonymous_cache.rb @@ -64,8 +64,13 @@ module Middleware CurrentUser.has_auth_cookie?(@env) end + def no_cache_bypass + request = Rack::Request.new(@env) + request.cookies['_bypass_cache'].nil? + end + def cacheable? - !!(!has_auth_cookie? && get?) + !!(!has_auth_cookie? && get? && no_cache_bypass) end def cached diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb index f6e2d523b5..590576567a 100644 --- a/lib/pretty_text.rb +++ b/lib/pretty_text.rb @@ -189,6 +189,8 @@ module PrettyText end end + # reset emojis (v8 context is shared amongst multisites) + context.eval("Discourse.Dialect.resetEmoji();") # custom emojis Emoji.custom.each do |emoji| context.eval("Discourse.Dialect.registerEmoji('#{emoji.name}', '#{emoji.url}');") diff --git a/lib/search.rb b/lib/search.rb index e99e603612..4c60c318fb 100644 --- a/lib/search.rb +++ b/lib/search.rb @@ -379,6 +379,8 @@ class Search end def user_search + return if SiteSetting.hide_user_profiles_from_public && !@guardian.user + users = User.includes(:user_search_data) .where("active = true AND user_search_data.search_data @@ #{ts_query("simple")}") .order("CASE WHEN username_lower = '#{@original_term.downcase}' THEN 0 ELSE 1 END") diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index ab40a807c2..8d23222512 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -7,6 +7,8 @@ end task 'db:migrate' => ['environment', 'set_locale'] do SeedFu.seed + SiteSetting.last_vacuum = Time.now.to_i if SiteSetting.last_vacuum == 0 + if SiteSetting.vacuum_db_days > 0 && SiteSetting.last_vacuum < (Time.now.to_i - SiteSetting.vacuum_db_days.days.to_i) puts "Running VACUUM FULL ANALYZE to reclaim DB space, this may take a while" diff --git a/lib/topic_query.rb b/lib/topic_query.rb index 7637bbaa7b..b02c3148e0 100644 --- a/lib/topic_query.rb +++ b/lib/topic_query.rb @@ -201,6 +201,7 @@ class TopicQuery def latest_results(options={}) result = default_results(options) + result = remove_muted_topics(result, @user) unless options && options[:state] == "muted".freeze result = remove_muted_categories(result, @user, exclude: options[:category]) result end @@ -215,6 +216,7 @@ class TopicQuery # TODO does this make sense or should it be ordered on created_at # it is ordering on bumped_at now result = TopicQuery.new_filter(default_results(options.reverse_merge(:unordered => true)), @user.treat_as_new_topic_start_date) + result = remove_muted_topics(result, @user) result = remove_muted_categories(result, @user, exclude: options[:category]) suggested_ordering(result, options) end @@ -395,6 +397,13 @@ class TopicQuery @guardian.filter_allowed_categories(result) end + def remove_muted_topics(list, user) + if user + list = list.where('COALESCE(tu.notification_level,1) > :muted', muted: TopicUser.notification_levels[:muted]) + end + + list + end def remove_muted_categories(list, user, opts=nil) category_id = get_category_id(opts[:exclude]) if opts diff --git a/lib/topics_bulk_action.rb b/lib/topics_bulk_action.rb index 337c32eac1..1a54ae9e3c 100644 --- a/lib/topics_bulk_action.rb +++ b/lib/topics_bulk_action.rb @@ -8,7 +8,7 @@ class TopicsBulkAction end def self.operations - @operations ||= %w(change_category close archive change_notification_level reset_read dismiss_posts delete) + @operations ||= %w(change_category close archive change_notification_level reset_read dismiss_posts delete unlist) end def self.register_operation(name, &block) @@ -66,6 +66,15 @@ class TopicsBulkAction end end + def unlist + topics.each do |t| + if guardian.can_moderate?(t) + t.update_status('visible', false, @user) + @changed_ids << t.id + end + end + end + def archive topics.each do |t| if guardian.can_moderate?(t) diff --git a/lib/version.rb b/lib/version.rb index 539f05bc8b..60a0859f95 100644 --- a/lib/version.rb +++ b/lib/version.rb @@ -5,7 +5,7 @@ module Discourse MAJOR = 1 MINOR = 5 TINY = 0 - PRE = 'beta3' + PRE = 'beta4' STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') end diff --git a/plugins/poll/config/locales/client.nl.yml b/plugins/poll/config/locales/client.nl.yml index d4f833833f..2f7c23c816 100644 --- a/plugins/poll/config/locales/client.nl.yml +++ b/plugins/poll/config/locales/client.nl.yml @@ -17,6 +17,12 @@ nl: average_rating: "Gemiddeld cijfer: %{average}." multiple: help: + at_least_min_options: + one: "U dient tenminste 1 optie te kiezen." + other: "U dient tenminste %{count} opties te kiezen." + up_to_max_options: + one: "U kunt maximaal 1 optie kiezen." + other: "U kunt maximaal %{count} opties kiezen." between_min_and_max_options: "Je kan tussen %{min} en %{max} opties kiezen." cast-votes: title: "Geef je stem" diff --git a/plugins/poll/config/locales/client.pl_PL.yml b/plugins/poll/config/locales/client.pl_PL.yml index 262a6bfa90..cd2cc46375 100644 --- a/plugins/poll/config/locales/client.pl_PL.yml +++ b/plugins/poll/config/locales/client.pl_PL.yml @@ -19,6 +19,18 @@ pl_PL: average_rating: "Średnia ocena: %{average}." multiple: help: + at_least_min_options: + one: "Musisz wybrać przynajmniej jedną pozycje." + few: "Musisz wybrać co najmniej %{count} pozycje." + other: "Musisz wybrać co najmniej %{count} pozycje." + up_to_max_options: + one: "Możesz wybrać maksymalnie 1 opcję." + few: "Możesz wybrać maksymalnie %{count} opcje." + other: "Możesz wybrać maksymalnie %{count} opcji." + x_options: + one: "Musisz wybrać jedną opcję." + few: "Musisz wybrać %{count} opcje." + other: "Musisz wybrać %{count} opcji." between_min_and_max_options: "Możesz wybrać pomiędzy %{min} a %{max} pozycjami." cast-votes: title: "Oddaj głos" diff --git a/plugins/poll/config/locales/client.tr_TR.yml b/plugins/poll/config/locales/client.tr_TR.yml index 5074053397..4b9e75273e 100644 --- a/plugins/poll/config/locales/client.tr_TR.yml +++ b/plugins/poll/config/locales/client.tr_TR.yml @@ -15,6 +15,12 @@ tr_TR: average_rating: "Ortalama oran: %{average}." multiple: help: + at_least_min_options: + other: "En az %{count} seçim yapmalısınız." + up_to_max_options: + other: "En fazla %{count} seçim yapabilirsiniz." + x_options: + other: "%{count} seçim yapmalısınız." between_min_and_max_options: "%{min} ve %{max} seçenekleri arasında seçim yapabilirsiniz." cast-votes: title: "Oyunuzu kullanın" diff --git a/plugins/poll/config/locales/server.da.yml b/plugins/poll/config/locales/server.da.yml index 1e32f4ef13..0ad4aa946a 100644 --- a/plugins/poll/config/locales/server.da.yml +++ b/plugins/poll/config/locales/server.da.yml @@ -35,3 +35,5 @@ da: poll_must_be_open_to_vote: "Afstemning skal være åben for at kunne stemme." topic_must_be_open_to_toggle_status: "Emnet skal være åbent for at ændre status." only_staff_or_op_can_toggle_status: "Kun personalet eller emnets opretter kan ændre status for en afstemning" + email: + link_to_poll: "Klik for at se afstemningen." diff --git a/plugins/poll/config/locales/server.de.yml b/plugins/poll/config/locales/server.de.yml index ade4a865a7..e1672ac3d2 100644 --- a/plugins/poll/config/locales/server.de.yml +++ b/plugins/poll/config/locales/server.de.yml @@ -35,3 +35,5 @@ de: poll_must_be_open_to_vote: "Die Umfrage muss zum Abstimmen gestartet sein." topic_must_be_open_to_toggle_status: "Damit du den Status ändern kannst, muss das Thema geöffnet sein." only_staff_or_op_can_toggle_status: "Nur Mitarbeiter und der Autor des Beitrags können den Status der Umfrage ändern." + email: + link_to_poll: "Klicke hier, um die Umfrage zu sehen." diff --git a/plugins/poll/config/locales/server.en.yml b/plugins/poll/config/locales/server.en.yml index 9417c9ba08..1ef088e0e4 100644 --- a/plugins/poll/config/locales/server.en.yml +++ b/plugins/poll/config/locales/server.en.yml @@ -55,3 +55,6 @@ en: topic_must_be_open_to_toggle_status: "The topic must be open to toggle status." only_staff_or_op_can_toggle_status: "Only a staff member or the original poster can toggle a poll status." + + email: + link_to_poll: "Click to view the poll." diff --git a/plugins/poll/config/locales/server.es.yml b/plugins/poll/config/locales/server.es.yml index 990dde322d..1792d5cf91 100644 --- a/plugins/poll/config/locales/server.es.yml +++ b/plugins/poll/config/locales/server.es.yml @@ -35,3 +35,5 @@ es: poll_must_be_open_to_vote: "La encuesta debe estar abierta para votar." topic_must_be_open_to_toggle_status: "Este tema debe estar abierto para cambiar entre estados." only_staff_or_op_can_toggle_status: "Solo un moderador, administrador o el autor original del post puede cambiar el estado de una encuesta." + email: + link_to_poll: "Haz clic para ver la encuesta." diff --git a/plugins/poll/config/locales/server.fi.yml b/plugins/poll/config/locales/server.fi.yml index 7abf82d557..775e250db2 100644 --- a/plugins/poll/config/locales/server.fi.yml +++ b/plugins/poll/config/locales/server.fi.yml @@ -35,3 +35,5 @@ fi: poll_must_be_open_to_vote: "Vain avoimessa kyselyssä voi äänestää." topic_must_be_open_to_toggle_status: "Vain avoimessa ketjussa voi muuttaa äänestyksen tilaa." only_staff_or_op_can_toggle_status: "Vain henkilökunta tai kyselyn laatija voi muuttaa äänestyksen tilaa." + email: + link_to_poll: "Siirry äänestykseen klikkaamalla tästä" diff --git a/plugins/poll/config/locales/server.nl.yml b/plugins/poll/config/locales/server.nl.yml index 13865efdac..7218cfbd7d 100644 --- a/plugins/poll/config/locales/server.nl.yml +++ b/plugins/poll/config/locales/server.nl.yml @@ -14,6 +14,12 @@ nl: multiple_polls_with_same_name: "Er zijn meerdere polls met dezelfde naam : %{name}. Gebruik het 'naam' attribuut om je polls te identificeren." default_poll_must_have_at_least_2_options: "De poll moet minimaal 2 opties hebben." named_poll_must_have_at_least_2_options: "De poll genaamd %{name} moet minimaal 2 opties hebben." + default_poll_must_have_less_options: + one: "Poll dient minder dan 1 optie te hebben." + other: "Poll dient minder dan %{count} opties te hebben." + named_poll_must_have_less_options: + one: "De poll genaamd %{name} moet minder dan 1 optie hebben." + other: "De poll genaamd %{name} moet minder dan %{count} opties hebben." default_poll_must_have_different_options: "Polls moeten verschillende opties hebben." named_poll_must_have_different_options: "De poll genaamd %{name} moet verschillende opties hebben." default_poll_with_multiple_choices_has_invalid_parameters: "De poll met meerdere keuzes heeft ongeldige parameters." diff --git a/plugins/poll/config/locales/server.pl_PL.yml b/plugins/poll/config/locales/server.pl_PL.yml index 0247edf163..0f2b9a368b 100644 --- a/plugins/poll/config/locales/server.pl_PL.yml +++ b/plugins/poll/config/locales/server.pl_PL.yml @@ -14,10 +14,18 @@ pl_PL: multiple_polls_with_same_name: "Istnieje kilka ankiet o tej samej nazwie: %{name}. Użyj atrybutu 'name', aby umożliwić ich jednoznaczną identyfikację." default_poll_must_have_at_least_2_options: "Ankieta musi posiadać co najmniej 2 opcje." named_poll_must_have_at_least_2_options: "Ankieta %{name} musi posiadać co najmniej 2 opcje do wyboru." + default_poll_must_have_less_options: + one: "Ankieta musi posiadać mniej niż 1 opcję do wyboru." + few: "Ankieta musi posiadać co najmniej %{count} pozycje." + other: "Ankieta musi posiadać co najmniej %{count} pozycji." + named_poll_must_have_less_options: + one: "Ankieta %{name} musi posiadać mniej niż 1 opcję." + few: "Ankieta %{name} musi posiadać mniej niż %{count} opcje." + other: "Ankieta %{name} musi posiadać mniej niż %{count} opcji." default_poll_must_have_different_options: "Ankieta musi posiadać kilka różnych opcji do wyboru." named_poll_must_have_different_options: "Ankieta %{name} musi posiadać kilka różnych opcji do wyboru." - default_poll_with_multiple_choices_has_invalid_parameters: "Sonda wielokrotnego wyboru posiada nieprawidłowe parametry." - named_poll_with_multiple_choices_has_invalid_parameters: "Sonda wielokrotnego wyboru o nazwie %{name} posiada nieprawidłowe parametry." + default_poll_with_multiple_choices_has_invalid_parameters: "Ankieta wielokrotnego wyboru posiada nieprawidłowe parametry." + named_poll_with_multiple_choices_has_invalid_parameters: "Ankieta wielokrotnego wyboru o nazwie %{name} posiada nieprawidłowe parametry." requires_at_least_1_valid_option: "Musisz wybrać co najmniej 1 poprawną opcje." cannot_change_polls_after_5_minutes: "Po upływie 5 minut ankiety nie mogą być zmieniane." op_cannot_edit_options_after_5_minutes: "Po upływie 5 minut nie można dodawać lub usuwać opcji wyboru w ankietach. Skontaktuj się z moderatorem jeśli naprawdę musisz zmienić opcję w tej ankiecie." @@ -29,3 +37,5 @@ pl_PL: poll_must_be_open_to_vote: "Głosowanie jest możliwe tylko w otwartych ankietach." topic_must_be_open_to_toggle_status: "Zmiana statusu jest możliwa jedynie w otwartych tematach." only_staff_or_op_can_toggle_status: "Status może być zmieniony przez autora wpisu lub członka załogi serwisu." + email: + link_to_poll: "Kliknij, aby zobaczyć ankietę." diff --git a/plugins/poll/config/locales/server.pt.yml b/plugins/poll/config/locales/server.pt.yml index 24704a455b..6a8c13a7e5 100644 --- a/plugins/poll/config/locales/server.pt.yml +++ b/plugins/poll/config/locales/server.pt.yml @@ -35,3 +35,5 @@ pt: poll_must_be_open_to_vote: "Votação tem que estar aberta para votar." topic_must_be_open_to_toggle_status: "O tópico tem que estar aberto para alternar o estado." only_staff_or_op_can_toggle_status: "Apenas um membro do pessoal ou o autor original pode alternar o estado da votação." + email: + link_to_poll: "Clique para ver a votação." diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb index cb0aa1874f..aec1340286 100644 --- a/plugins/poll/plugin.rb +++ b/plugins/poll/plugin.rb @@ -22,9 +22,17 @@ DEFAULT_POLL_NAME ||= "poll".freeze after_initialize do - # remove "Vote Now!" & "Show Results" links in emails - Email::Styles.register_plugin_style do |fragment| - fragment.css(".poll a.cast-votes, .poll a.toggle-results").each(&:remove) + # turn polls into a link in emails + Email::Styles.register_plugin_style do |fragment, opts| + post = Post.find_by(id: opts[:post_id]) rescue nil + if post.nil? || post.trashed? + fragment.css(".poll").each(&:remove) + else + post_url = "#{Discourse.base_url}#{post.url}" + fragment.css(".poll").each do |poll| + poll.replace "

    #{I18n.t("poll.email.link_to_poll")}

    " + end + end end module ::DiscoursePoll diff --git a/script/import_scripts/base.rb b/script/import_scripts/base.rb index 49b86caccb..ea98e73cb0 100644 --- a/script/import_scripts/base.rb +++ b/script/import_scripts/base.rb @@ -199,7 +199,7 @@ class ImportScripts::Base Post.exec_sql('create temp table import_ids(val varchar(200) primary key)') - import_id_clause = import_ids.map{|id| "('#{PG::Connection.escape_string(id)}')"}.join(",") + import_id_clause = import_ids.map{|id| "('#{PG::Connection.escape_string(id.to_s)}')"}.join(",") Post.exec_sql("insert into import_ids values #{import_id_clause}") existing = "#{type.to_s.classify}CustomField".constantize.where(name: 'import_id') @@ -246,7 +246,7 @@ class ImportScripts::Base failed += 1 puts "Failed to create user id: #{import_id}, username: #{new_user.username}, email: #{new_user.email}" puts "user errors: #{new_user.errors.full_messages}" - puts "user_profile errors: #{new_user.user_profiler.errors.full_messages}" + puts "user_profile errors: #{new_user.user_profile.errors.full_messages}" if new_user.user_profile.present? && new_user.user_profile.errors.present? end else failed += 1 @@ -273,6 +273,10 @@ class ImportScripts::Base location = opts.delete(:location) avatar_url = opts.delete(:avatar_url) + # Allow the || operations to work with empty strings '' + opts[:name] = nil if opts[:name].blank? + opts[:username] = nil if opts[:username].blank? + opts[:name] = User.suggest_name(opts[:email]) unless opts[:name] if opts[:username].blank? || opts[:username].length < User.username_length.begin || @@ -317,7 +321,7 @@ class ImportScripts::Base u = existing end else - puts "Error on record: #{opts}" + puts "Error on record: #{opts.inspect}" raise e end end diff --git a/script/import_scripts/jive.rb b/script/import_scripts/jive.rb new file mode 100644 index 0000000000..bb5cedd854 --- /dev/null +++ b/script/import_scripts/jive.rb @@ -0,0 +1,346 @@ +# Jive importer +require 'nokogiri' +require 'csv' +require File.expand_path(File.dirname(__FILE__) + "/base.rb") + +class ImportScripts::Jive < ImportScripts::Base + + BATCH_SIZE = 1000 + CATEGORY_IDS = [2023,2003,2004,2042,2036,2029] # categories that should be skipped + + def initialize(path) + @path = path + super() + @bbcode_to_md = true + + puts "loading post mappings..." + @post_number_map = {} + Post.pluck(:id, :post_number).each do |post_id, post_number| + @post_number_map[post_id] = post_number + end + end + + def created_post(post) + @post_number_map[post.id] = post.post_number + super + end + + def execute + import_users + import_groups + import_group_members + import_categories + import_posts + + # Topic.update_all(closed: true) + end + + class RowResolver + def load(row) + @row = row + end + + def self.create(cols) + Class.new(RowResolver).new(cols) + end + + def initialize(cols) + cols.each_with_index do |col,idx| + self.class.send(:define_method, col) do + @row[idx] + end + end + end + end + + def load_user_batch!(users, offset, total) + if users.length > 0 + create_users(users, offset: offset, total: total) do |user| + user + end + users.clear + end + end + + def csv_parse(name) + filename = "#{@path}/#{name}.csv" + first = true + row = nil + + current_row = ""; + double_quote_count = 0 + + File.open(filename).each_line do |line| + + line.gsub!(/\\(.{1})/){|m| m[-1] == '"'? '""': m[-1]} + line.strip! + + current_row << "\n" unless current_row.empty? + current_row << line + + double_quote_count += line.scan('"').count + + if double_quote_count % 2 == 1 + next + end + + raw = begin + CSV.parse(current_row) + rescue CSV::MalformedCSVError => e + puts e.message + puts "*" * 100 + puts "Bad row skipped, line is: #{line}" + puts + puts current_row + puts + puts "double quote count is : #{double_quote_count}" + puts "*" * 100 + + current_row = "" + double_quote_count = 0 + next + end[0] + + if first + row = RowResolver.create(raw) + + current_row = "" + double_quote_count = 0 + first = false + next + end + + row.load(raw) + + yield row + + current_row = "" + double_quote_count = 0 + end + end + + def total_rows(table) + File.foreach("#{@path}/#{table}.csv").inject(0) {|c, line| c+1} - 1 + end + + def import_groups + puts "", "importing groups..." + + rows = [] + csv_parse("group") do |row| + rows << {id: row.groupid, name: row.name} + end + + create_groups(rows) do |row| + row + end + end + + def import_users + puts "", "creating users" + + count = 0 + users = [] + + total = total_rows("user") + + csv_parse("user") do |row| + + id = row.userid + + # append "-x" at the end of each email + email = "#{row.email}-x" + + # fake it + if row.email.blank? || row.email !~ /@/ + email = SecureRandom.hex << "@domain.com" + end + + name = "#{row.firstname} #{row.lastname}" + username = row.username + created_at = DateTime.parse(row.creationdate) + last_seen_at = DateTime.parse(row.lastloggedin) + is_activated = row.userenabled + + username = name if username == "NULL" + username = email.split("@")[0] if username.blank? + name = email.split("@")[0] if name.blank? + + users << { + id: id, + email: email, + name: name, + username: username, + created_at: created_at, + last_seen_at: last_seen_at, + active: is_activated.to_i == 1, + approved: is_activated.to_i == 1 + } + + count += 1 + if count % BATCH_SIZE == 0 + load_user_batch! users, count - users.length, total + end + + end + + load_user_batch! users, count, total + end + + def import_group_members + puts "", "importing group members..." + + csv_parse("group_members") do |row| + user_id = user_id_from_imported_user_id(row.userid) + group_id = group_id_from_imported_group_id(row.groupid) + + if user_id && group_id + GroupUser.find_or_create_by(user_id: user_id, group_id: group_id) + end + end + end + + def import_categories + rows = [] + + csv_parse("community") do |row| + next unless CATEGORY_IDS.include?(row.communityid.to_i) + rows << {id: row.communityid, name: "#{row.name} (#{row.communityid})"} + end + + create_categories(rows) do |row| + row + end + end + + def normalize_raw!(raw) + raw = raw.dup + raw = raw[5..-6] + + doc = Nokogiri::HTML.fragment(raw) + doc.css('img').each do |img| + img.remove if img['class'] == "jive-image" + end + + raw = doc.to_html + raw = raw[4..-1] + + raw + end + + def import_post_batch!(posts, topics, offset, total) + create_posts(posts, total: total, offset: offset) do |post| + + mapped = {} + + mapped[:id] = post[:id] + mapped[:user_id] = user_id_from_imported_user_id(post[:user_id]) || -1 + mapped[:raw] = post[:body] + mapped[:created_at] = post[:created_at] + + topic = topics[post[:topic_id]] + + unless topic + p "MISSING TOPIC #{post[:topic_id]}" + p post + next + end + + unless topic[:post_id] + mapped[:category] = category_id_from_imported_category_id(topic[:category_id]) + mapped[:title] = post[:title] + topic[:post_id] = post[:id] + else + parent = topic_lookup_from_imported_post_id(topic[:post_id]) + next unless parent + + mapped[:topic_id] = parent[:topic_id] + + reply_to_post_id = post_id_from_imported_post_id(post[:reply_id]) + if reply_to_post_id + reply_to_post_number = @post_number_map[reply_to_post_id] + if reply_to_post_number && reply_to_post_number > 1 + mapped[:reply_to_post_number] = reply_to_post_number + end + end + end + + next if topic[:deleted] or post[:deleted] + + mapped + end + + posts.clear + end + + def import_posts + puts "", "creating topics and posts" + + topic_map = {} + thread_map = {} + + csv_parse("message") do |thread| + + next unless CATEGORY_IDS.include?(thread.containerid.to_i) + + if !thread.parentmessageid + # topic + + thread_map[thread.threadid] = thread.messageid + + topic_map[thread.messageid] = { + id: thread.messageid, + topic_id: thread.messageid, + category_id: thread.containerid, + user_id: thread.userid, + title: thread.subject, + body: normalize_raw!(thread.body || thread.subject || ""), + created_at: DateTime.parse(thread.creationdate), + } + + end + end + + total = total_rows("message") + posts = [] + count = 0 + + topic_map.each do |_, topic| + posts << topic if topic[:body] + count+=1 + end + + csv_parse("message") do |thread| + # post + + next unless CATEGORY_IDS.include?(thread.containerid.to_i) + + if thread.parentmessageid + row = { + id: thread.messageid, + topic_id: thread_map["#{thread.threadid}"], + user_id: thread.userid, + title: thread.subject, + body: normalize_raw!(thread.body), + created_at: DateTime.parse(thread.creationdate) + } + posts << row + count+=1 + + if posts.length > 0 && posts.length % BATCH_SIZE == 0 + import_post_batch!(posts, topic_map, count - posts.length, total) + end + end + end + + import_post_batch!(posts, topic_map, count - posts.length, total) if posts.length > 0 + end + +end + +unless ARGV[0] && Dir.exist?(ARGV[0]) + puts "", "Usage:", "", "bundle exec ruby script/import_scripts/jive.rb DIRNAME", "" + exit 1 +end + +ImportScripts::Jive.new(ARGV[0]).perform diff --git a/script/import_scripts/mbox.rb b/script/import_scripts/mbox.rb index d47b5553fc..a7773f0a56 100755 --- a/script/import_scripts/mbox.rb +++ b/script/import_scripts/mbox.rb @@ -37,6 +37,7 @@ class ImportScripts::Mbox < ImportScripts::Base topics = [] topic_lookup = {} + topic_titles = {} replies = [] all_messages do |mail, filename| @@ -44,21 +45,63 @@ class ImportScripts::Mbox < ImportScripts::Base msg_id = mail['Message-ID'].to_s reply_to = mail['In-Reply-To'].to_s + title = clean_title(mail['Subject'].to_s) + date = Time.parse(mail['date'].to_s).to_i if reply_to.present? topic = topic_lookup[reply_to] || reply_to topic_lookup[msg_id] = topic - replies << {id: msg_id, topic: topic, file: filename} + replies << {id: msg_id, topic: topic, file: filename, title: title, date: date} else - topics << {id: msg_id, file: filename} + topics << {id: msg_id, file: filename, title: title, date: date} + topic_titles[title] ||= msg_id end end + replies.sort! {|a, b| a[:date] <=> b[:date]} + topics.sort! {|a, b| a[:date] <=> b[:date]} + + # Replies without parents should be hoisted to topics + to_hoist = [] + replies.each do |r| + to_hoist << r if !topic_lookup[r[:topic]] + end + + to_hoist.each do |h| + replies.delete(h) + topics << {id: h[:id], file: h[:file], title: h[:title], date: h[:date]} + topic_titles[h[:title]] ||= h[:id] + end + + # Topics with duplicate replies should be replies + to_group = [] + topics.each do |t| + first = topic_titles[t[:title]] + to_group << t if first && first != t[:id] + end + + to_group.each do |t| + topics.delete(t) + replies << {id: t[:id], topic: topic_titles[t[:title]], file: t[:file], title: t[:title], date: t[:date]} + end + + replies.sort! {|a, b| a[:date] <=> b[:date]} + topics.sort! {|a, b| a[:date] <=> b[:date]} + + File.write(USER_INDEX_PATH, {users: users}.to_json) File.write(TOPIC_INDEX_PATH, {topics: topics}.to_json) File.write(REPLY_INDEX_PATH, {replies: replies}.to_json) end + def clean_title(title) + title.gsub(/^Re: */i, '') + end + + def clean_raw(raw) + raw.gsub(/-- \nYou received this message because you are subscribed to the Google Groups "[^"]*" group.\nTo unsubscribe from this group and stop receiving emails from it, send an email to [^+@]+\+unsubscribe@googlegroups.com\.\nFor more options, visit https:\/\/groups\.google\.com\/groups\/opt_out\./, '') + end + def import_users puts "", "importing users" @@ -100,7 +143,7 @@ class ImportScripts::Mbox < ImportScripts::Base topics = all_topics[offset..offset+BATCH_SIZE-1] break if topics.nil? - next if all_records_exist? :posts, topics.map {|t| t['id'].to_i} + next if all_records_exist? :posts, topics.map {|t| t['id']} create_posts(topics, total: topic_count, offset: offset) do |t| raw_email = File.read(t['file']) @@ -116,11 +159,11 @@ class ImportScripts::Mbox < ImportScripts::Base title = mail.subject.gsub(/\[[^\]]+\]+/, '').strip { id: t['id'], - title: title, + title: clean_title(title), user_id: user_id_from_imported_user_id(mail.from.first) || Discourse::SYSTEM_USER_ID, created_at: mail.date, category: CATEGORY_ID, - raw: raw, + raw: clean_raw(raw), cook_method: Post.cook_methods[:email] } end end @@ -129,9 +172,6 @@ class ImportScripts::Mbox < ImportScripts::Base def import_replies puts "", "creating topic replies" - all_topics = ::JSON.parse(File.read(TOPIC_INDEX_PATH))['topics'] - topic_count = all_topics.size - replies = ::JSON.parse(File.read(REPLY_INDEX_PATH))['replies'] post_count = replies.size @@ -139,7 +179,7 @@ class ImportScripts::Mbox < ImportScripts::Base posts = replies[offset..offset+BATCH_SIZE-1] break if posts.nil? - next if all_records_exist? :posts, posts.map {|p| p['id'].to_i} + next if all_records_exist? :posts, posts.map {|p| p['id']} create_posts(posts, total: post_count, offset: offset) do |p| parent_id = p['topic'] @@ -161,7 +201,7 @@ class ImportScripts::Mbox < ImportScripts::Base topic_id: topic_id, user_id: user_id_from_imported_user_id(mail.from.first) || Discourse::SYSTEM_USER_ID, created_at: mail.date, - raw: raw, + raw: clean_raw(raw), cook_method: Post.cook_methods[:email] } end end diff --git a/script/import_scripts/vbulletin.rb b/script/import_scripts/vbulletin.rb index 22e5883db3..588e1ddff1 100644 --- a/script/import_scripts/vbulletin.rb +++ b/script/import_scripts/vbulletin.rb @@ -210,7 +210,7 @@ class ImportScripts::VBulletin < ImportScripts::Base SQL break if topics.size < 1 - next if all_records_exist? :posts, topics.map {|t| "thread-#{topic["threadid"]}" } + next if all_records_exist? :posts, topics.map {|t| "thread-#{t["threadid"]}" } create_posts(topics, total: topic_count, offset: offset) do |topic| raw = preprocess_post_raw(topic["raw"]) rescue nil @@ -555,7 +555,7 @@ class ImportScripts::VBulletin < ImportScripts::Base end def mysql_query(sql) - @client.query(sql, cache_rows: false) + @client.query(sql, cache_rows: true) end end diff --git a/script/pull_translations.rb b/script/pull_translations.rb index 98da5ad419..231482fcb2 100644 --- a/script/pull_translations.rb +++ b/script/pull_translations.rb @@ -6,6 +6,7 @@ # team will pull them in. require 'open3' +require_relative '../lib/locale_file_walker' if `which tx`.strip.empty? puts '', 'The Transifex client needs to be installed to use this script.' @@ -17,10 +18,11 @@ if `which tx`.strip.empty? exit 1 end -locales = Dir.glob(File.expand_path('../../config/locales/client.*.yml', __FILE__)).map {|x| x.split('.')[-2]}.select {|x| x != 'en'}.sort.join(',') +languages = Dir.glob(File.expand_path('../../config/locales/client.*.yml', __FILE__)) + .map { |x| x.split('.')[-2] }.select { |x| x != 'en' }.sort puts 'Pulling new translations...', '' -command = "tx pull --mode=developer --language=#{locales} #{ARGV.include?('force') ? '-f' : ''}" +command = "tx pull --mode=developer --language=#{languages.join(',')} #{ARGV.include?('force') ? '-f' : ''}" Open3.popen2e(command) do |stdin, stdout_err, wait_thr| while (line = stdout_err.gets) @@ -46,19 +48,180 @@ END YML_DIRS = ['config/locales', 'plugins/poll/config/locales', 'vendor/gems/discourse_imgur/lib/discourse_imgur/locale'] +YML_FILE_PREFIXES = ['server', 'client'] -# Add comments to the top of files -['client', 'server'].each do |base| - YML_DIRS.each do |dir| - Dir.glob(File.expand_path("../../#{dir}/#{base}.*.yml", __FILE__)).each do |file_name| - language = File.basename(file_name).match(Regexp.new("#{base}\\.([^\\.]*)\\.yml"))[1] +def yml_path(dir, prefix, language) + path = "../../#{dir}/#{prefix}.#{language}.yml" + path = File.expand_path(path, __FILE__) + File.exists?(path) ? path : nil +end - lines = File.readlines(file_name) - lines.collect! {|line| line =~ /^[a-z_]+:$/i ? "#{language}:" : line} +# Add comments to the top of files and replace the language (first key in YAML file) +def update_file_header(filename, language) + lines = File.readlines(filename) + lines.collect! {|line| line =~ /^[a-z_]+:$/i ? "#{language}:" : line} - File.open(file_name, 'w+') do |f| - f.puts(YML_FILE_COMMENTS, '') unless lines[0][0] == '#' - f.puts(lines) + File.open(filename, 'w+') do |f| + f.puts(YML_FILE_COMMENTS, '') unless lines[0][0] == '#' + f.puts(lines) + end +end + +class YamlAliasFinder < LocaleFileWalker + def initialize + @anchors = {} + @aliases = Hash.new { |hash, key| hash[key] = [] } + end + + def parse_file(filename) + document = Psych.parse_file(filename) + handle_document(document) + {anchors: @anchors, aliases: @aliases} + end + + private + + def handle_alias(node, depth, parents) + @aliases[node.anchor] << parents.dup + end + + def handle_mapping(node, depth, parents) + if node.anchor + @anchors[parents.dup] = node.anchor + end + end +end + +class YamlAliasSynchronizer < LocaleFileWalker + def initialize(original_alias_data) + @anchors = original_alias_data[:anchors] + @aliases = original_alias_data[:aliases] + @used_anchors = Set.new + + calculate_required_keys + end + + def add_to(filename) + stream = Psych.parse_stream(File.read(filename)) + stream.children.each { |document| handle_document(document) } + + add_aliases + write_yaml(stream, filename) + end + + private + + def calculate_required_keys + @required_keys = {} + + @aliases.each_value do |key_sets| + key_sets.each do |keys| + until keys.empty? + add_needed_node(keys) + keys = keys.dup + keys.pop + end + end + end + + add_needed_node([]) unless @required_keys.empty? + end + + def add_needed_node(keys) + @required_keys[keys] = {mapping: nil, scalar: nil, alias: nil} + end + + def write_yaml(stream, filename) + yaml = stream.to_yaml(nil, {:line_width => -1}) + + File.open(filename, 'w') do |file| + file.write(yaml) + end + end + + def handle_scalar(node, depth, parents) + super(node, depth, parents) + + if @required_keys.has_key?(parents) + @required_keys[parents][:scalar] = node + end + end + + def handle_alias(node, depth, parents) + if @required_keys.has_key?(parents) + @required_keys[parents][:alias] = node + end + end + + def handle_mapping(node, depth, parents) + if @anchors.has_key?(parents) + node.anchor = @anchors[parents] + @used_anchors.add(node.anchor) + end + + if @required_keys.has_key?(parents) + @required_keys[parents][:mapping] = node + end + end + + def add_aliases + @used_anchors.each do |anchor| + @aliases[anchor].each do |keys| + parents = [] + parent_node = @required_keys[[]] + + keys.each_with_index do |key, index| + parents << key + current_node = @required_keys[parents] + is_last = index == keys.size - 1 + add_node(current_node, parent_node, key, is_last ? anchor : nil) + parent_node = current_node + end + end + end + end + + def add_node(node, parent_node, scalar_name, anchor) + parent_mapping = parent_node[:mapping] + parent_mapping.children ||= [] + + if node[:scalar].nil? + node[:scalar] = Psych::Nodes::Scalar.new(scalar_name) + parent_mapping.children << node[:scalar] + end + + if anchor.nil? + if node[:mapping].nil? + node[:mapping] = Psych::Nodes::Mapping.new + parent_mapping.children << node[:mapping] + end + elsif node[:alias].nil? + parent_mapping.children << Psych::Nodes::Alias.new(anchor) + end + end +end + +def get_english_alias_data(dir, prefix) + filename = yml_path(dir, prefix, 'en') + filename ? YamlAliasFinder.new.parse_file(filename) : nil +end + +def add_anchors_and_aliases(english_alias_data, filename) + if english_alias_data + YamlAliasSynchronizer.new(english_alias_data).add_to(filename) + end +end + +YML_DIRS.each do |dir| + YML_FILE_PREFIXES.each do |prefix| + english_alias_data = get_english_alias_data(dir, prefix) + + languages.each do |language| + filename = yml_path(dir, prefix, language) + + if filename + add_anchors_and_aliases(english_alias_data, filename) + update_file_header(filename, language) end end end diff --git a/spec/components/email/sender_spec.rb b/spec/components/email/sender_spec.rb index 55f56e4c35..06ed0bb65b 100644 --- a/spec/components/email/sender_spec.rb +++ b/spec/components/email/sender_spec.rb @@ -66,11 +66,14 @@ describe Email::Sender do context "adds a List-ID header to identify the forum" do before do - message.header['X-Discourse-Topic-Id'] = 5577 + category = Fabricate(:category, name: 'Name With Space') + topic = Fabricate(:topic, category_id: category.id) + message.header['X-Discourse-Topic-Id'] = topic.id end When { email_sender.send } Then { expect(message.header['List-ID']).to be_present } + Then { expect(message.header['List-ID'].to_s).to match('name-with-space') } end context "adds a Message-ID header even when topic id is not present" do diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb index 92318aada5..5d12ef0f19 100644 --- a/spec/components/guardian_spec.rb +++ b/spec/components/guardian_spec.rb @@ -316,12 +316,6 @@ describe Guardian do expect(Guardian.new(coding_horror).can_invite_to?(topic)).to be_falsey end - it 'returns false when local logins are disabled' do - SiteSetting.stubs(:enable_local_logins).returns(false) - expect(Guardian.new(moderator).can_invite_to?(topic)).to be_falsey - expect(Guardian.new(user).can_invite_to?(topic)).to be_falsey - end - it 'returns false for normal user on private topic' do expect(Guardian.new(user).can_invite_to?(private_topic)).to be_falsey end diff --git a/spec/components/search_spec.rb b/spec/components/search_spec.rb index 462b119112..093aeb766f 100644 --- a/spec/components/search_spec.rb +++ b/spec/components/search_spec.rb @@ -85,6 +85,21 @@ describe Search do expect(result.users.length).to eq(1) expect(result.users[0].id).to eq(user.id) end + + context 'hiding user profiles' do + before { SiteSetting.stubs(:hide_user_profiles_from_public).returns(true) } + + it 'returns no result for anon' do + expect(result.users.length).to eq(0) + end + + it 'returns a result for logged in users' do + result = Search.execute('bruce', type_filter: 'user', guardian: Guardian.new(user)) + expect(result.users.length).to eq(1) + end + + end + end context 'inactive users' do @@ -119,7 +134,6 @@ describe Search do TopicAllowedUser.create!(user_id: reply.user_id, topic_id: topic.id) TopicAllowedUser.create!(user_id: post.user_id, topic_id: topic.id) - results = Search.execute('mars', type_filter: 'private_messages', guardian: Guardian.new(reply.user)) diff --git a/spec/components/topic_query_spec.rb b/spec/components/topic_query_spec.rb index c06c6623b5..bb99bc35b8 100644 --- a/spec/components/topic_query_spec.rb +++ b/spec/components/topic_query_spec.rb @@ -374,6 +374,7 @@ describe TopicQuery do it "returns an empty set" do expect(topics).to be_blank + expect(topic_query.list_latest.topics).to be_blank end context 'un-muted' do @@ -383,6 +384,7 @@ describe TopicQuery do it "returns the topic again" do expect(topics).to eq([new_topic]) + expect(topic_query.list_latest.topics).not_to be_blank end end end diff --git a/spec/components/topics_bulk_action_spec.rb b/spec/components/topics_bulk_action_spec.rb index 2a3396d2dc..24dc4310ba 100644 --- a/spec/components/topics_bulk_action_spec.rb +++ b/spec/components/topics_bulk_action_spec.rb @@ -153,4 +153,31 @@ describe TopicsBulkAction do end end end + + describe "unlist" do + let(:topic) { Fabricate(:topic) } + + context "when the user can moderate the topic" do + it "unlists the topic and returns the topic_id" do + Guardian.any_instance.expects(:can_moderate?).returns(true) + Guardian.any_instance.expects(:can_create?).returns(true) + tba = TopicsBulkAction.new(topic.user, [topic.id], type: 'unlist') + topic_ids = tba.perform! + expect(topic_ids).to eq([topic.id]) + topic.reload + expect(topic).not_to be_visible + end + end + + context "when the user can't edit the topic" do + it "doesn't unlist the topic" do + Guardian.any_instance.expects(:can_moderate?).returns(false) + tba = TopicsBulkAction.new(topic.user, [topic.id], type: 'unlist') + topic_ids = tba.perform! + expect(topic_ids).to be_blank + topic.reload + expect(topic).to be_visible + end + end + end end diff --git a/spec/controllers/admin/email_controller_spec.rb b/spec/controllers/admin/email_controller_spec.rb index 2820cb1543..68b0ee5319 100644 --- a/spec/controllers/admin/email_controller_spec.rb +++ b/spec/controllers/admin/email_controller_spec.rb @@ -66,7 +66,7 @@ describe Admin::EmailController do end it "previews the digest" do - xhr :get, :preview_digest, last_seen_at: 1.week.ago + xhr :get, :preview_digest, last_seen_at: 1.week.ago, username: user.username expect(response).to be_success end end diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb index 75bc9ddac1..e7c2233ec1 100644 --- a/spec/controllers/admin/groups_controller_spec.rb +++ b/spec/controllers/admin/groups_controller_spec.rb @@ -36,6 +36,26 @@ describe Admin::GroupsController do end + context ".bulk" do + it "can assign users to a group by email or username" do + group = Fabricate(:group, name: "test", primary_group: true, title: 'WAT') + user = Fabricate(:user) + user2 = Fabricate(:user) + + xhr :put, :bulk_perform, group_id: group.id, users: [user.username.upcase, user2.email, 'doesnt_exist'] + + expect(response).to be_success + + user.reload + expect(user.primary_group).to eq(group) + expect(user.title).to eq("WAT") + + user2.reload + expect(user2.primary_group).to eq(group) + + end + end + context ".create" do it "strip spaces on the group name" do diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 4f93fe55a5..20d5d198df 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -37,7 +37,6 @@ describe Admin::UsersController do expect(UserHistory.where(action: UserHistory.actions[:check_email], acting_user_id: @user.id).count).to eq(0) xhr :get, :index, show_emails: "true" - data = ::JSON.parse(response.body) expect(UserHistory.where(action: UserHistory.actions[:check_email], acting_user_id: @user.id).count).to eq(1) end @@ -173,6 +172,22 @@ describe Admin::UsersController do end end + context '.add_group' do + let(:user) { Fabricate(:user) } + let(:group) { Fabricate(:group) } + + it 'adds the user to the group' do + xhr :post, :add_group, group_id: group.id, user_id: user.id + expect(response).to be_success + + expect(GroupUser.where(user_id: user.id, group_id: group.id).exists?).to eq(true) + + # Doing it again doesn't raise an error + xhr :post, :add_group, group_id: group.id, user_id: user.id + expect(response).to be_success + end + end + context '.primary_group' do before do @another_user = Fabricate(:coding_horror) diff --git a/spec/controllers/session_controller_spec.rb b/spec/controllers/session_controller_spec.rb index 26d9b7f579..3f1af05533 100644 --- a/spec/controllers/session_controller_spec.rb +++ b/spec/controllers/session_controller_spec.rb @@ -264,40 +264,61 @@ describe SessionController do expect(response.code).to eq('419') end - it 'can act as an SSO provider' do - SiteSetting.enable_sso_provider = true - SiteSetting.enable_sso = false - SiteSetting.enable_local_logins = true - SiteSetting.sso_secret = "topsecret" + describe 'can act as an SSO provider' do + before do + SiteSetting.enable_sso_provider = true + SiteSetting.enable_sso = false + SiteSetting.enable_local_logins = true + SiteSetting.sso_secret = "topsecret" - sso = SingleSignOn.new - sso.nonce = "mynonce" - sso.sso_secret = SiteSetting.sso_secret - sso.return_sso_url = "http://somewhere.over.rainbow/sso" + @sso = SingleSignOn.new + @sso.nonce = "mynonce" + @sso.sso_secret = SiteSetting.sso_secret + @sso.return_sso_url = "http://somewhere.over.rainbow/sso" - get :sso_provider, Rack::Utils.parse_query(sso.payload) + @user = Fabricate(:user, password: "frogs", active: true, admin: true) + EmailToken.update_all(confirmed: true) + end - expect(response).to redirect_to("/login") + it "successfully logs in and redirects user to return_sso_url when the user is not logged in" do + get :sso_provider, Rack::Utils.parse_query(@sso.payload) + expect(response).to redirect_to("/login") - user = Fabricate(:user, password: "frogs", active: true, admin: true) - EmailToken.update_all(confirmed: true) + xhr :post, :create, login: @user.username, password: "frogs", format: :json - xhr :post, :create, login: user.username, password: "frogs", format: :json + location = cookies[:sso_destination_url] + # javascript code will handle redirection of user to return_sso_url + expect(location).to match(/^http:\/\/somewhere.over.rainbow\/sso/) - location = response.header["Location"] - expect(location).to match(/^http:\/\/somewhere.over.rainbow\/sso/) + payload = location.split("?")[1] + sso2 = SingleSignOn.parse(payload, "topsecret") - payload = location.split("?")[1] + expect(sso2.email).to eq(@user.email) + expect(sso2.name).to eq(@user.name) + expect(sso2.username).to eq(@user.username) + expect(sso2.external_id).to eq(@user.id.to_s) + expect(sso2.admin).to eq(true) + expect(sso2.moderator).to eq(false) + end - sso2 = SingleSignOn.parse(payload, "topsecret") + it "successfully redirects user to return_sso_url when the user is logged in" do + log_in_user(@user) - expect(sso2.email).to eq(user.email) - expect(sso2.name).to eq(user.name) - expect(sso2.username).to eq(user.username) - expect(sso2.external_id).to eq(user.id.to_s) - expect(sso2.admin).to eq(true) - expect(sso2.moderator).to eq(false) + get :sso_provider, Rack::Utils.parse_query(@sso.payload) + location = response.header["Location"] + expect(location).to match(/^http:\/\/somewhere.over.rainbow\/sso/) + + payload = location.split("?")[1] + sso2 = SingleSignOn.parse(payload, "topsecret") + + expect(sso2.email).to eq(@user.email) + expect(sso2.name).to eq(@user.name) + expect(sso2.username).to eq(@user.username) + expect(sso2.external_id).to eq(@user.id.to_s) + expect(sso2.admin).to eq(true) + expect(sso2.moderator).to eq(false) + end end describe 'local attribute override from SSO payload' do diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index e693da0225..fb49b404c7 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -3,71 +3,93 @@ require 'spec_helper' describe UsersController do describe '.show' do - let(:user) { log_in } - it 'returns success' do - xhr :get, :show, username: user.username, format: :json - expect(response).to be_success - json = JSON.parse(response.body) + context "anon" do - expect(json["user"]["has_title_badges"]).to eq(false) + let(:user) { Discourse.system_user } - end - - it "returns not found when the username doesn't exist" do - xhr :get, :show, username: 'madeuppity' - expect(response).not_to be_success - end - - it 'returns not found when the user is inactive' do - inactive = Fabricate(:user, active: false) - xhr :get, :show, username: inactive.username - expect(response).not_to be_success - end - - it "raises an error on invalid access" do - Guardian.any_instance.expects(:can_see?).with(user).returns(false) - xhr :get, :show, username: user.username - expect(response).to be_forbidden - end - - describe "user profile views" do - let(:other_user) { Fabricate(:user) } - - it "should track a user profile view for a signed in user" do - UserProfileView.expects(:add).with(other_user.user_profile.id, request.remote_ip, user.id) - xhr :get, :show, username: other_user.username - end - - it "should not track a user profile view for a user viewing his own profile" do - UserProfileView.expects(:add).never - xhr :get, :show, username: user.username - end - - it "should track a user profile view for an anon user" do - UserProfileView.expects(:add).with(other_user.user_profile.id, request.remote_ip, nil) - xhr :get, :show, username: other_user.username - end - - it "skips tracking" do - UserProfileView.expects(:add).never - xhr :get, :show, { username: user.username, skip_track_visit: true } - end - end - - context "fetching a user by external_id" do - before { user.create_single_sign_on_record(external_id: '997', last_payload: '') } - - it "returns fetch for a matching external_id" do - xhr :get, :show, external_id: '997' + it "returns success" do + xhr :get, :show, username: user.username, format: :json expect(response).to be_success end - it "returns not found when external_id doesn't match" do - xhr :get, :show, external_id: '99' + it "raises an error for anon when profiles are hidden" do + SiteSetting.stubs(:hide_user_profiles_from_public).returns(true) + xhr :get, :show, username: user.username, format: :json expect(response).not_to be_success end + end + + context "logged in" do + + let(:user) { log_in } + + it 'returns success' do + xhr :get, :show, username: user.username, format: :json + expect(response).to be_success + json = JSON.parse(response.body) + + expect(json["user"]["has_title_badges"]).to eq(false) + end + + it "returns not found when the username doesn't exist" do + xhr :get, :show, username: 'madeuppity' + expect(response).not_to be_success + end + + it 'returns not found when the user is inactive' do + inactive = Fabricate(:user, active: false) + xhr :get, :show, username: inactive.username + expect(response).not_to be_success + end + + it "raises an error on invalid access" do + Guardian.any_instance.expects(:can_see?).with(user).returns(false) + xhr :get, :show, username: user.username + expect(response).to be_forbidden + end + + describe "user profile views" do + let(:other_user) { Fabricate(:user) } + + it "should track a user profile view for a signed in user" do + UserProfileView.expects(:add).with(other_user.user_profile.id, request.remote_ip, user.id) + xhr :get, :show, username: other_user.username + end + + it "should not track a user profile view for a user viewing his own profile" do + UserProfileView.expects(:add).never + xhr :get, :show, username: user.username + end + + it "should track a user profile view for an anon user" do + UserProfileView.expects(:add).with(other_user.user_profile.id, request.remote_ip, nil) + xhr :get, :show, username: other_user.username + end + + it "skips tracking" do + UserProfileView.expects(:add).never + xhr :get, :show, { username: user.username, skip_track_visit: true } + end + end + + context "fetching a user by external_id" do + before { user.create_single_sign_on_record(external_id: '997', last_payload: '') } + + it "returns fetch for a matching external_id" do + xhr :get, :show, external_id: '997' + expect(response).to be_success + end + + it "returns not found when external_id doesn't match" do + xhr :get, :show, external_id: '99' + expect(response).not_to be_success + end + end + + end + end describe '.user_preferences_redirect' do diff --git a/spec/fixtures/emails/html_only.eml b/spec/fixtures/emails/html_only.eml index 561b8db2c7..db88f2c388 100644 --- a/spec/fixtures/emails/html_only.eml +++ b/spec/fixtures/emails/html_only.eml @@ -80,7 +80,7 @@ king"

    Grizzly B just sent you a private message

    -

    Log in to our EC2 instance -or- log into a new Digital Ocean instanc= +


    Log in to our EC2 instance -or- log into a new DigitalOcean instanc= e?


    Please visit this link to respond: `); + andThen(() => { + assert.equal(this.$('.d-editor-preview').html().trim(), '

    \">

    '); + }); + } +}); + componentTest('updating the value refreshes the preview', { template: '{{d-editor value=value}}', @@ -430,21 +442,34 @@ testCase(`rule with a selection`, function(assert, textarea) { }); }); -testCase(`emoji`, function(assert) { - assert.equal($('.emoji-modal').length, 0); +componentTest('emoji', { + template: '{{d-editor value=value}}', + setup() { + // Test adding a custom button + onToolbarCreate(toolbar => { + toolbar.addButton({ + id: 'emoji', + group: 'extras', + icon: 'smile-o', + action: 'emoji' + }); + }); + this.set('value', 'hello world.'); + }, + test(assert) { + assert.equal($('.emoji-modal').length, 0); - click('button.emoji'); - andThen(() => { - assert.equal($('.emoji-modal').length, 1); - }); + click('button.emoji'); + andThen(() => { + assert.equal($('.emoji-modal').length, 1); + }); - click('a[data-group-id=0]'); - click('a[title=grinning]'); + click('a[data-group-id=0]'); + click('a[title=grinning]'); - andThen(() => { - assert.ok($('.emoji-modal').length === 0); - assert.equal(this.get('value'), 'hello world.:grinning:'); - }); + andThen(() => { + assert.ok($('.emoji-modal').length === 0); + assert.equal(this.get('value'), 'hello world.:grinning:'); + }); + } }); - - diff --git a/test/javascripts/fixtures/search-fixtures.js.es6 b/test/javascripts/fixtures/search-fixtures.js.es6 index 344b655ec5..cd65c09b01 100644 --- a/test/javascripts/fixtures/search-fixtures.js.es6 +++ b/test/javascripts/fixtures/search-fixtures.js.es6 @@ -505,8 +505,8 @@ export default { }, { "id":26192, - "title":"403 when embedding a Digital Ocean droplet", - "fancy_title":"403 when embedding a Digital Ocean droplet", + "title":"403 when embedding a DigitalOcean droplet", + "fancy_title":"403 when embedding a DigitalOcean droplet", "slug":"403-when-embedding-a-digital-ocean-droplet", "posts_count":7, "reply_count":3, diff --git a/test/javascripts/fixtures/top_fixture.js.es6 b/test/javascripts/fixtures/top_fixture.js.es6 index 9dc5c7cd55..3ddc2300c6 100644 --- a/test/javascripts/fixtures/top_fixture.js.es6 +++ b/test/javascripts/fixtures/top_fixture.js.es6 @@ -1,2 +1,2 @@ /*jshint maxlen:10000000 */ -export default {"/top.json":{"users":[{"id":32,"username":"codinghorror","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/codinghorror/{size}/2.png"},{"id":2316,"username":"pakl","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pakl/{size}/2.png"},{"id":1,"username":"sam","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/sam/{size}/2.png"},{"id":2770,"username":"awesomerobot","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/awesomerobot/{size}/2.png"},{"id":8307,"username":"HAWK","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hawk/{size}/2.png"},{"id":10886,"username":"Onyx","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/onyx/{size}/2.png"},{"id":10855,"username":"abarker","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/abarker/{size}/2.png"},{"id":8300,"username":"cpradio","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cpradio/{size}/2.png"},{"id":5559,"username":"downey","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/downey/{size}/2.png"},{"id":11160,"username":"boomzilla","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/boomzilla/{size}/2.png"},{"id":4263,"username":"mcwumbly","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mcwumbly/{size}/2.png"},{"id":8909,"username":"AdamCapriola","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/adamcapriola/{size}/2.png"},{"id":4500,"username":"bbendick","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bbendick/{size}/2.png"},{"id":3415,"username":"radq","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/radq/{size}/2.png"},{"id":471,"username":"BhaelOchon","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bhaelochon/{size}/2.png"},{"id":7948,"username":"probus","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/probus/{size}/2.png"},{"id":6626,"username":"riking","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/riking/{size}/2.png"},{"id":2989,"username":"meglio","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/meglio/{size}/2.png"},{"id":8493,"username":"PJH","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pjh/{size}/2.png"},{"id":11455,"username":"Dan_G","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/dan_g/{size}/2.png"},{"id":5707,"username":"trident","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/trident/{size}/2.png"},{"id":5351,"username":"erlend_sh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/erlend_sh/{size}/2.png"},{"id":2,"username":"neil","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/neil/{size}/2.png"},{"id":11017,"username":"Matches","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/matches/{size}/2.png"},{"id":19,"username":"eviltrout","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eviltrout/{size}/2.png"},{"id":8325,"username":"StevieD","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/stevied/{size}/2.png"},{"id":6060,"username":"lightyear","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lightyear/{size}/2.png"},{"id":8085,"username":"watchmanmonitor","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/watchmanmonitor/{size}/2.png"},{"id":7717,"username":"lake54","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lake54/{size}/2.png"},{"id":8873,"username":"birarda","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/birarda/{size}/2.png"},{"id":8434,"username":"ArmedGuy","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/armedguy/{size}/2.png"},{"id":8437,"username":"paully21","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/paully21/{size}/2.png"},{"id":9147,"username":"davemaxwell","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/davemaxwell/{size}/2.png"},{"id":9653,"username":"TechnoBear","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/technobear/{size}/2.png"},{"id":11589,"username":"mott555","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mott555/{size}/2.png"},{"id":6607,"username":"aahank","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/aahank/{size}/2.png"},{"id":10816,"username":"Alankrit_Choudh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/alankrit_choudh/{size}/2.png"},{"id":8222,"username":"techAPJ","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/techapj/{size}/2.png"},{"id":11780,"username":"cosban","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cosban/{size}/2.png"},{"id":6819,"username":"gmanjapan","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/gmanjapan/{size}/2.png"},{"id":6548,"username":"michaeld","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/michaeld/{size}/2.png"},{"id":6268,"username":"ChaoticLoki","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/chaoticloki/{size}/2.png"},{"id":8,"username":"geek","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/geek/{size}/2.png"},{"id":8343,"username":"Piioo","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/piioo/{size}/2.png"},{"id":9536,"username":"nahtnam","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/nahtnam/{size}/2.png"},{"id":9093,"username":"RRManzke","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/rrmanzke/{size}/2.png"},{"id":8364,"username":"codetricity","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/codetricity/{size}/2.png"},{"id":5013,"username":"zenkamal","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/zenkamal/{size}/2.png"},{"id":10778,"username":"Lid","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lid/{size}/2.png"},{"id":5399,"username":"jeffwidman","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jeffwidman/{size}/2.png"},{"id":11747,"username":"fysics","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/fysics/{size}/2.png"},{"id":11762,"username":"bruceoberg","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bruceoberg/{size}/2.png"},{"id":10856,"username":"youderian","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/youderian/{size}/2.png"},{"id":8810,"username":"fantasticfears","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/fantasticfears/{size}/2.png"},{"id":10098,"username":"jwatte","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jwatte/{size}/2.png"},{"id":9775,"username":"elberet","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/elberet/{size}/2.png"},{"id":704,"username":"AstonJ","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/astonj/{size}/2.png"},{"id":10920,"username":"Webinsane","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/webinsane/{size}/2.png"},{"id":6613,"username":"haiku","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/haiku/{size}/2.png"},{"id":8820,"username":"aaroleung","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/aaroleung/{size}/2.png"},{"id":6746,"username":"shiningdracon","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/shiningdracon/{size}/2.png"},{"id":9909,"username":"unikevin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/unikevin/{size}/2.png"},{"id":11003,"username":"node","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/node/{size}/2.png"},{"id":8571,"username":"tobiaseigen","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/tobiaseigen/{size}/2.png"},{"id":8344,"username":"pyro240","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pyro240/{size}/2.png"},{"id":8399,"username":"edwardlafoy","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/edwardlafoy/{size}/2.png"},{"id":10949,"username":"stu1","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/stu1/{size}/2.png"},{"id":9664,"username":"cameronmartin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cameronmartin/{size}/2.png"},{"id":9931,"username":"Frank","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/frank/{size}/2.png"},{"id":10470,"username":"brpc","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/brpc/{size}/2.png"},{"id":10548,"username":"RabidFX","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/rabidfx/{size}/2.png"},{"id":4983,"username":"hey_julien","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hey_julien/{size}/2.png"},{"id":7074,"username":"Maomao","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/maomao/{size}/2.png"},{"id":7502,"username":"Pablo_Macaluso","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pablo_macaluso/{size}/2.png"},{"id":5609,"username":"camilohollanda","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/camilohollanda/{size}/2.png"},{"id":8059,"username":"Torrelles","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/torrelles/{size}/2.png"},{"id":8105,"username":"trevor_ratliff","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/trevor_ratliff/{size}/2.png"},{"id":8072,"username":"apere006","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/apere006/{size}/2.png"},{"id":9497,"username":"arumdev","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/arumdev/{size}/2.png"},{"id":5017,"username":"tuananh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/tuananh/{size}/2.png"},{"id":11163,"username":"faoileag","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/faoileag/{size}/2.png"},{"id":11265,"username":"cipher1","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cipher1/{size}/2.png"},{"id":5105,"username":"Ricky_Mason","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/ricky_mason/{size}/2.png"},{"id":1353,"username":"sparr","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/sparr/{size}/2.png"},{"id":5851,"username":"TheChadMiller","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/thechadmiller/{size}/2.png"},{"id":2520,"username":"anotherchris","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/anotherchris/{size}/2.png"},{"id":5249,"username":"cawas","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cawas/{size}/2.png"},{"id":4457,"username":"Lee_Ars","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lee_ars/{size}/2.png"},{"id":5160,"username":"eriko","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eriko/{size}/2.png"},{"id":4220,"username":"kirantpatil","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/kirantpatil/{size}/2.png"},{"id":3704,"username":"mojzis","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mojzis/{size}/2.png"},{"id":8944,"username":"hunterboerner","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hunterboerner/{size}/2.png"},{"id":6808,"username":"velesin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/velesin/{size}/2.png"},{"id":8933,"username":"JohnONolan","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/johnonolan/{size}/2.png"},{"id":7604,"username":"citkane","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/citkane/{size}/2.png"},{"id":1783,"username":"iainb","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/iainb/{size}/2.png"},{"id":9371,"username":"Vocino","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/vocino/{size}/2.png"},{"id":8617,"username":"Mittineague","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mittineague/{size}/2.png"},{"id":10632,"username":"justinmayer","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/justinmayer/{size}/2.png"},{"id":438,"username":"TuringTest","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/turingtest/{size}/2.png"},{"id":9726,"username":"brybell","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/brybell/{size}/2.png"},{"id":3675,"username":"jk779","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jk779/{size}/2.png"}],"topic_list":{"can_create_topic":false,"draft":null,"draft_key":"new_topic","draft_sequence":null,"for_period":"yearly","topics":[{"id":13088,"title":"Initial Discourse badge design spec","fancy_title":"Initial Discourse badge design spec","slug":"initial-discourse-badge-design-spec","posts_count":129,"reply_count":87,"highest_post_number":132,"image_url":"/uploads/default/3429/a20bcab33be2b6e2.png","created_at":"2014-02-26T04:55:39.741-05:00","last_posted_at":"2014-07-15T17:15:47.236-04:00","bumped":true,"bumped_at":"2014-07-15T17:15:47.236-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":3278,"like_count":305,"has_summary":true,"archetype":"regular","last_poster_username":"HAWK","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2316},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":8307}]},{"id":18063,"title":"10k+ posts causes progress bar to show single number","fancy_title":"10k+ posts causes progress bar to show single number","slug":"10k-posts-causes-progress-bar-to-show-single-number","posts_count":67,"reply_count":57,"highest_post_number":70,"image_url":"/uploads/default/_optimized/fdc/03e/3d48765fc4_690x45.png","created_at":"2014-07-25T13:31:34.474-04:00","last_posted_at":"2014-07-26T04:14:18.323-04:00","bumped":true,"bumped_at":"2014-07-26T04:20:54.730-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":335,"like_count":337,"has_summary":true,"archetype":"regular","last_poster_username":"sam","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":10886},{"extras":null,"description":"Frequent Poster","user_id":10855},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":18827,"title":"Consolidating Activity field","fancy_title":"Consolidating Activity field","slug":"consolidating-activity-field","posts_count":89,"reply_count":81,"highest_post_number":94,"image_url":"/uploads/default/33551/6483991bda61d4e5.png","created_at":"2014-08-13T18:46:09.613-04:00","last_posted_at":"2014-08-18T16:31:12.479-04:00","bumped":true,"bumped_at":"2014-08-18T16:30:13.362-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":226,"like_count":181,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":4263}]},{"id":18397,"title":"Does anyone actually like the \"Likes\" column?","fancy_title":"Does anyone actually like the “Likes” column?","slug":"does-anyone-actually-like-the-likes-column","posts_count":81,"reply_count":94,"highest_post_number":111,"image_url":null,"created_at":"2014-08-02T22:15:54.016-04:00","last_posted_at":"2014-08-25T19:37:00.313-04:00","bumped":true,"bumped_at":"2014-08-25T19:37:00.313-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":460,"like_count":191,"has_summary":true,"archetype":"regular","last_poster_username":"bbendick","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":8909},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":"latest","description":"Most Recent Poster","user_id":4500}]},{"id":13789,"title":"Badges feedback","fancy_title":"Badges feedback","slug":"badges-feedback","posts_count":101,"reply_count":74,"highest_post_number":104,"image_url":null,"created_at":"2014-03-16T20:16:29.885-04:00","last_posted_at":"2014-08-25T13:38:58.464-04:00","bumped":true,"bumped_at":"2014-08-25T13:38:58.464-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2227,"like_count":97,"has_summary":true,"archetype":"regular","last_poster_username":"cpradio","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":8300}]},{"id":13479,"title":"Topic List design experiments","fancy_title":"Topic List design experiments","slug":"topic-list-design-experiments","posts_count":90,"reply_count":70,"highest_post_number":93,"image_url":"/uploads/default/_optimized/8f2/41d/0436a3b666_689x392.png","created_at":"2014-03-06T23:41:26.312-05:00","last_posted_at":"2014-07-30T16:03:05.846-04:00","bumped":true,"bumped_at":"2014-07-30T16:03:05.846-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1532,"like_count":109,"has_summary":true,"archetype":"regular","last_poster_username":"probus","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":471},{"extras":"latest","description":"Most Recent Poster","user_id":7948}]},{"id":11911,"title":"How should we implement polls?","fancy_title":"How should we implement polls?","slug":"how-should-we-implement-polls","posts_count":70,"reply_count":51,"highest_post_number":73,"image_url":null,"created_at":"2014-01-12T21:48:03.160-05:00","last_posted_at":"2014-07-27T18:11:30.077-04:00","bumped":true,"bumped_at":"2014-07-27T18:11:30.077-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2724,"like_count":123,"has_summary":true,"archetype":"regular","last_poster_username":"meglio","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":2989}]},{"id":18524,"title":"Rename \"Dismiss Unread\" to \"Stop Tracking Topics\"","fancy_title":"Rename “Dismiss Unread” to “Stop Tracking Topics”","slug":"rename-dismiss-unread-to-stop-tracking-topics","posts_count":74,"reply_count":53,"highest_post_number":74,"image_url":null,"created_at":"2014-08-06T01:12:01.086-04:00","last_posted_at":"2014-08-12T05:47:20.750-04:00","bumped":true,"bumped_at":"2014-08-12T05:47:20.750-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":149,"like_count":103,"has_summary":true,"archetype":"regular","last_poster_username":"Dan_G","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":8493},{"extras":"latest","description":"Most Recent Poster","user_id":11455}]},{"id":10515,"title":"Flatter styling now deployed","fancy_title":"Flatter styling now deployed","slug":"flatter-styling-now-deployed","posts_count":80,"reply_count":41,"highest_post_number":80,"image_url":null,"created_at":"2013-10-20T19:36:00.465-04:00","last_posted_at":"2014-03-18T14:04:00.515-04:00","bumped":true,"bumped_at":"2014-03-18T14:04:00.515-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1790,"like_count":78,"has_summary":true,"archetype":"regular","last_poster_username":"mcwumbly","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":5707},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":4263}]},{"id":12346,"title":"What about an easier styling/theming system?","fancy_title":"What about an easier styling/theming system?","slug":"what-about-an-easier-styling-theming-system","posts_count":54,"reply_count":26,"highest_post_number":54,"image_url":null,"created_at":"2014-01-31T19:11:51.887-05:00","last_posted_at":"2014-07-01T17:42:38.425-04:00","bumped":true,"bumped_at":"2014-07-01T17:42:38.425-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1740,"like_count":130,"has_summary":true,"archetype":"regular","last_poster_username":"neil","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":5351},{"extras":"latest","description":"Most Recent Poster","user_id":2}]},{"id":18875,"title":"Notification when a moderator or admin deletes your message","fancy_title":"Notification when a moderator or admin deletes your message","slug":"notification-when-a-moderator-or-admin-deletes-your-message","posts_count":58,"reply_count":44,"highest_post_number":66,"image_url":null,"created_at":"2014-08-14T18:57:28.722-04:00","last_posted_at":"2014-08-20T12:34:26.180-04:00","bumped":true,"bumped_at":"2014-08-20T12:34:20.630-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":181,"like_count":122,"has_summary":true,"archetype":"regular","last_poster_username":"eviltrout","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":11017},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":11455},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":12257,"title":"Is \"Activity\" too ambiguous?","fancy_title":"Is “Activity” too ambiguous?","slug":"is-activity-too-ambiguous","posts_count":53,"reply_count":40,"highest_post_number":53,"image_url":"/uploads/default/_optimized/542/c04/82250e51e5_690x248.png","created_at":"2014-01-28T14:01:08.745-05:00","last_posted_at":"2014-04-13T18:25:45.492-04:00","bumped":true,"bumped_at":"2014-04-13T18:25:45.492-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":686,"like_count":103,"has_summary":true,"archetype":"regular","last_poster_username":"StevieD","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":7948},{"extras":"latest","description":"Most Recent Poster","user_id":8325}]},{"id":13099,"title":"Replacing Mailing lists: Email-In","fancy_title":"Replacing Mailing lists: Email-In","slug":"replacing-mailing-lists-email-in","posts_count":66,"reply_count":46,"highest_post_number":68,"image_url":null,"created_at":"2014-02-26T13:24:44.965-05:00","last_posted_at":"2014-07-09T18:01:21.166-04:00","bumped":true,"bumped_at":"2014-07-09T19:10:30.547-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1567,"like_count":76,"has_summary":true,"archetype":"regular","last_poster_username":"lake54","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6060},{"extras":null,"description":"Frequent Poster","user_id":5351},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":7717}]},{"id":13045,"title":"Official Single-Sign-On for Discourse","fancy_title":"Official Single-Sign-On for Discourse","slug":"official-single-sign-on-for-discourse","posts_count":61,"reply_count":37,"highest_post_number":64,"image_url":"/uploads/default/_optimized/07c/3bf/3fa1d69ceb_690x207.png","created_at":"2014-02-25T03:30:34.321-05:00","last_posted_at":"2014-08-01T17:44:56.523-04:00","bumped":true,"bumped_at":"2014-08-07T13:27:14.684-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":13052,"like_count":74,"has_summary":true,"archetype":"regular","last_poster_username":"riking","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8873},{"extras":null,"description":"Frequent Poster","user_id":8434},{"extras":null,"description":"Frequent Poster","user_id":8437},{"extras":"latest","description":"Most Recent Poster","user_id":6626}]},{"id":19099,"title":"Should search prioritize recent topics over older topics?","fancy_title":"Should search prioritize recent topics over older topics?","slug":"should-search-prioritize-recent-topics-over-older-topics","posts_count":55,"reply_count":48,"highest_post_number":58,"image_url":"/uploads/default/33840/49e57c5a286a2131.png","created_at":"2014-08-20T12:00:12.737-04:00","last_posted_at":"2014-08-22T17:46:34.073-04:00","bumped":true,"bumped_at":"2014-08-22T17:46:20.038-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":149,"like_count":83,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":9147},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":9653},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":18879,"title":"Further simplifying the columns: quality score > view count","fancy_title":"Further simplifying the columns: quality score > view count","slug":"further-simplifying-the-columns-quality-score-view-count","posts_count":44,"reply_count":32,"highest_post_number":44,"image_url":"/uploads/default/33627/b40ad535eba2b7a3.png","created_at":"2014-08-14T21:19:24.118-04:00","last_posted_at":"2014-08-22T14:25:12.092-04:00","bumped":true,"bumped_at":"2014-08-22T15:21:09.995-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":560,"like_count":95,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":8909},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":11589},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13847,"title":"Allowing SSL for your Discourse Docker setup","fancy_title":"Allowing SSL for your Discourse Docker setup","slug":"allowing-ssl-for-your-discourse-docker-setup","posts_count":47,"reply_count":59,"highest_post_number":58,"image_url":null,"created_at":"2014-03-18T19:45:27.517-04:00","last_posted_at":"2014-08-28T04:03:20.851-04:00","bumped":true,"bumped_at":"2014-08-28T04:17:17.852-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":6927,"like_count":87,"has_summary":false,"archetype":"regular","last_poster_username":"cosban","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6607},{"extras":null,"description":"Frequent Poster","user_id":10816},{"extras":null,"description":"Frequent Poster","user_id":8222},{"extras":"latest","description":"Most Recent Poster","user_id":11780}]},{"id":9621,"title":"Free Hosted Option?","fancy_title":"Free Hosted Option?","slug":"free-hosted-option","posts_count":43,"reply_count":33,"highest_post_number":43,"image_url":null,"created_at":"2013-09-05T16:22:20.790-04:00","last_posted_at":"2014-04-08T00:24:46.320-04:00","bumped":true,"bumped_at":"2014-04-08T00:24:46.320-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1844,"like_count":93,"has_summary":false,"archetype":"regular","last_poster_username":"ChaoticLoki","category_id":8,"posters":[{"extras":null,"description":"Original Poster","user_id":6819},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":6268}]},{"id":18873,"title":"Alternative to blue colors for coldmapping","fancy_title":"Alternative to blue colors for coldmapping","slug":"alternative-to-blue-colors-for-coldmapping","posts_count":47,"reply_count":23,"highest_post_number":47,"image_url":null,"created_at":"2014-08-14T18:33:21.844-04:00","last_posted_at":"2014-08-15T10:46:08.175-04:00","bumped":true,"bumped_at":"2014-08-15T10:46:08.175-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":122,"like_count":84,"has_summary":false,"archetype":"regular","last_poster_username":"boomzilla","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":10855},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":8},{"extras":"latest","description":"Most Recent Poster","user_id":11160}]},{"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":57,"reply_count":36,"highest_post_number":58,"image_url":"/uploads/default/_optimized/66d/cf0/d69e6709fe_496x500.PNG","created_at":"2014-01-05T14:28:58.037-05:00","last_posted_at":"2014-08-08T07:55:23.454-04:00","bumped":true,"bumped_at":"2014-08-08T07:55:23.454-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2085,"like_count":62,"has_summary":true,"archetype":"regular","last_poster_username":"michaeld","category_id":22,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":8343},{"extras":null,"description":"Frequent Poster","user_id":9536},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":9093}]},{"id":13485,"title":"What do you like/dislike about the NodeBB design?","fancy_title":"What do you like/dislike about the NodeBB design?","slug":"what-do-you-like-dislike-about-the-nodebb-design","posts_count":52,"reply_count":28,"highest_post_number":53,"image_url":null,"created_at":"2014-03-07T03:38:14.227-05:00","last_posted_at":"2014-08-20T15:19:00.969-04:00","bumped":true,"bumped_at":"2014-08-19T20:22:04.123-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1495,"like_count":68,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8364},{"extras":null,"description":"Frequent Poster","user_id":5013},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":2770}]},{"id":17454,"title":"Spambots from Tor exit points keep taking over my forum","fancy_title":"Spambots from Tor exit points keep taking over my forum","slug":"spambots-from-tor-exit-points-keep-taking-over-my-forum","posts_count":46,"reply_count":32,"highest_post_number":46,"image_url":"/uploads/default/_optimized/b0d/ab3/20401b97ce_690x454.png","created_at":"2014-07-11T03:20:49.433-04:00","last_posted_at":"2014-08-19T18:09:10.799-04:00","bumped":true,"bumped_at":"2014-08-19T18:02:57.107-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1243,"like_count":78,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":6,"posters":[{"extras":null,"description":"Original Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":10778},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":19317,"title":"Introducing Discourse 1.0","fancy_title":"Introducing Discourse 1.0","slug":"introducing-discourse-1-0","posts_count":36,"reply_count":3,"highest_post_number":36,"image_url":null,"created_at":"2014-08-26T15:43:01.370-04:00","last_posted_at":"2014-08-28T13:16:42.484-04:00","bumped":true,"bumped_at":"2014-08-28T13:16:42.484-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":709,"like_count":103,"has_summary":false,"archetype":"regular","last_poster_username":"youderian","category_id":13,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5399},{"extras":null,"description":"Frequent Poster","user_id":11747},{"extras":null,"description":"Frequent Poster","user_id":11762},{"extras":"latest","description":"Most Recent Poster","user_id":10856}]},{"id":13184,"title":"Discourse General Polish prior to V1","fancy_title":"Discourse General Polish prior to V1","slug":"discourse-general-polish-prior-to-v1","posts_count":44,"reply_count":30,"highest_post_number":48,"image_url":"/plugins/emoji/images/arrow_left.png","created_at":"2014-02-27T19:10:41.496-05:00","last_posted_at":"2014-06-08T03:32:02.009-04:00","bumped":true,"bumped_at":"2014-06-06T03:30:23.984-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":1864,"like_count":77,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":8222},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":17694,"title":"Release schedule post version 1.0","fancy_title":"Release schedule post version 1.0","slug":"release-schedule-post-version-1-0","posts_count":44,"reply_count":35,"highest_post_number":44,"image_url":null,"created_at":"2014-07-17T19:45:21.459-04:00","last_posted_at":"2014-07-23T03:51:03.564-04:00","bumped":true,"bumped_at":"2014-07-29T17:20:06.942-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":539,"like_count":70,"has_summary":false,"archetype":"regular","last_poster_username":"probus","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":10098},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":"latest","description":"Most Recent Poster","user_id":7948}]},{"id":18533,"title":"My latest forum... but it's not running Discourse - here's why","fancy_title":"My latest forum… but it’s not running Discourse - here’s why","slug":"my-latest-forum-but-its-not-running-discourse-heres-why","posts_count":37,"reply_count":27,"highest_post_number":38,"image_url":null,"created_at":"2014-08-06T06:01:35.608-04:00","last_posted_at":"2014-08-15T13:27:13.386-04:00","bumped":true,"bumped_at":"2014-08-15T13:27:13.386-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1185,"like_count":73,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":704},{"extras":null,"description":"Frequent Poster","user_id":10920},{"extras":null,"description":"Frequent Poster","user_id":6613},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13287,"title":"Chinese search issues","fancy_title":"Chinese search issues","slug":"chinese-search-issues","posts_count":60,"reply_count":41,"highest_post_number":60,"image_url":"https://f.cloud.github.com/assets/6783175/2296397/3dcabcf8-a09e-11e3-9f5a-2a94d981fced.png","created_at":"2014-03-01T10:12:14.845-05:00","last_posted_at":"2014-07-10T17:03:25.796-04:00","bumped":true,"bumped_at":"2014-07-10T17:03:25.796-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":947,"like_count":25,"has_summary":true,"archetype":"regular","last_poster_username":"sam","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":8820},{"extras":null,"description":"Frequent Poster","user_id":6746},{"extras":null,"description":"Frequent Poster","user_id":9909},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":17727,"title":"Compliance with EU Cookie Law","fancy_title":"Compliance with EU Cookie Law","slug":"compliance-with-eu-cookie-law","posts_count":46,"reply_count":32,"highest_post_number":46,"image_url":null,"created_at":"2014-07-18T17:39:38.499-04:00","last_posted_at":"2014-07-26T18:01:33.751-04:00","bumped":true,"bumped_at":"2014-07-26T18:01:33.751-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":836,"like_count":48,"has_summary":false,"archetype":"regular","last_poster_username":"node","category_id":6,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":11003},{"extras":null,"description":"Frequent Poster","user_id":11017},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":9536}]},{"id":15336,"title":"Switch from Gravatar to HTML/CSS letters for no-avatar users","fancy_title":"Switch from Gravatar to HTML/CSS letters for no-avatar users","slug":"switch-from-gravatar-to-html-css-letters-for-no-avatar-users","posts_count":39,"reply_count":25,"highest_post_number":39,"image_url":"/uploads/default/_optimized/d29/bc1/25fa89ae0a_415x500.png","created_at":"2014-05-05T18:46:02.221-04:00","last_posted_at":"2014-05-28T18:07:12.448-04:00","bumped":true,"bumped_at":"2014-05-28T18:07:09.701-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":1011,"like_count":63,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":26,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":8571},{"extras":null,"description":"Frequent Poster","user_id":8344}]},{"id":12957,"title":"Discourse for iOS","fancy_title":"Discourse for iOS","slug":"discourse-for-ios","posts_count":43,"reply_count":24,"highest_post_number":43,"image_url":"http://a4.mzstatic.com/us/r30/Purple/v4/8d/85/93/8d859353-625c-8abc-5c00-36be5f293709/mzl.luwjaamb.png","created_at":"2014-02-21T20:37:44.606-05:00","last_posted_at":"2014-08-20T15:09:19.767-04:00","bumped":true,"bumped_at":"2014-08-20T15:09:19.767-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1082,"like_count":48,"has_summary":false,"archetype":"regular","last_poster_username":"erlend_sh","category_id":5,"posters":[{"extras":null,"description":"Original Poster","user_id":8399},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":10949},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":5351}]},{"id":14973,"title":"Symbol for like - why is it a heart?","fancy_title":"Symbol for like - why is it a heart?","slug":"symbol-for-like-why-is-it-a-heart","posts_count":29,"reply_count":14,"highest_post_number":29,"image_url":null,"created_at":"2014-04-22T12:24:22.822-04:00","last_posted_at":"2014-05-08T17:41:27.803-04:00","bumped":true,"bumped_at":"2014-05-08T17:41:27.803-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1421,"like_count":73,"has_summary":false,"archetype":"regular","last_poster_username":"Frank","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":9664},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":9931}]},{"id":16875,"title":"Options to disable hijack of CMD+F / CTRL+F and \"/\" keys for search?","fancy_title":"Options to disable hijack of CMD+F / CTRL+F and “/” keys for search?","slug":"options-to-disable-hijack-of-cmd-f-ctrl-f-and-keys-for-search","posts_count":44,"reply_count":36,"highest_post_number":44,"image_url":null,"created_at":"2014-06-25T17:04:48.413-04:00","last_posted_at":"2014-08-25T04:01:38.132-04:00","bumped":true,"bumped_at":"2014-08-25T04:01:38.132-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":541,"like_count":41,"has_summary":false,"archetype":"regular","last_poster_username":"RabidFX","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":10470},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":"latest","description":"Most Recent Poster","user_id":10548}]},{"id":9975,"title":"Translators We Want You!","fancy_title":"Translators We Want You!","slug":"translators-we-want-you","posts_count":50,"reply_count":28,"highest_post_number":50,"image_url":null,"created_at":"2013-09-23T13:47:39.521-04:00","last_posted_at":"2014-03-16T16:21:13.891-04:00","bumped":true,"bumped_at":"2014-03-16T16:21:13.891-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1262,"like_count":26,"has_summary":true,"archetype":"regular","last_poster_username":"Torrelles","category_id":27,"posters":[{"extras":null,"description":"Original Poster","user_id":4983},{"extras":null,"description":"Frequent Poster","user_id":7074},{"extras":null,"description":"Frequent Poster","user_id":7502},{"extras":null,"description":"Frequent Poster","user_id":5609},{"extras":"latest","description":"Most Recent Poster","user_id":8059}]},{"id":12112,"title":"The system user needs a cool avatar","fancy_title":"The system user needs a cool avatar","slug":"the-system-user-needs-a-cool-avatar","posts_count":35,"reply_count":24,"highest_post_number":35,"image_url":"/uploads/default/31460/c596ef65a9d0533c.png","created_at":"2014-01-21T22:26:01.574-05:00","last_posted_at":"2014-01-31T16:54:22.261-05:00","bumped":true,"bumped_at":"2014-01-31T16:54:22.261-05:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":848,"like_count":55,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":8105},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":11718,"title":"Reply button while logged out","fancy_title":"Reply button while logged out","slug":"reply-button-while-logged-out","posts_count":46,"reply_count":42,"highest_post_number":46,"image_url":null,"created_at":"2014-01-02T17:11:14.130-05:00","last_posted_at":"2014-04-05T10:20:11.921-04:00","bumped":true,"bumped_at":"2014-04-05T10:20:11.921-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":830,"like_count":32,"has_summary":false,"archetype":"regular","last_poster_username":"apere006","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":8072},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":9497},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":471}]},{"id":18698,"title":"Site setting for sending analytics data to Discourse.org","fancy_title":"Site setting for sending analytics data to Discourse.org","slug":"site-setting-for-sending-analytics-data-to-discourse-org","posts_count":27,"reply_count":18,"highest_post_number":27,"image_url":null,"created_at":"2014-08-10T11:47:04.016-04:00","last_posted_at":"2014-08-11T15:36:21.664-04:00","bumped":true,"bumped_at":"2014-08-11T15:36:04.020-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":135,"like_count":72,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":17443,"title":"Can I Keep Nofollow for All User Links, Including from Trust Level 3?","fancy_title":"Can I Keep Nofollow for All User Links, Including from Trust Level 3?","slug":"can-i-keep-nofollow-for-all-user-links-including-from-trust-level-3","posts_count":40,"reply_count":30,"highest_post_number":41,"image_url":null,"created_at":"2014-07-10T22:06:49.357-04:00","last_posted_at":"2014-07-14T19:20:37.014-04:00","bumped":true,"bumped_at":"2014-07-14T19:20:37.014-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":237,"like_count":42,"has_summary":false,"archetype":"regular","last_poster_username":"cpradio","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5017},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":8300}]},{"id":18821,"title":"Suggestion: # of likes in a topic in the tool tip","fancy_title":"Suggestion: # of likes in a topic in the tool tip","slug":"suggestion-of-likes-in-a-topic-in-the-tool-tip","posts_count":27,"reply_count":22,"highest_post_number":27,"image_url":null,"created_at":"2014-08-13T15:23:46.745-04:00","last_posted_at":"2014-08-15T07:40:57.684-04:00","bumped":true,"bumped_at":"2014-08-15T07:40:57.684-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":133,"like_count":68,"has_summary":false,"archetype":"regular","last_poster_username":"boomzilla","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":11163},{"extras":null,"description":"Frequent Poster","user_id":11265},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8493},{"extras":"latest","description":"Most Recent Poster","user_id":11160}]},{"id":9741,"title":"Difference between Reddit and Discourse","fancy_title":"Difference between Reddit and Discourse","slug":"difference-between-reddit-and-discourse","posts_count":42,"reply_count":32,"highest_post_number":42,"image_url":null,"created_at":"2013-09-11T22:17:39.971-04:00","last_posted_at":"2013-09-17T19:01:36.139-04:00","bumped":true,"bumped_at":"2013-09-17T19:01:36.139-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":3303,"like_count":35,"has_summary":false,"archetype":"regular","last_poster_username":"anotherchris","category_id":3,"posters":[{"extras":null,"description":"Original Poster","user_id":5105},{"extras":null,"description":"Frequent Poster","user_id":1353},{"extras":null,"description":"Frequent Poster","user_id":5851},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":2520}]},{"id":12156,"title":"Beginners Guide to Deploy Discourse on Digital Ocean using Docker","fancy_title":"Beginners Guide to Deploy Discourse on Digital Ocean using Docker","slug":"beginners-guide-to-deploy-discourse-on-digital-ocean-using-docker","posts_count":28,"reply_count":157,"highest_post_number":219,"image_url":"http://www.discourse.org/images/install/droplet-step-1.png","created_at":"2014-01-23T14:58:17.918-05:00","last_posted_at":"2014-08-26T10:06:25.833-04:00","bumped":true,"bumped_at":"2014-08-26T10:06:25.833-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":10112,"like_count":63,"has_summary":false,"archetype":"regular","last_poster_username":"cawas","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":8222},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":8364},{"extras":"latest","description":"Most Recent Poster","user_id":5249}]},{"id":12522,"title":"Permission Changes (moderators have less)","fancy_title":"Permission Changes (moderators have less)","slug":"permission-changes-moderators-have-less","posts_count":42,"reply_count":30,"highest_post_number":43,"image_url":null,"created_at":"2014-02-06T22:34:05.332-05:00","last_posted_at":"2014-08-01T12:26:40.440-04:00","bumped":true,"bumped_at":"2014-08-01T12:26:40.440-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1806,"like_count":37,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":4457},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":10291,"title":"CAS sso auth plugin","fancy_title":"CAS sso auth plugin","slug":"cas-sso-auth-plugin","posts_count":48,"reply_count":32,"highest_post_number":51,"image_url":null,"created_at":"2013-10-09T17:01:21.524-04:00","last_posted_at":"2014-08-27T16:08:25.417-04:00","bumped":true,"bumped_at":"2014-08-27T16:08:25.417-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1433,"like_count":20,"has_summary":false,"archetype":"regular","last_poster_username":"eriko","category_id":22,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5160},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4220},{"extras":null,"description":"Frequent Poster","user_id":3704},{"extras":null,"description":"Frequent Poster","user_id":32}]},{"id":16877,"title":"Discourse V1.0 Next Month","fancy_title":"Discourse V1.0 Next Month","slug":"discourse-v1-0-next-month","posts_count":25,"reply_count":11,"highest_post_number":26,"image_url":null,"created_at":"2014-06-25T18:54:32.020-04:00","last_posted_at":"2014-08-14T13:07:09.405-04:00","bumped":true,"bumped_at":"2014-08-14T13:07:09.405-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1113,"like_count":65,"has_summary":false,"archetype":"regular","last_poster_username":"Dan_G","category_id":13,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":null,"description":"Frequent Poster","user_id":8944},{"extras":null,"description":"Frequent Poster","user_id":10920},{"extras":"latest","description":"Most Recent Poster","user_id":11455}]},{"id":18257,"title":"Move the new/unread counters to the first column in topic list","fancy_title":"Move the new/unread counters to the first column in topic list","slug":"move-the-new-unread-counters-to-the-first-column-in-topic-list","posts_count":32,"reply_count":25,"highest_post_number":32,"image_url":null,"created_at":"2014-07-30T02:33:42.679-04:00","last_posted_at":"2014-08-01T12:33:11.694-04:00","bumped":true,"bumped_at":"2014-08-01T12:33:11.694-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":217,"like_count":51,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13249,"title":"Syncing the editor viewport scroll","fancy_title":"Syncing the editor viewport scroll","slug":"syncing-the-editor-viewport-scroll","posts_count":35,"reply_count":15,"highest_post_number":35,"image_url":null,"created_at":"2014-02-28T19:03:57.708-05:00","last_posted_at":"2014-04-06T21:04:59.528-04:00","bumped":true,"bumped_at":"2014-04-06T21:04:59.528-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":980,"like_count":44,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6808},{"extras":null,"description":"Frequent Poster","user_id":8933},{"extras":null,"description":"Frequent Poster","user_id":19},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":9711,"title":"Now testing: mobile (small screen) layouts on key pages","fancy_title":"Now testing: mobile (small screen) layouts on key pages","slug":"now-testing-mobile-small-screen-layouts-on-key-pages","posts_count":43,"reply_count":31,"highest_post_number":51,"image_url":"/uploads/meta_discourse/1787/beb2b60fba4c46c3.png","created_at":"2013-09-10T19:45:51.532-04:00","last_posted_at":"2014-02-05T02:03:24.974-05:00","bumped":true,"bumped_at":"2014-02-05T13:45:55.088-05:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1635,"like_count":27,"has_summary":false,"archetype":"regular","last_poster_username":"iainb","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2},{"extras":null,"description":"Frequent Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":7604},{"extras":"latest","description":"Most Recent Poster","user_id":1783}]},{"id":15048,"title":"Linking a Discourse User db with a Mumble server (Murmur)","fancy_title":"Linking a Discourse User db with a Mumble server (Murmur)","slug":"linking-a-discourse-user-db-with-a-mumble-server-murmur","posts_count":48,"reply_count":40,"highest_post_number":48,"image_url":null,"created_at":"2014-04-24T18:30:17.568-04:00","last_posted_at":"2014-05-30T20:43:13.387-04:00","bumped":true,"bumped_at":"2014-05-30T20:43:13.387-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":625,"like_count":17,"has_summary":false,"archetype":"regular","last_poster_username":"Vocino","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":9371},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":4457},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6613}]},{"id":17945,"title":"Unread/new badge style?","fancy_title":"Unread/new badge style?","slug":"unread-new-badge-style","posts_count":35,"reply_count":23,"highest_post_number":35,"image_url":"/uploads/default/_optimized/b61/a61/3508713cc1_690x202.png","created_at":"2014-07-23T10:49:18.864-04:00","last_posted_at":"2014-07-28T13:52:16.773-04:00","bumped":true,"bumped_at":"2014-07-28T13:52:16.773-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":279,"like_count":43,"has_summary":false,"archetype":"regular","last_poster_username":"Mittineague","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":8617}]},{"id":16803,"title":"Auto-hide persistent fixed header on scroll","fancy_title":"Auto-hide persistent fixed header on scroll","slug":"auto-hide-persistent-fixed-header-on-scroll","posts_count":39,"reply_count":27,"highest_post_number":39,"image_url":null,"created_at":"2014-06-23T13:25:32.523-04:00","last_posted_at":"2014-07-07T10:45:40.399-04:00","bumped":true,"bumped_at":"2014-07-07T10:45:40.399-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":792,"like_count":34,"has_summary":false,"archetype":"regular","last_poster_username":"mcwumbly","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":10632},{"extras":null,"description":"Frequent Poster","user_id":438},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":4263}]},{"id":15858,"title":"Configuring Google OAuth2 login for Discourse","fancy_title":"Configuring Google OAuth2 login for Discourse","slug":"configuring-google-oauth2-login-for-discourse","posts_count":36,"reply_count":24,"highest_post_number":40,"image_url":"/uploads/default/_optimized/9ae/174/5a30a33f56_690x399.png","created_at":"2014-05-21T18:46:55.403-04:00","last_posted_at":"2014-08-17T15:30:40.593-04:00","bumped":true,"bumped_at":"2014-08-17T15:29:45.558-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":5257,"like_count":41,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":2},{"extras":null,"description":"Frequent Poster","user_id":9726},{"extras":null,"description":"Frequent Poster","user_id":3675},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":32}]}]}}}; +export default {"/top.json":{"users":[{"id":32,"username":"codinghorror","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/codinghorror/{size}/2.png"},{"id":2316,"username":"pakl","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pakl/{size}/2.png"},{"id":1,"username":"sam","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/sam/{size}/2.png"},{"id":2770,"username":"awesomerobot","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/awesomerobot/{size}/2.png"},{"id":8307,"username":"HAWK","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hawk/{size}/2.png"},{"id":10886,"username":"Onyx","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/onyx/{size}/2.png"},{"id":10855,"username":"abarker","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/abarker/{size}/2.png"},{"id":8300,"username":"cpradio","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cpradio/{size}/2.png"},{"id":5559,"username":"downey","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/downey/{size}/2.png"},{"id":11160,"username":"boomzilla","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/boomzilla/{size}/2.png"},{"id":4263,"username":"mcwumbly","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mcwumbly/{size}/2.png"},{"id":8909,"username":"AdamCapriola","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/adamcapriola/{size}/2.png"},{"id":4500,"username":"bbendick","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bbendick/{size}/2.png"},{"id":3415,"username":"radq","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/radq/{size}/2.png"},{"id":471,"username":"BhaelOchon","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bhaelochon/{size}/2.png"},{"id":7948,"username":"probus","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/probus/{size}/2.png"},{"id":6626,"username":"riking","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/riking/{size}/2.png"},{"id":2989,"username":"meglio","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/meglio/{size}/2.png"},{"id":8493,"username":"PJH","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pjh/{size}/2.png"},{"id":11455,"username":"Dan_G","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/dan_g/{size}/2.png"},{"id":5707,"username":"trident","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/trident/{size}/2.png"},{"id":5351,"username":"erlend_sh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/erlend_sh/{size}/2.png"},{"id":2,"username":"neil","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/neil/{size}/2.png"},{"id":11017,"username":"Matches","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/matches/{size}/2.png"},{"id":19,"username":"eviltrout","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eviltrout/{size}/2.png"},{"id":8325,"username":"StevieD","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/stevied/{size}/2.png"},{"id":6060,"username":"lightyear","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lightyear/{size}/2.png"},{"id":8085,"username":"watchmanmonitor","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/watchmanmonitor/{size}/2.png"},{"id":7717,"username":"lake54","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lake54/{size}/2.png"},{"id":8873,"username":"birarda","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/birarda/{size}/2.png"},{"id":8434,"username":"ArmedGuy","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/armedguy/{size}/2.png"},{"id":8437,"username":"paully21","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/paully21/{size}/2.png"},{"id":9147,"username":"davemaxwell","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/davemaxwell/{size}/2.png"},{"id":9653,"username":"TechnoBear","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/technobear/{size}/2.png"},{"id":11589,"username":"mott555","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mott555/{size}/2.png"},{"id":6607,"username":"aahank","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/aahank/{size}/2.png"},{"id":10816,"username":"Alankrit_Choudh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/alankrit_choudh/{size}/2.png"},{"id":8222,"username":"techAPJ","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/techapj/{size}/2.png"},{"id":11780,"username":"cosban","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cosban/{size}/2.png"},{"id":6819,"username":"gmanjapan","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/gmanjapan/{size}/2.png"},{"id":6548,"username":"michaeld","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/michaeld/{size}/2.png"},{"id":6268,"username":"ChaoticLoki","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/chaoticloki/{size}/2.png"},{"id":8,"username":"geek","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/geek/{size}/2.png"},{"id":8343,"username":"Piioo","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/piioo/{size}/2.png"},{"id":9536,"username":"nahtnam","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/nahtnam/{size}/2.png"},{"id":9093,"username":"RRManzke","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/rrmanzke/{size}/2.png"},{"id":8364,"username":"codetricity","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/codetricity/{size}/2.png"},{"id":5013,"username":"zenkamal","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/zenkamal/{size}/2.png"},{"id":10778,"username":"Lid","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lid/{size}/2.png"},{"id":5399,"username":"jeffwidman","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jeffwidman/{size}/2.png"},{"id":11747,"username":"fysics","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/fysics/{size}/2.png"},{"id":11762,"username":"bruceoberg","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/bruceoberg/{size}/2.png"},{"id":10856,"username":"youderian","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/youderian/{size}/2.png"},{"id":8810,"username":"fantasticfears","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/fantasticfears/{size}/2.png"},{"id":10098,"username":"jwatte","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jwatte/{size}/2.png"},{"id":9775,"username":"elberet","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/elberet/{size}/2.png"},{"id":704,"username":"AstonJ","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/astonj/{size}/2.png"},{"id":10920,"username":"Webinsane","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/webinsane/{size}/2.png"},{"id":6613,"username":"haiku","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/haiku/{size}/2.png"},{"id":8820,"username":"aaroleung","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/aaroleung/{size}/2.png"},{"id":6746,"username":"shiningdracon","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/shiningdracon/{size}/2.png"},{"id":9909,"username":"unikevin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/unikevin/{size}/2.png"},{"id":11003,"username":"node","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/node/{size}/2.png"},{"id":8571,"username":"tobiaseigen","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/tobiaseigen/{size}/2.png"},{"id":8344,"username":"pyro240","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pyro240/{size}/2.png"},{"id":8399,"username":"edwardlafoy","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/edwardlafoy/{size}/2.png"},{"id":10949,"username":"stu1","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/stu1/{size}/2.png"},{"id":9664,"username":"cameronmartin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cameronmartin/{size}/2.png"},{"id":9931,"username":"Frank","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/frank/{size}/2.png"},{"id":10470,"username":"brpc","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/brpc/{size}/2.png"},{"id":10548,"username":"RabidFX","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/rabidfx/{size}/2.png"},{"id":4983,"username":"hey_julien","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hey_julien/{size}/2.png"},{"id":7074,"username":"Maomao","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/maomao/{size}/2.png"},{"id":7502,"username":"Pablo_Macaluso","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/pablo_macaluso/{size}/2.png"},{"id":5609,"username":"camilohollanda","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/camilohollanda/{size}/2.png"},{"id":8059,"username":"Torrelles","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/torrelles/{size}/2.png"},{"id":8105,"username":"trevor_ratliff","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/trevor_ratliff/{size}/2.png"},{"id":8072,"username":"apere006","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/apere006/{size}/2.png"},{"id":9497,"username":"arumdev","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/arumdev/{size}/2.png"},{"id":5017,"username":"tuananh","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/tuananh/{size}/2.png"},{"id":11163,"username":"faoileag","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/faoileag/{size}/2.png"},{"id":11265,"username":"cipher1","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cipher1/{size}/2.png"},{"id":5105,"username":"Ricky_Mason","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/ricky_mason/{size}/2.png"},{"id":1353,"username":"sparr","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/sparr/{size}/2.png"},{"id":5851,"username":"TheChadMiller","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/thechadmiller/{size}/2.png"},{"id":2520,"username":"anotherchris","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/anotherchris/{size}/2.png"},{"id":5249,"username":"cawas","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/cawas/{size}/2.png"},{"id":4457,"username":"Lee_Ars","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/lee_ars/{size}/2.png"},{"id":5160,"username":"eriko","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eriko/{size}/2.png"},{"id":4220,"username":"kirantpatil","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/kirantpatil/{size}/2.png"},{"id":3704,"username":"mojzis","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mojzis/{size}/2.png"},{"id":8944,"username":"hunterboerner","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/hunterboerner/{size}/2.png"},{"id":6808,"username":"velesin","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/velesin/{size}/2.png"},{"id":8933,"username":"JohnONolan","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/johnonolan/{size}/2.png"},{"id":7604,"username":"citkane","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/citkane/{size}/2.png"},{"id":1783,"username":"iainb","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/iainb/{size}/2.png"},{"id":9371,"username":"Vocino","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/vocino/{size}/2.png"},{"id":8617,"username":"Mittineague","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/mittineague/{size}/2.png"},{"id":10632,"username":"justinmayer","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/justinmayer/{size}/2.png"},{"id":438,"username":"TuringTest","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/turingtest/{size}/2.png"},{"id":9726,"username":"brybell","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/brybell/{size}/2.png"},{"id":3675,"username":"jk779","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/jk779/{size}/2.png"}],"topic_list":{"can_create_topic":false,"draft":null,"draft_key":"new_topic","draft_sequence":null,"for_period":"yearly","topics":[{"id":13088,"title":"Initial Discourse badge design spec","fancy_title":"Initial Discourse badge design spec","slug":"initial-discourse-badge-design-spec","posts_count":129,"reply_count":87,"highest_post_number":132,"image_url":"/uploads/default/3429/a20bcab33be2b6e2.png","created_at":"2014-02-26T04:55:39.741-05:00","last_posted_at":"2014-07-15T17:15:47.236-04:00","bumped":true,"bumped_at":"2014-07-15T17:15:47.236-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":3278,"like_count":305,"has_summary":true,"archetype":"regular","last_poster_username":"HAWK","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2316},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":8307}]},{"id":18063,"title":"10k+ posts causes progress bar to show single number","fancy_title":"10k+ posts causes progress bar to show single number","slug":"10k-posts-causes-progress-bar-to-show-single-number","posts_count":67,"reply_count":57,"highest_post_number":70,"image_url":"/uploads/default/_optimized/fdc/03e/3d48765fc4_690x45.png","created_at":"2014-07-25T13:31:34.474-04:00","last_posted_at":"2014-07-26T04:14:18.323-04:00","bumped":true,"bumped_at":"2014-07-26T04:20:54.730-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":335,"like_count":337,"has_summary":true,"archetype":"regular","last_poster_username":"sam","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":10886},{"extras":null,"description":"Frequent Poster","user_id":10855},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":18827,"title":"Consolidating Activity field","fancy_title":"Consolidating Activity field","slug":"consolidating-activity-field","posts_count":89,"reply_count":81,"highest_post_number":94,"image_url":"/uploads/default/33551/6483991bda61d4e5.png","created_at":"2014-08-13T18:46:09.613-04:00","last_posted_at":"2014-08-18T16:31:12.479-04:00","bumped":true,"bumped_at":"2014-08-18T16:30:13.362-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":226,"like_count":181,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":4263}]},{"id":18397,"title":"Does anyone actually like the \"Likes\" column?","fancy_title":"Does anyone actually like the “Likes” column?","slug":"does-anyone-actually-like-the-likes-column","posts_count":81,"reply_count":94,"highest_post_number":111,"image_url":null,"created_at":"2014-08-02T22:15:54.016-04:00","last_posted_at":"2014-08-25T19:37:00.313-04:00","bumped":true,"bumped_at":"2014-08-25T19:37:00.313-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":460,"like_count":191,"has_summary":true,"archetype":"regular","last_poster_username":"bbendick","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":8909},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":"latest","description":"Most Recent Poster","user_id":4500}]},{"id":13789,"title":"Badges feedback","fancy_title":"Badges feedback","slug":"badges-feedback","posts_count":101,"reply_count":74,"highest_post_number":104,"image_url":null,"created_at":"2014-03-16T20:16:29.885-04:00","last_posted_at":"2014-08-25T13:38:58.464-04:00","bumped":true,"bumped_at":"2014-08-25T13:38:58.464-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2227,"like_count":97,"has_summary":true,"archetype":"regular","last_poster_username":"cpradio","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":8300}]},{"id":13479,"title":"Topic List design experiments","fancy_title":"Topic List design experiments","slug":"topic-list-design-experiments","posts_count":90,"reply_count":70,"highest_post_number":93,"image_url":"/uploads/default/_optimized/8f2/41d/0436a3b666_689x392.png","created_at":"2014-03-06T23:41:26.312-05:00","last_posted_at":"2014-07-30T16:03:05.846-04:00","bumped":true,"bumped_at":"2014-07-30T16:03:05.846-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1532,"like_count":109,"has_summary":true,"archetype":"regular","last_poster_username":"probus","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":471},{"extras":"latest","description":"Most Recent Poster","user_id":7948}]},{"id":11911,"title":"How should we implement polls?","fancy_title":"How should we implement polls?","slug":"how-should-we-implement-polls","posts_count":70,"reply_count":51,"highest_post_number":73,"image_url":null,"created_at":"2014-01-12T21:48:03.160-05:00","last_posted_at":"2014-07-27T18:11:30.077-04:00","bumped":true,"bumped_at":"2014-07-27T18:11:30.077-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2724,"like_count":123,"has_summary":true,"archetype":"regular","last_poster_username":"meglio","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":2989}]},{"id":18524,"title":"Rename \"Dismiss Unread\" to \"Stop Tracking Topics\"","fancy_title":"Rename “Dismiss Unread” to “Stop Tracking Topics”","slug":"rename-dismiss-unread-to-stop-tracking-topics","posts_count":74,"reply_count":53,"highest_post_number":74,"image_url":null,"created_at":"2014-08-06T01:12:01.086-04:00","last_posted_at":"2014-08-12T05:47:20.750-04:00","bumped":true,"bumped_at":"2014-08-12T05:47:20.750-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":149,"like_count":103,"has_summary":true,"archetype":"regular","last_poster_username":"Dan_G","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":8493},{"extras":"latest","description":"Most Recent Poster","user_id":11455}]},{"id":10515,"title":"Flatter styling now deployed","fancy_title":"Flatter styling now deployed","slug":"flatter-styling-now-deployed","posts_count":80,"reply_count":41,"highest_post_number":80,"image_url":null,"created_at":"2013-10-20T19:36:00.465-04:00","last_posted_at":"2014-03-18T14:04:00.515-04:00","bumped":true,"bumped_at":"2014-03-18T14:04:00.515-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1790,"like_count":78,"has_summary":true,"archetype":"regular","last_poster_username":"mcwumbly","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":5707},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":4263}]},{"id":12346,"title":"What about an easier styling/theming system?","fancy_title":"What about an easier styling/theming system?","slug":"what-about-an-easier-styling-theming-system","posts_count":54,"reply_count":26,"highest_post_number":54,"image_url":null,"created_at":"2014-01-31T19:11:51.887-05:00","last_posted_at":"2014-07-01T17:42:38.425-04:00","bumped":true,"bumped_at":"2014-07-01T17:42:38.425-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1740,"like_count":130,"has_summary":true,"archetype":"regular","last_poster_username":"neil","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":5351},{"extras":"latest","description":"Most Recent Poster","user_id":2}]},{"id":18875,"title":"Notification when a moderator or admin deletes your message","fancy_title":"Notification when a moderator or admin deletes your message","slug":"notification-when-a-moderator-or-admin-deletes-your-message","posts_count":58,"reply_count":44,"highest_post_number":66,"image_url":null,"created_at":"2014-08-14T18:57:28.722-04:00","last_posted_at":"2014-08-20T12:34:26.180-04:00","bumped":true,"bumped_at":"2014-08-20T12:34:20.630-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":181,"like_count":122,"has_summary":true,"archetype":"regular","last_poster_username":"eviltrout","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":11017},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":11455},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":12257,"title":"Is \"Activity\" too ambiguous?","fancy_title":"Is “Activity” too ambiguous?","slug":"is-activity-too-ambiguous","posts_count":53,"reply_count":40,"highest_post_number":53,"image_url":"/uploads/default/_optimized/542/c04/82250e51e5_690x248.png","created_at":"2014-01-28T14:01:08.745-05:00","last_posted_at":"2014-04-13T18:25:45.492-04:00","bumped":true,"bumped_at":"2014-04-13T18:25:45.492-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":686,"like_count":103,"has_summary":true,"archetype":"regular","last_poster_username":"StevieD","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":7948},{"extras":"latest","description":"Most Recent Poster","user_id":8325}]},{"id":13099,"title":"Replacing Mailing lists: Email-In","fancy_title":"Replacing Mailing lists: Email-In","slug":"replacing-mailing-lists-email-in","posts_count":66,"reply_count":46,"highest_post_number":68,"image_url":null,"created_at":"2014-02-26T13:24:44.965-05:00","last_posted_at":"2014-07-09T18:01:21.166-04:00","bumped":true,"bumped_at":"2014-07-09T19:10:30.547-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1567,"like_count":76,"has_summary":true,"archetype":"regular","last_poster_username":"lake54","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":6060},{"extras":null,"description":"Frequent Poster","user_id":5351},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":7717}]},{"id":13045,"title":"Official Single-Sign-On for Discourse","fancy_title":"Official Single-Sign-On for Discourse","slug":"official-single-sign-on-for-discourse","posts_count":61,"reply_count":37,"highest_post_number":64,"image_url":"/uploads/default/_optimized/07c/3bf/3fa1d69ceb_690x207.png","created_at":"2014-02-25T03:30:34.321-05:00","last_posted_at":"2014-08-01T17:44:56.523-04:00","bumped":true,"bumped_at":"2014-08-07T13:27:14.684-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":13052,"like_count":74,"has_summary":true,"archetype":"regular","last_poster_username":"riking","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8873},{"extras":null,"description":"Frequent Poster","user_id":8434},{"extras":null,"description":"Frequent Poster","user_id":8437},{"extras":"latest","description":"Most Recent Poster","user_id":6626}]},{"id":19099,"title":"Should search prioritize recent topics over older topics?","fancy_title":"Should search prioritize recent topics over older topics?","slug":"should-search-prioritize-recent-topics-over-older-topics","posts_count":55,"reply_count":48,"highest_post_number":58,"image_url":"/uploads/default/33840/49e57c5a286a2131.png","created_at":"2014-08-20T12:00:12.737-04:00","last_posted_at":"2014-08-22T17:46:34.073-04:00","bumped":true,"bumped_at":"2014-08-22T17:46:20.038-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":149,"like_count":83,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":9147},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":9653},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":18879,"title":"Further simplifying the columns: quality score > view count","fancy_title":"Further simplifying the columns: quality score > view count","slug":"further-simplifying-the-columns-quality-score-view-count","posts_count":44,"reply_count":32,"highest_post_number":44,"image_url":"/uploads/default/33627/b40ad535eba2b7a3.png","created_at":"2014-08-14T21:19:24.118-04:00","last_posted_at":"2014-08-22T14:25:12.092-04:00","bumped":true,"bumped_at":"2014-08-22T15:21:09.995-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":560,"like_count":95,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":8909},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":11160},{"extras":null,"description":"Frequent Poster","user_id":11589},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13847,"title":"Allowing SSL for your Discourse Docker setup","fancy_title":"Allowing SSL for your Discourse Docker setup","slug":"allowing-ssl-for-your-discourse-docker-setup","posts_count":47,"reply_count":59,"highest_post_number":58,"image_url":null,"created_at":"2014-03-18T19:45:27.517-04:00","last_posted_at":"2014-08-28T04:03:20.851-04:00","bumped":true,"bumped_at":"2014-08-28T04:17:17.852-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":6927,"like_count":87,"has_summary":false,"archetype":"regular","last_poster_username":"cosban","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6607},{"extras":null,"description":"Frequent Poster","user_id":10816},{"extras":null,"description":"Frequent Poster","user_id":8222},{"extras":"latest","description":"Most Recent Poster","user_id":11780}]},{"id":9621,"title":"Free Hosted Option?","fancy_title":"Free Hosted Option?","slug":"free-hosted-option","posts_count":43,"reply_count":33,"highest_post_number":43,"image_url":null,"created_at":"2013-09-05T16:22:20.790-04:00","last_posted_at":"2014-04-08T00:24:46.320-04:00","bumped":true,"bumped_at":"2014-04-08T00:24:46.320-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1844,"like_count":93,"has_summary":false,"archetype":"regular","last_poster_username":"ChaoticLoki","category_id":8,"posters":[{"extras":null,"description":"Original Poster","user_id":6819},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":6268}]},{"id":18873,"title":"Alternative to blue colors for coldmapping","fancy_title":"Alternative to blue colors for coldmapping","slug":"alternative-to-blue-colors-for-coldmapping","posts_count":47,"reply_count":23,"highest_post_number":47,"image_url":null,"created_at":"2014-08-14T18:33:21.844-04:00","last_posted_at":"2014-08-15T10:46:08.175-04:00","bumped":true,"bumped_at":"2014-08-15T10:46:08.175-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":122,"like_count":84,"has_summary":false,"archetype":"regular","last_poster_username":"boomzilla","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":10855},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":8},{"extras":"latest","description":"Most Recent Poster","user_id":11160}]},{"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":57,"reply_count":36,"highest_post_number":58,"image_url":"/uploads/default/_optimized/66d/cf0/d69e6709fe_496x500.PNG","created_at":"2014-01-05T14:28:58.037-05:00","last_posted_at":"2014-08-08T07:55:23.454-04:00","bumped":true,"bumped_at":"2014-08-08T07:55:23.454-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":2085,"like_count":62,"has_summary":true,"archetype":"regular","last_poster_username":"michaeld","category_id":22,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":8343},{"extras":null,"description":"Frequent Poster","user_id":9536},{"extras":null,"description":"Frequent Poster","user_id":3415},{"extras":null,"description":"Frequent Poster","user_id":9093}]},{"id":13485,"title":"What do you like/dislike about the NodeBB design?","fancy_title":"What do you like/dislike about the NodeBB design?","slug":"what-do-you-like-dislike-about-the-nodebb-design","posts_count":52,"reply_count":28,"highest_post_number":53,"image_url":null,"created_at":"2014-03-07T03:38:14.227-05:00","last_posted_at":"2014-08-20T15:19:00.969-04:00","bumped":true,"bumped_at":"2014-08-19T20:22:04.123-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1495,"like_count":68,"has_summary":true,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8364},{"extras":null,"description":"Frequent Poster","user_id":5013},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":2770}]},{"id":17454,"title":"Spambots from Tor exit points keep taking over my forum","fancy_title":"Spambots from Tor exit points keep taking over my forum","slug":"spambots-from-tor-exit-points-keep-taking-over-my-forum","posts_count":46,"reply_count":32,"highest_post_number":46,"image_url":"/uploads/default/_optimized/b0d/ab3/20401b97ce_690x454.png","created_at":"2014-07-11T03:20:49.433-04:00","last_posted_at":"2014-08-19T18:09:10.799-04:00","bumped":true,"bumped_at":"2014-08-19T18:02:57.107-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1243,"like_count":78,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":6,"posters":[{"extras":null,"description":"Original Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":10778},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":19317,"title":"Introducing Discourse 1.0","fancy_title":"Introducing Discourse 1.0","slug":"introducing-discourse-1-0","posts_count":36,"reply_count":3,"highest_post_number":36,"image_url":null,"created_at":"2014-08-26T15:43:01.370-04:00","last_posted_at":"2014-08-28T13:16:42.484-04:00","bumped":true,"bumped_at":"2014-08-28T13:16:42.484-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":709,"like_count":103,"has_summary":false,"archetype":"regular","last_poster_username":"youderian","category_id":13,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5399},{"extras":null,"description":"Frequent Poster","user_id":11747},{"extras":null,"description":"Frequent Poster","user_id":11762},{"extras":"latest","description":"Most Recent Poster","user_id":10856}]},{"id":13184,"title":"Discourse General Polish prior to V1","fancy_title":"Discourse General Polish prior to V1","slug":"discourse-general-polish-prior-to-v1","posts_count":44,"reply_count":30,"highest_post_number":48,"image_url":"/plugins/emoji/images/arrow_left.png","created_at":"2014-02-27T19:10:41.496-05:00","last_posted_at":"2014-06-08T03:32:02.009-04:00","bumped":true,"bumped_at":"2014-06-06T03:30:23.984-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":1864,"like_count":77,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":8222},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":17694,"title":"Release schedule post version 1.0","fancy_title":"Release schedule post version 1.0","slug":"release-schedule-post-version-1-0","posts_count":44,"reply_count":35,"highest_post_number":44,"image_url":null,"created_at":"2014-07-17T19:45:21.459-04:00","last_posted_at":"2014-07-23T03:51:03.564-04:00","bumped":true,"bumped_at":"2014-07-29T17:20:06.942-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":539,"like_count":70,"has_summary":false,"archetype":"regular","last_poster_username":"probus","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":10098},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":"latest","description":"Most Recent Poster","user_id":7948}]},{"id":18533,"title":"My latest forum... but it's not running Discourse - here's why","fancy_title":"My latest forum… but it’s not running Discourse - here’s why","slug":"my-latest-forum-but-its-not-running-discourse-heres-why","posts_count":37,"reply_count":27,"highest_post_number":38,"image_url":null,"created_at":"2014-08-06T06:01:35.608-04:00","last_posted_at":"2014-08-15T13:27:13.386-04:00","bumped":true,"bumped_at":"2014-08-15T13:27:13.386-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1185,"like_count":73,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":704},{"extras":null,"description":"Frequent Poster","user_id":10920},{"extras":null,"description":"Frequent Poster","user_id":6613},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13287,"title":"Chinese search issues","fancy_title":"Chinese search issues","slug":"chinese-search-issues","posts_count":60,"reply_count":41,"highest_post_number":60,"image_url":"https://f.cloud.github.com/assets/6783175/2296397/3dcabcf8-a09e-11e3-9f5a-2a94d981fced.png","created_at":"2014-03-01T10:12:14.845-05:00","last_posted_at":"2014-07-10T17:03:25.796-04:00","bumped":true,"bumped_at":"2014-07-10T17:03:25.796-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":947,"like_count":25,"has_summary":true,"archetype":"regular","last_poster_username":"sam","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":8820},{"extras":null,"description":"Frequent Poster","user_id":6746},{"extras":null,"description":"Frequent Poster","user_id":9909},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":17727,"title":"Compliance with EU Cookie Law","fancy_title":"Compliance with EU Cookie Law","slug":"compliance-with-eu-cookie-law","posts_count":46,"reply_count":32,"highest_post_number":46,"image_url":null,"created_at":"2014-07-18T17:39:38.499-04:00","last_posted_at":"2014-07-26T18:01:33.751-04:00","bumped":true,"bumped_at":"2014-07-26T18:01:33.751-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":836,"like_count":48,"has_summary":false,"archetype":"regular","last_poster_username":"node","category_id":6,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":11003},{"extras":null,"description":"Frequent Poster","user_id":11017},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":9536}]},{"id":15336,"title":"Switch from Gravatar to HTML/CSS letters for no-avatar users","fancy_title":"Switch from Gravatar to HTML/CSS letters for no-avatar users","slug":"switch-from-gravatar-to-html-css-letters-for-no-avatar-users","posts_count":39,"reply_count":25,"highest_post_number":39,"image_url":"/uploads/default/_optimized/d29/bc1/25fa89ae0a_415x500.png","created_at":"2014-05-05T18:46:02.221-04:00","last_posted_at":"2014-05-28T18:07:12.448-04:00","bumped":true,"bumped_at":"2014-05-28T18:07:09.701-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":1011,"like_count":63,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":26,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":8571},{"extras":null,"description":"Frequent Poster","user_id":8344}]},{"id":12957,"title":"Discourse for iOS","fancy_title":"Discourse for iOS","slug":"discourse-for-ios","posts_count":43,"reply_count":24,"highest_post_number":43,"image_url":"http://a4.mzstatic.com/us/r30/Purple/v4/8d/85/93/8d859353-625c-8abc-5c00-36be5f293709/mzl.luwjaamb.png","created_at":"2014-02-21T20:37:44.606-05:00","last_posted_at":"2014-08-20T15:09:19.767-04:00","bumped":true,"bumped_at":"2014-08-20T15:09:19.767-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1082,"like_count":48,"has_summary":false,"archetype":"regular","last_poster_username":"erlend_sh","category_id":5,"posters":[{"extras":null,"description":"Original Poster","user_id":8399},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":10949},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":5351}]},{"id":14973,"title":"Symbol for like - why is it a heart?","fancy_title":"Symbol for like - why is it a heart?","slug":"symbol-for-like-why-is-it-a-heart","posts_count":29,"reply_count":14,"highest_post_number":29,"image_url":null,"created_at":"2014-04-22T12:24:22.822-04:00","last_posted_at":"2014-05-08T17:41:27.803-04:00","bumped":true,"bumped_at":"2014-05-08T17:41:27.803-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1421,"like_count":73,"has_summary":false,"archetype":"regular","last_poster_username":"Frank","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":9664},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":8085},{"extras":"latest","description":"Most Recent Poster","user_id":9931}]},{"id":16875,"title":"Options to disable hijack of CMD+F / CTRL+F and \"/\" keys for search?","fancy_title":"Options to disable hijack of CMD+F / CTRL+F and “/” keys for search?","slug":"options-to-disable-hijack-of-cmd-f-ctrl-f-and-keys-for-search","posts_count":44,"reply_count":36,"highest_post_number":44,"image_url":null,"created_at":"2014-06-25T17:04:48.413-04:00","last_posted_at":"2014-08-25T04:01:38.132-04:00","bumped":true,"bumped_at":"2014-08-25T04:01:38.132-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":541,"like_count":41,"has_summary":false,"archetype":"regular","last_poster_username":"RabidFX","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":10470},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8300},{"extras":"latest","description":"Most Recent Poster","user_id":10548}]},{"id":9975,"title":"Translators We Want You!","fancy_title":"Translators We Want You!","slug":"translators-we-want-you","posts_count":50,"reply_count":28,"highest_post_number":50,"image_url":null,"created_at":"2013-09-23T13:47:39.521-04:00","last_posted_at":"2014-03-16T16:21:13.891-04:00","bumped":true,"bumped_at":"2014-03-16T16:21:13.891-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1262,"like_count":26,"has_summary":true,"archetype":"regular","last_poster_username":"Torrelles","category_id":27,"posters":[{"extras":null,"description":"Original Poster","user_id":4983},{"extras":null,"description":"Frequent Poster","user_id":7074},{"extras":null,"description":"Frequent Poster","user_id":7502},{"extras":null,"description":"Frequent Poster","user_id":5609},{"extras":"latest","description":"Most Recent Poster","user_id":8059}]},{"id":12112,"title":"The system user needs a cool avatar","fancy_title":"The system user needs a cool avatar","slug":"the-system-user-needs-a-cool-avatar","posts_count":35,"reply_count":24,"highest_post_number":35,"image_url":"/uploads/default/31460/c596ef65a9d0533c.png","created_at":"2014-01-21T22:26:01.574-05:00","last_posted_at":"2014-01-31T16:54:22.261-05:00","bumped":true,"bumped_at":"2014-01-31T16:54:22.261-05:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":848,"like_count":55,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":8105},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":11718,"title":"Reply button while logged out","fancy_title":"Reply button while logged out","slug":"reply-button-while-logged-out","posts_count":46,"reply_count":42,"highest_post_number":46,"image_url":null,"created_at":"2014-01-02T17:11:14.130-05:00","last_posted_at":"2014-04-05T10:20:11.921-04:00","bumped":true,"bumped_at":"2014-04-05T10:20:11.921-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":830,"like_count":32,"has_summary":false,"archetype":"regular","last_poster_username":"apere006","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":8072},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":9497},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":471}]},{"id":18698,"title":"Site setting for sending analytics data to Discourse.org","fancy_title":"Site setting for sending analytics data to Discourse.org","slug":"site-setting-for-sending-analytics-data-to-discourse-org","posts_count":27,"reply_count":18,"highest_post_number":27,"image_url":null,"created_at":"2014-08-10T11:47:04.016-04:00","last_posted_at":"2014-08-11T15:36:21.664-04:00","bumped":true,"bumped_at":"2014-08-11T15:36:04.020-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":true,"archived":false,"views":135,"like_count":72,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":6548},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":17443,"title":"Can I Keep Nofollow for All User Links, Including from Trust Level 3?","fancy_title":"Can I Keep Nofollow for All User Links, Including from Trust Level 3?","slug":"can-i-keep-nofollow-for-all-user-links-including-from-trust-level-3","posts_count":40,"reply_count":30,"highest_post_number":41,"image_url":null,"created_at":"2014-07-10T22:06:49.357-04:00","last_posted_at":"2014-07-14T19:20:37.014-04:00","bumped":true,"bumped_at":"2014-07-14T19:20:37.014-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":237,"like_count":42,"has_summary":false,"archetype":"regular","last_poster_username":"cpradio","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5017},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":8300}]},{"id":18821,"title":"Suggestion: # of likes in a topic in the tool tip","fancy_title":"Suggestion: # of likes in a topic in the tool tip","slug":"suggestion-of-likes-in-a-topic-in-the-tool-tip","posts_count":27,"reply_count":22,"highest_post_number":27,"image_url":null,"created_at":"2014-08-13T15:23:46.745-04:00","last_posted_at":"2014-08-15T07:40:57.684-04:00","bumped":true,"bumped_at":"2014-08-15T07:40:57.684-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":133,"like_count":68,"has_summary":false,"archetype":"regular","last_poster_username":"boomzilla","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":11163},{"extras":null,"description":"Frequent Poster","user_id":11265},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":8493},{"extras":"latest","description":"Most Recent Poster","user_id":11160}]},{"id":9741,"title":"Difference between Reddit and Discourse","fancy_title":"Difference between Reddit and Discourse","slug":"difference-between-reddit-and-discourse","posts_count":42,"reply_count":32,"highest_post_number":42,"image_url":null,"created_at":"2013-09-11T22:17:39.971-04:00","last_posted_at":"2013-09-17T19:01:36.139-04:00","bumped":true,"bumped_at":"2013-09-17T19:01:36.139-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":3303,"like_count":35,"has_summary":false,"archetype":"regular","last_poster_username":"anotherchris","category_id":3,"posters":[{"extras":null,"description":"Original Poster","user_id":5105},{"extras":null,"description":"Frequent Poster","user_id":1353},{"extras":null,"description":"Frequent Poster","user_id":5851},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":2520}]},{"id":12156,"title":"Beginners Guide to Deploy Discourse on DigitalOcean using Docker","fancy_title":"Beginners Guide to Deploy Discourse on DigitalOcean using Docker","slug":"beginners-guide-to-deploy-discourse-on-digital-ocean-using-docker","posts_count":28,"reply_count":157,"highest_post_number":219,"image_url":"http://www.discourse.org/images/install/droplet-step-1.png","created_at":"2014-01-23T14:58:17.918-05:00","last_posted_at":"2014-08-26T10:06:25.833-04:00","bumped":true,"bumped_at":"2014-08-26T10:06:25.833-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":10112,"like_count":63,"has_summary":false,"archetype":"regular","last_poster_username":"cawas","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":8222},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":8364},{"extras":"latest","description":"Most Recent Poster","user_id":5249}]},{"id":12522,"title":"Permission Changes (moderators have less)","fancy_title":"Permission Changes (moderators have less)","slug":"permission-changes-moderators-have-less","posts_count":42,"reply_count":30,"highest_post_number":43,"image_url":null,"created_at":"2014-02-06T22:34:05.332-05:00","last_posted_at":"2014-08-01T12:26:40.440-04:00","bumped":true,"bumped_at":"2014-08-01T12:26:40.440-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1806,"like_count":37,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":17,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":5559},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":null,"description":"Frequent Poster","user_id":4457},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":10291,"title":"CAS sso auth plugin","fancy_title":"CAS sso auth plugin","slug":"cas-sso-auth-plugin","posts_count":48,"reply_count":32,"highest_post_number":51,"image_url":null,"created_at":"2013-10-09T17:01:21.524-04:00","last_posted_at":"2014-08-27T16:08:25.417-04:00","bumped":true,"bumped_at":"2014-08-27T16:08:25.417-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1433,"like_count":20,"has_summary":false,"archetype":"regular","last_poster_username":"eriko","category_id":22,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5160},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4220},{"extras":null,"description":"Frequent Poster","user_id":3704},{"extras":null,"description":"Frequent Poster","user_id":32}]},{"id":16877,"title":"Discourse V1.0 Next Month","fancy_title":"Discourse V1.0 Next Month","slug":"discourse-v1-0-next-month","posts_count":25,"reply_count":11,"highest_post_number":26,"image_url":null,"created_at":"2014-06-25T18:54:32.020-04:00","last_posted_at":"2014-08-14T13:07:09.405-04:00","bumped":true,"bumped_at":"2014-08-14T13:07:09.405-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1113,"like_count":65,"has_summary":false,"archetype":"regular","last_poster_username":"Dan_G","category_id":13,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":8810},{"extras":null,"description":"Frequent Poster","user_id":8944},{"extras":null,"description":"Frequent Poster","user_id":10920},{"extras":"latest","description":"Most Recent Poster","user_id":11455}]},{"id":18257,"title":"Move the new/unread counters to the first column in topic list","fancy_title":"Move the new/unread counters to the first column in topic list","slug":"move-the-new-unread-counters-to-the-first-column-in-topic-list","posts_count":32,"reply_count":25,"highest_post_number":32,"image_url":null,"created_at":"2014-07-30T02:33:42.679-04:00","last_posted_at":"2014-08-01T12:33:11.694-04:00","bumped":true,"bumped_at":"2014-08-01T12:33:11.694-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":217,"like_count":51,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":7948},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":13249,"title":"Syncing the editor viewport scroll","fancy_title":"Syncing the editor viewport scroll","slug":"syncing-the-editor-viewport-scroll","posts_count":35,"reply_count":15,"highest_post_number":35,"image_url":null,"created_at":"2014-02-28T19:03:57.708-05:00","last_posted_at":"2014-04-06T21:04:59.528-04:00","bumped":true,"bumped_at":"2014-04-06T21:04:59.528-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":980,"like_count":44,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6808},{"extras":null,"description":"Frequent Poster","user_id":8933},{"extras":null,"description":"Frequent Poster","user_id":19},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":9711,"title":"Now testing: mobile (small screen) layouts on key pages","fancy_title":"Now testing: mobile (small screen) layouts on key pages","slug":"now-testing-mobile-small-screen-layouts-on-key-pages","posts_count":43,"reply_count":31,"highest_post_number":51,"image_url":"/uploads/meta_discourse/1787/beb2b60fba4c46c3.png","created_at":"2013-09-10T19:45:51.532-04:00","last_posted_at":"2014-02-05T02:03:24.974-05:00","bumped":true,"bumped_at":"2014-02-05T13:45:55.088-05:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":1635,"like_count":27,"has_summary":false,"archetype":"regular","last_poster_username":"iainb","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2},{"extras":null,"description":"Frequent Poster","user_id":8},{"extras":null,"description":"Frequent Poster","user_id":7604},{"extras":"latest","description":"Most Recent Poster","user_id":1783}]},{"id":15048,"title":"Linking a Discourse User db with a Mumble server (Murmur)","fancy_title":"Linking a Discourse User db with a Mumble server (Murmur)","slug":"linking-a-discourse-user-db-with-a-mumble-server-murmur","posts_count":48,"reply_count":40,"highest_post_number":48,"image_url":null,"created_at":"2014-04-24T18:30:17.568-04:00","last_posted_at":"2014-05-30T20:43:13.387-04:00","bumped":true,"bumped_at":"2014-05-30T20:43:13.387-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":625,"like_count":17,"has_summary":false,"archetype":"regular","last_poster_username":"Vocino","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":9371},{"extras":null,"description":"Frequent Poster","user_id":9775},{"extras":null,"description":"Frequent Poster","user_id":4457},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6613}]},{"id":17945,"title":"Unread/new badge style?","fancy_title":"Unread/new badge style?","slug":"unread-new-badge-style","posts_count":35,"reply_count":23,"highest_post_number":35,"image_url":"/uploads/default/_optimized/b61/a61/3508713cc1_690x202.png","created_at":"2014-07-23T10:49:18.864-04:00","last_posted_at":"2014-07-28T13:52:16.773-04:00","bumped":true,"bumped_at":"2014-07-28T13:52:16.773-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":279,"like_count":43,"has_summary":false,"archetype":"regular","last_poster_username":"Mittineague","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2770},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":8617}]},{"id":16803,"title":"Auto-hide persistent fixed header on scroll","fancy_title":"Auto-hide persistent fixed header on scroll","slug":"auto-hide-persistent-fixed-header-on-scroll","posts_count":39,"reply_count":27,"highest_post_number":39,"image_url":null,"created_at":"2014-06-23T13:25:32.523-04:00","last_posted_at":"2014-07-07T10:45:40.399-04:00","bumped":true,"bumped_at":"2014-07-07T10:45:40.399-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":792,"like_count":34,"has_summary":false,"archetype":"regular","last_poster_username":"mcwumbly","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":10632},{"extras":null,"description":"Frequent Poster","user_id":438},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2770},{"extras":"latest","description":"Most Recent Poster","user_id":4263}]},{"id":15858,"title":"Configuring Google OAuth2 login for Discourse","fancy_title":"Configuring Google OAuth2 login for Discourse","slug":"configuring-google-oauth2-login-for-discourse","posts_count":36,"reply_count":24,"highest_post_number":40,"image_url":"/uploads/default/_optimized/9ae/174/5a30a33f56_690x399.png","created_at":"2014-05-21T18:46:55.403-04:00","last_posted_at":"2014-08-17T15:30:40.593-04:00","bumped":true,"bumped_at":"2014-08-17T15:29:45.558-04:00","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"views":5257,"like_count":41,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":2},{"extras":null,"description":"Frequent Poster","user_id":9726},{"extras":null,"description":"Frequent Poster","user_id":3675},{"extras":null,"description":"Frequent Poster","user_id":6626},{"extras":"latest","description":"Most Recent Poster","user_id":32}]}]}}}; diff --git a/test/javascripts/fixtures/user_fixtures.js.es6 b/test/javascripts/fixtures/user_fixtures.js.es6 index a84974b695..7a24b9b546 100644 --- a/test/javascripts/fixtures/user_fixtures.js.es6 +++ b/test/javascripts/fixtures/user_fixtures.js.es6 @@ -1,6 +1,6 @@ /*jshint maxlen:10000000 */ export default { "/users/eviltrout.json": {"user_badges":[{"id":5870,"granted_at":"2014-05-16T02:39:38.388Z","badge_id":4,"user_id":19,"granted_by_id":-1},{"id":40673,"granted_at":"2014-03-31T14:23:18.060Z","post_id":7241,"post_number":19,"badge_id":23,"user_id":19,"granted_by_id":-1,"topic_id":3153},{"id":5868,"granted_at":"2014-05-16T02:39:38.380Z","badge_id":3,"user_id":19,"granted_by_id":-1}],"badges":[{"id":4,"name":"Leader","description":null,"grant_count":7,"allow_title":true,"multiple_grant":false,"icon":"fa-user","image":null,"listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":1},{"id":23,"name":"Great Share","description":null,"grant_count":14,"allow_title":false,"multiple_grant":true,"icon":"fa-certificate","image":null,"listable":true,"enabled":true,"badge_grouping_id":2,"system":true,"badge_type_id":1},{"id":3,"name":"Regular","description":null,"grant_count":30,"allow_title":true,"multiple_grant":false,"icon":"fa-user","image":null,"listable":true,"enabled":true,"badge_grouping_id":4,"system":true,"badge_type_id":2}],"badge_types":[{"id":1,"name":"Gold","sort_order":9},{"id":2,"name":"Silver","sort_order":8},{"id":3,"name":"Bronze","sort_order":7}],"users":[{"id":19,"username":"eviltrout","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eviltrout/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png"},{"id":-1,"username":"system","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/system/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png"}],"topics":[{"id":3153,"title":"Is it better for Discourse to use JavaScript or CoffeeScript?","fancy_title":"Is it better for Discourse to use JavaScript or CoffeeScript?","slug":"is-it-better-for-discourse-to-use-javascript-or-coffeescript","posts_count":56}],"user":{"id":19,"username":"eviltrout","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/eviltrout/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png","name":"Robin Ward","email":"robin.ward@gmail.com","last_posted_at":"2015-05-07T15:23:35.074Z","last_seen_at":"2015-05-13T14:34:23.188Z","bio_raw":"Co-founder of Discourse. Previously, I created Forumwarz. Follow me on Twitter.","bio_cooked":"

    Co-founder of Discourse. Previously, I created Forumwarz. Follow me on Twitter.

    ","created_at":"2013-02-03T15:19:22.704Z","website":"http://eviltrout.com","location":"Toronto","can_edit":false,"can_edit_username":true,"can_edit_email":true,"can_edit_name":true,"stats":[{"action_type":13,"count":342,"id":null},{"action_type":12,"count":109,"id":null},{"action_type":4,"count":27,"id":null},{"action_type":5,"count":1607,"id":null},{"action_type":6,"count":771,"id":null},{"action_type":1,"count":333,"id":null},{"action_type":2,"count":2671,"id":null},{"action_type":7,"count":949,"id":null},{"action_type":9,"count":42,"id":null},{"action_type":3,"count":8,"id":null},{"action_type":11,"count":20,"id":null}],"can_send_private_messages":true,"can_send_private_message_to_user":false,"bio_excerpt":"Co-founder of Discourse. Previously, I created Forumwarz. Follow me on Twitter.","trust_level":4,"moderator":true,"admin":true,"title":"co-founder","badge_count":23,"notification_count":3244,"has_title_badges":true,"custom_fields":{},"user_fields":{"1":"33"},"pending_count":0,"post_count":1987,"can_be_deleted":false,"can_delete_all_posts":false,"locale":"","email_digests":true,"email_private_messages":true,"email_direct":true,"email_always":true,"digest_after_days":7,"mailing_list_mode":false,"auto_track_topics_after_msecs":60000,"new_topic_duration_minutes":1440,"external_links_in_new_tab":false,"dynamic_favicon":true,"enable_quoting":true,"muted_category_ids":[],"tracked_category_ids":[],"watched_category_ids":[3],"private_messages_stats":{"all":101,"mine":13,"unread":3},"disable_jump_reply":false,"gravatar_avatar_upload_id":5275,"custom_avatar_upload_id":1573,"card_image_badge":"https://meta-discourse.global.ssl.fastly.net/uploads/default/36220/15b19c80dd99d5a5.png","card_image_badge_id":120,"muted_usernames":[],"invited_by":{"id":1,"username":"sam","uploaded_avatar_id":null,"avatar_template":"/letter_avatar/sam/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png"},"custom_groups":[{"id":44,"automatic":false,"name":"ubuntu","user_count":11,"alias_level":0,"visible":true,"automatic_membership_email_domains":null,"automatic_membership_retroactive":false,"primary_group":false,"title":null},{"id":47,"automatic":false,"name":"discourse","user_count":7,"alias_level":0,"visible":true,"automatic_membership_email_domains":null,"automatic_membership_retroactive":false,"primary_group":false,"title":null}],"featured_user_badge_ids":[5870,40673,5868],"card_badge":{"id":120,"name":"Garbage Man","description":"This Discourse developer successfully called something \"garbage!\"","grant_count":3,"allow_title":false,"multiple_grant":false,"icon":"https://meta-discourse.global.ssl.fastly.net/uploads/default/36220/15b19c80dd99d5a5.png","image":"https://meta-discourse.global.ssl.fastly.net/uploads/default/36220/15b19c80dd99d5a5.png","listable":false,"enabled":false,"badge_grouping_id":8,"system":false,"badge_type_id":3}}}, -"/user_actions.json": {"user_actions":[{"action_type":7,"created_at":"2014-01-16T14:13:05Z","excerpt":"So again, \n\nWhat is the problem?\n\nI need to check user_trust_level , i get the 'username' from a form via ajax, i need to check what level he is on discourse \n\nAlso, if possible, i would like to get other details as well, like email address etc. \n\nI took a look at : https://github.com/discourse/dis…","avatar_template":"//www.gravatar.com/avatar/bdab7e61b3191e483492fd680f563fed.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/bdab7e61b3191e483492fd680f563fed.png?s={size}&r=pg&d=identicon","slug":"how-to-check-the-user-level-via-ajax","topic_id":11993,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"Abhishek_Gupta","name":"Abhishek Gupta","user_id":8021,"acting_username":"Abhishek_Gupta","acting_name":"Abhishek Gupta","acting_user_id":8021,"title":"How to check the user level via ajax?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-15T16:53:49Z","excerpt":"A good fix would be to have the ERB template do an if statement. We'd happily accept a PR that did this if you feel up to it: \n\n <% if SiteSetting.logo_url.present? %>\n display logo html\n<% else %>\n display title html\n<% end %>","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"users-activate-account-pulling-blank-logo-instead-of-defaulting-to-h2","topic_id":10911,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"/users/activate-account pulling blank logo instead of defaulting to h2","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-15T15:21:37Z","excerpt":"A good fix would be to have the ERB template do an if statement. We'd happily accept a PR that did this if you feel up to it: \n\n <% if SiteSetting.logo_url.present? %>\n display logo html\n<% else %>\n display title html\n<% end %>","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"users-activate-account-pulling-blank-logo-instead-of-defaulting-to-h2","topic_id":10911,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"/users/activate-account pulling blank logo instead of defaulting to h2","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-15T12:22:12Z","excerpt":"OK - i see what you mean. From the piwik code I should add: \n\n_paq.push(["setDocumentTitle", document.domain + "/" + document.title]);\n\n? \n\nUnfortunately I have had to give up on Piwik for now because I have switched the forum to SSL on a free cert and have used up the free subdomain for the forum. …","avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":26,"reply_to_post_number":25,"username":"citkane","name":"Michael Jonker","user_id":7604,"acting_username":"citkane","acting_name":"Michael Jonker","acting_user_id":7604,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T11:16:36Z","excerpt":"@eviltrout recently added support for multiple API keys [wink] \n\n[]","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"allow-for-multiple-api-keys","topic_id":7444,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Allow for multiple API Keys","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T10:58:46Z","excerpt":"@eviltrout added a tooltip when you click on the user's avatar which allows you to show the posts made by that user \n\n[image]","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"to-group-posts-by-a-user","topic_id":7412,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":3,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"To group posts by a user","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T10:36:15Z","excerpt":"@eviltrout implemented per-user API key a while ago [wink] \n\n [image]\nTopics_-_Discourse_Meta-5.png884x339 29.6 KB\n","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"auth-using-rest-api","topic_id":5937,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Auth using REST API?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T09:55:17Z","excerpt":"@eviltrout has recently introduced this feature and has even blogged about it: \n\n \n \n \n \n eviltrout.com\n \n \n \n \n \n Hiding Offscreen Content in Ember.js - Evil Trout's Blog","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"infinite-scrolling-reusing-dom-nodes","topic_id":5186,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Infinite scrolling: Reusing DOM nodes","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-15T00:54:32Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:59:51Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"znation","acting_name":"znation","acting_user_id":8163,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:46:50Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T21:43:28Z","excerpt":"Thanks for your help @eviltrout! I will consider making that change and sending a pull request. I may not get to it for a while. \n\nI am embedding Discourse on another site and it is mostly going well. I have indeed been using your blog for inspiration.","avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"znation","name":"znation","user_id":8163,"acting_username":"znation","acting_name":"znation","acting_user_id":8163,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:21:52Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T21:03:07Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T20:42:51Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T20:29:23Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T19:20:28Z","excerpt":"Perhaps the ['trackpageView'] is not the correct API call? We can probably send more information across such as the URL.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":25,"reply_to_post_number":24,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T19:19:46Z","excerpt":"Nope but I bet you can find one!","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":3,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T18:37:05Z","excerpt":"I'd be glad to write a pull request to take use there. Is there a specific part of their documentation you have in mind?","avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"watchmanmonitor","name":"Watchman Monitoring","user_id":8085,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T16:04:28Z","excerpt":"Thanks @eviltrout , the code in the 'bottom of pages' now reads: \n\n<script type="text/javascript">\nDiscourse.PageTracker.current().on('change', function() {\n console.log('tracked!')\n _paq.push(['trackPageView']);\n});\n</script>\n\nThe console is logging 'tracked!' and piwik is logging for each page c…","avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":23,"reply_to_post_number":22,"username":"citkane","name":"Michael Jonker","user_id":7604,"acting_username":"citkane","acting_name":"Michael Jonker","acting_user_id":7604,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T15:58:27Z","excerpt":"This topic is now archived. It is frozen and cannot be changed in any way.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"regression-cannot-sort-topic-list","topic_id":11944,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Regression: Cannot sort topic list","deleted":false,"hidden":false,"moderator_action":true,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T15:26:57Z","excerpt":"I do think that leading them into the official rails documentation at that point is not a bad idea. Like "congratulations, everything is ready but now you'll need to understand the platform we built it in to be productive."","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T08:28:00Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-14T00:21:26Z","excerpt":"In pull request 1821, @eviltrout asked: \n\n "About rails s: I wouldn't be against adding it but at what point do we stop holding their hand and expect them to know how rails works? I'm sure rails documentation could do a better job than us. Actually maybe we should just link to that? \n\nWhat point to …","avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"watchmanmonitor","name":"Watchman Monitoring","user_id":8085,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-13T21:58:28Z","excerpt":"It looks uneeded, but you need to review a fair amount of code to confirm it is not needed. \n\nI am going to keep it for now cause its safer under some weird edge conditions.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"ruby-question-about-use-of-klass-self-in-the-site-customization-rb","topic_id":11889,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Ruby question about use of klass=self in the site_customization.rb","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T21:11:32Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-13T21:10:57Z","excerpt":"Having a look, the fix is a bit scary imho, we should fix the root issue.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":11,"reply_to_post_number":10,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T20:50:34Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//localhost:3000/uploads/default/avatars/527/614/d16e1504d9/{size}.jpg","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"trident","acting_name":"Ben T","acting_user_id":5707,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T20:44:56Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T20:40:21Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T19:52:04Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T19:01:19Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T18:50:14Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T18:47:33Z","excerpt":"I am pretty sure that the denizens of SO are correct and the variable is unneeded. @sam can confirm but it seems like it was once needed for something that has since been removed and the variable declaration was left intact.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"ruby-question-about-use-of-klass-self-in-the-site-customization-rb","topic_id":11889,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Ruby question about use of klass=self in the site_customization.rb","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T18:45:41Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T17:19:08Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T16:41:31Z","excerpt":"I'd love to see API support. @sam and @eviltrout, I can facilitate an intro to the piwik guys if you want—I've written about them before and they're typically super-responsive. Because I know you guys are totally hunting for new stuff to do [wink]","avatar_template":"//localhost:3000/uploads/default/avatars/95a/06d/c337428568/{size}.png","acting_avatar_template":"//localhost:3000/uploads/default/avatars/95a/06d/c337428568/{size}.png","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":20,"reply_to_post_number":null,"username":"Lee_Ars","name":"Lee_Ars","user_id":4457,"acting_username":"Lee_Ars","acting_name":"Lee_Ars","acting_user_id":4457,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T16:15:51Z","excerpt":"The code looks okay but it's hard to debug this way. \n\nOne thing you could do is add a: console.log('tracked!') just before line 8. Then open a developer console and see if the javascript is running properly.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T15:10:41Z","excerpt":"This is really interesting. I'd like to hear your findings.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"focus-events-track-which-window-is-the-last-active-instance-of-a-forum-edit","topic_id":11872,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":9,"reply_to_post_number":8,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Focus events: Track which window is the last active instance of a forum Edit","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T15:02:45Z","excerpt":"The code looks okay but it's hard to debug this way. \n\nOne thing you could do is add a: console.log('tracked!') just before line 8. Then open a developer console and see if the javascript is running properly.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T14:53:13Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T06:27:26Z","excerpt":"Can this be archived @eviltrout?","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"search-not-working-for-staff-users","topic_id":11371,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":13,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Search not working for Staff users","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T05:32:46Z","excerpt":"When you navigate to another topic using the "suggested topics" area we are not registering a page view with Google. \n\n@eviltrout perhaps we should do this from discourse location instead of application controller?","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"google-analytics-is-not-registering-page-views","topic_id":11914,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Google analytics is not registering page views","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T02:50:25Z","excerpt":"@eviltrout any ideas here, the code seems correct","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":17,"reply_to_post_number":16,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-12T22:31:35Z","excerpt":"This is an interesting approach an an interesting feature. @eviltrout your thoughts. Essentially allows us to have notifications cross tabs.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"focus-events-track-which-window-is-the-last-active-instance-of-a-forum-edit","topic_id":11872,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":1,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Focus events: Track which window is the last active instance of a forum Edit","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-12T18:01:04Z","excerpt":"This was the link \n\nmetric_fu \n\n[metric_fu](https://github.com/metricfu/metric_fu/blob/b1bf8feb921916fc265f041efa3157a6a6530a9b/lib/metric_fu/logging/mf_debugger.rb#L24)\n\nSeems to work fine now that @eviltrout worked so hard to get us MDTest 1.1 compliant.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"underscores-in-linked-text-can-cause-markdown-bug","topic_id":10848,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Underscores in linked text can cause markdown bug","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-12T04:14:06Z","excerpt":"Awesome plugin, but doesn't seem to work out of the box with images \n\nhttps://github.com/discourse/discourse-spoiler-alert/issues/2","avatar_template":"//localhost:3000/uploads/default/avatars/276/f19/3826efe463/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/276/f19/3826efe463/{size}.jpg","slug":"brand-new-plugin-interface","topic_id":8793,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":64,"reply_to_post_number":44,"username":"xrvk","name":"Eero Heikkinen","user_id":8068,"acting_username":"xrvk","acting_name":"Eero Heikkinen","acting_user_id":8068,"title":"Brand new plugin interface","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T23:36:11Z","excerpt":"A few things, \n\n@eviltrout myself and many others have discourse_docker hosted on digital ocean, my user cpu is usually around 2% I have plenty of capacity. \n\nI know that stonehearth and other larger scale discourse work on digital ocean fine. Officially we strongly recommend a 2GB instance, thoug…","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"performance-issue-on-digital-ocean-with-discourse-docker","topic_id":11895,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Performance issue on Digital Ocean with discourse_docker","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:58:23Z","excerpt":"Confirmed on try.discourse.org, this is still an issue. \n\n@eviltrout can you add that to your list -- unless you are a staff member you should not be able to delete (your own) posts from an archived topic.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"archived-discussions-still-allow-posts-to-be-deleted","topic_id":6479,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Archived discussions still allow posts to be deleted","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:35:38Z","excerpt":"Agree, @eviltrout can you make sure the usercard is using the same logic as the user page in displaying profile info?","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"usercard-does-not-resize-for-obnoxiously-large-images","topic_id":11007,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":4,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Usercard does not resize for obnoxiously large images","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:34:06Z","excerpt":"@eviltrout can you make sure the "import post" button is suppressed on the user page when editing "about me"? \n\n(I agree it is like a "lose all my work" button on that page if you happen to press it..) \n\nThen I can archive this.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"quote-post-button-should-be-disabled-or-raise-an-error-when-creating-a-new-topic","topic_id":834,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":4,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"\"Quote Post\" button should be disabled or raise an error when creating a new topic","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-10T21:00:11Z","excerpt":">\n\nLooks good now. Thanks for these fixes @eviltrout, we (and markdown-js) are now MDTest 1.1 compliant!","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"text-editor-issue-with-the-code-block","topic_id":10050,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Text Editor issue with the code block","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":1,"created_at":"2014-01-10T20:07:46Z","excerpt":"We can't repro that one, also seems a bit obscure. But thank you very much for all the reports, whenever I see a bug entry from YOU I always know it is going to be a good one based on experience here and elsewhere. [trophy]","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"security-error-on-console-noticed-on-meta","topic_id":11825,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":12,"reply_to_post_number":11,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Security Error on console (noticed on meta)","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T19:48:08Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T19:47:17Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/42776c4982dff1fa45ee8248532f8ad0.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"neil","acting_name":"Neil","acting_user_id":2,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:39:24Z","excerpt":"We should consider doing what Google Drive does: they intercept cmd-f and pop up a box that allows you to dynamically search.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"ctrl-f-search-is-interrupted-by-quotation-popup","topic_id":7114,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":12,"reply_to_post_number":11,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Ctrl+F search is interrupted by quotation popup","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:29:15Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:24:37Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-10T17:02:35Z","excerpt":"Fixed [smile] \n\ntop - 12:02:00 up 12 days, 2:16, 1 user, load average: 0.28, 0.92, 0.97\nTasks: 115 total, 1 running, 114 sleeping, 0 stopped, 0 zombie\nCpu0 : 0.7%us, 0.3%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st\nCpu1 : 0.7%us, 0.3%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi,…","avatar_template":"//localhost:3000/uploads/default/avatars/886/ea8/e533d87fd9/{size}.png","acting_avatar_template":"//localhost:3000/uploads/default/avatars/886/ea8/e533d87fd9/{size}.png","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":23,"reply_to_post_number":22,"username":"michaeld","name":"Michael","user_id":6548,"acting_username":"michaeld","acting_name":"Michael","acting_user_id":6548,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T16:58:12Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//localhost:3000/uploads/default/avatars/527/614/d16e1504d9/{size}.jpg","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"trident","acting_name":"Ben T","acting_user_id":5707,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null}]}, +"/user_actions.json": {"user_actions":[{"action_type":7,"created_at":"2014-01-16T14:13:05Z","excerpt":"So again, \n\nWhat is the problem?\n\nI need to check user_trust_level , i get the 'username' from a form via ajax, i need to check what level he is on discourse \n\nAlso, if possible, i would like to get other details as well, like email address etc. \n\nI took a look at : https://github.com/discourse/dis…","avatar_template":"//www.gravatar.com/avatar/bdab7e61b3191e483492fd680f563fed.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/bdab7e61b3191e483492fd680f563fed.png?s={size}&r=pg&d=identicon","slug":"how-to-check-the-user-level-via-ajax","topic_id":11993,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"Abhishek_Gupta","name":"Abhishek Gupta","user_id":8021,"acting_username":"Abhishek_Gupta","acting_name":"Abhishek Gupta","acting_user_id":8021,"title":"How to check the user level via ajax?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-15T16:53:49Z","excerpt":"A good fix would be to have the ERB template do an if statement. We'd happily accept a PR that did this if you feel up to it: \n\n <% if SiteSetting.logo_url.present? %>\n display logo html\n<% else %>\n display title html\n<% end %>","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"users-activate-account-pulling-blank-logo-instead-of-defaulting-to-h2","topic_id":10911,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"/users/activate-account pulling blank logo instead of defaulting to h2","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-15T15:21:37Z","excerpt":"A good fix would be to have the ERB template do an if statement. We'd happily accept a PR that did this if you feel up to it: \n\n <% if SiteSetting.logo_url.present? %>\n display logo html\n<% else %>\n display title html\n<% end %>","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"users-activate-account-pulling-blank-logo-instead-of-defaulting-to-h2","topic_id":10911,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"/users/activate-account pulling blank logo instead of defaulting to h2","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-15T12:22:12Z","excerpt":"OK - i see what you mean. From the piwik code I should add: \n\n_paq.push(["setDocumentTitle", document.domain + "/" + document.title]);\n\n? \n\nUnfortunately I have had to give up on Piwik for now because I have switched the forum to SSL on a free cert and have used up the free subdomain for the forum. …","avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":26,"reply_to_post_number":25,"username":"citkane","name":"Michael Jonker","user_id":7604,"acting_username":"citkane","acting_name":"Michael Jonker","acting_user_id":7604,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T11:16:36Z","excerpt":"@eviltrout recently added support for multiple API keys [wink] \n\n[]","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"allow-for-multiple-api-keys","topic_id":7444,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Allow for multiple API Keys","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T10:58:46Z","excerpt":"@eviltrout added a tooltip when you click on the user's avatar which allows you to show the posts made by that user \n\n[image]","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"to-group-posts-by-a-user","topic_id":7412,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":3,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"To group posts by a user","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T10:36:15Z","excerpt":"@eviltrout implemented per-user API key a while ago [wink] \n\n [image]\nTopics_-_Discourse_Meta-5.png884x339 29.6 KB\n","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"auth-using-rest-api","topic_id":5937,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Auth using REST API?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-15T09:55:17Z","excerpt":"@eviltrout has recently introduced this feature and has even blogged about it: \n\n \n \n \n \n eviltrout.com\n \n \n \n \n \n Hiding Offscreen Content in Ember.js - Evil Trout's Blog","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"infinite-scrolling-reusing-dom-nodes","topic_id":5186,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"zogstrip","name":"Régis Hanol","user_id":1995,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Infinite scrolling: Reusing DOM nodes","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-15T00:54:32Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:59:51Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"znation","acting_name":"znation","acting_user_id":8163,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:46:50Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T21:43:28Z","excerpt":"Thanks for your help @eviltrout! I will consider making that change and sending a pull request. I may not get to it for a while. \n\nI am embedding Discourse on another site and it is mostly going well. I have indeed been using your blog for inspiration.","avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/9cfd2536afac32d209335b092094c12c.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"znation","name":"znation","user_id":8163,"acting_username":"znation","acting_name":"znation","acting_user_id":8163,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T21:21:52Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T21:03:07Z","excerpt":"Okay I've fixed the https [point_right] http links on the server side and in the Javascript click tracking as @BhaelOchon pointed out. \n\nLet me know if you find anything else broken.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"broken-links-possibly-related-to-https","topic_id":11831,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Broken links, possibly related to HTTPS","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T20:42:51Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T20:29:23Z","excerpt":"You can retrieve a user's JSON by making a call to /users/username.json but that assumes you know the user's username. If that's impossible, I would be happy to accept a PR that would return the current user JSON from /session/current-user or something like that. \n\nAdditionally, if you're looking to…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"get-current-user-information-via-json","topic_id":11959,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Get current user information via JSON","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T19:20:28Z","excerpt":"Perhaps the ['trackpageView'] is not the correct API call? We can probably send more information across such as the URL.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":25,"reply_to_post_number":24,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T19:19:46Z","excerpt":"Nope but I bet you can find one!","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":3,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T18:37:05Z","excerpt":"I'd be glad to write a pull request to take use there. Is there a specific part of their documentation you have in mind?","avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"watchmanmonitor","name":"Watchman Monitoring","user_id":8085,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-14T16:04:28Z","excerpt":"Thanks @eviltrout , the code in the 'bottom of pages' now reads: \n\n<script type="text/javascript">\nDiscourse.PageTracker.current().on('change', function() {\n console.log('tracked!')\n _paq.push(['trackPageView']);\n});\n</script>\n\nThe console is logging 'tracked!' and piwik is logging for each page c…","avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/2a8/a3c/8fddcac642/{size}.jpg","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":23,"reply_to_post_number":22,"username":"citkane","name":"Michael Jonker","user_id":7604,"acting_username":"citkane","acting_name":"Michael Jonker","acting_user_id":7604,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T15:58:27Z","excerpt":"This topic is now archived. It is frozen and cannot be changed in any way.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"regression-cannot-sort-topic-list","topic_id":11944,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Regression: Cannot sort topic list","deleted":false,"hidden":false,"moderator_action":true,"edit_reason":null},{"action_type":5,"created_at":"2014-01-14T15:26:57Z","excerpt":"I do think that leading them into the official rails documentation at that point is not a bad idea. Like "congratulations, everything is ready but now you'll need to understand the platform we built it in to be productive."","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-14T08:28:00Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-14T00:21:26Z","excerpt":"In pull request 1821, @eviltrout asked: \n\n "About rails s: I wouldn't be against adding it but at what point do we stop holding their hand and expect them to know how rails works? I'm sure rails documentation could do a better job than us. Actually maybe we should just link to that? \n\nWhat point to …","avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/035d12bad251759d8fbc9fb10574d1f6.png?s={size}&r=pg&d=identicon","slug":"how-far-to-take-user-documentation","topic_id":11943,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"watchmanmonitor","name":"Watchman Monitoring","user_id":8085,"acting_username":"watchmanmonitor","acting_name":"Watchman Monitoring","acting_user_id":8085,"title":"How far to take user documentation?","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-13T21:58:28Z","excerpt":"It looks uneeded, but you need to review a fair amount of code to confirm it is not needed. \n\nI am going to keep it for now cause its safer under some weird edge conditions.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"ruby-question-about-use-of-klass-self-in-the-site-customization-rb","topic_id":11889,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":2,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Ruby question about use of klass=self in the site_customization.rb","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T21:11:32Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-13T21:10:57Z","excerpt":"Having a look, the fix is a bit scary imho, we should fix the root issue.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":11,"reply_to_post_number":10,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T20:50:34Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//localhost:3000/uploads/default/avatars/527/614/d16e1504d9/{size}.jpg","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"trident","acting_name":"Ben T","acting_user_id":5707,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T20:44:56Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T20:40:21Z","excerpt":"I had to fix an issue with Google analytics so I added a new API hook that can be used. \n\nIf you add the following it should work: \n\n Discourse.PageTracker.current().on('change', function() {\n _paq.push(['trackPageView']);\n});","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T19:52:04Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T19:01:19Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T18:50:14Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T18:47:33Z","excerpt":"I am pretty sure that the denizens of SO are correct and the variable is unneeded. @sam can confirm but it seems like it was once needed for something that has since been removed and the variable declaration was left intact.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"ruby-question-about-use-of-klass-self-in-the-site-customization-rb","topic_id":11889,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Ruby question about use of klass=self in the site_customization.rb","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T18:45:41Z","excerpt":"I've just added the ability to list reply counts on your blog index and archive pages as you can see here. \n\nIt works with a similar API to embedding comments: \n\n <script type="text/javascript">\n var discourseUrl = "http://fishtank.eviltrout.com/";\n\n (function() {\n var d = document.createEleme…","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"discourse-plugin-for-static-site-generators-like-jekyll-or-octopress","topic_id":7965,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":98,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Discourse plugin for static site generators like Jekyll or Octopress","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T17:19:08Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T16:41:31Z","excerpt":"I'd love to see API support. @sam and @eviltrout, I can facilitate an intro to the piwik guys if you want—I've written about them before and they're typically super-responsive. Because I know you guys are totally hunting for new stuff to do [wink]","avatar_template":"//localhost:3000/uploads/default/avatars/95a/06d/c337428568/{size}.png","acting_avatar_template":"//localhost:3000/uploads/default/avatars/95a/06d/c337428568/{size}.png","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":20,"reply_to_post_number":null,"username":"Lee_Ars","name":"Lee_Ars","user_id":4457,"acting_username":"Lee_Ars","acting_name":"Lee_Ars","acting_user_id":4457,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-13T16:15:51Z","excerpt":"The code looks okay but it's hard to debug this way. \n\nOne thing you could do is add a: console.log('tracked!') just before line 8. Then open a developer console and see if the javascript is running properly.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T15:10:41Z","excerpt":"This is really interesting. I'd like to hear your findings.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"focus-events-track-which-window-is-the-last-active-instance-of-a-forum-edit","topic_id":11872,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":9,"reply_to_post_number":8,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Focus events: Track which window is the last active instance of a forum Edit","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T15:02:45Z","excerpt":"The code looks okay but it's hard to debug this way. \n\nOne thing you could do is add a: console.log('tracked!') just before line 8. Then open a developer console and see if the javascript is running properly.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":18,"reply_to_post_number":16,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":5,"created_at":"2014-01-13T14:53:13Z","excerpt":"@Sam do you have any idea why only some people are getting this issue? I dont' mind the proposed fix but I'd prefer to know why it happens in the first place.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"error-after-update-to-0-9-8-1","topic_id":11903,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":10,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Error after update to 0.9.8.1","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T06:27:26Z","excerpt":"Can this be archived @eviltrout?","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"search-not-working-for-staff-users","topic_id":11371,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":13,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Search not working for Staff users","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T05:32:46Z","excerpt":"When you navigate to another topic using the "suggested topics" area we are not registering a page view with Google. \n\n@eviltrout perhaps we should do this from discourse location instead of application controller?","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"google-analytics-is-not-registering-page-views","topic_id":11914,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":1,"reply_to_post_number":null,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Google analytics is not registering page views","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-13T02:50:25Z","excerpt":"@eviltrout any ideas here, the code seems correct","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"support-for-piwik-analytics-as-an-alternative-to-google-analytics","topic_id":7512,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":17,"reply_to_post_number":16,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Support for Piwik Analytics as an alternative to Google Analytics","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-12T22:31:35Z","excerpt":"This is an interesting approach an an interesting feature. @eviltrout your thoughts. Essentially allows us to have notifications cross tabs.","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"focus-events-track-which-window-is-the-last-active-instance-of-a-forum-edit","topic_id":11872,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":4,"reply_to_post_number":1,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Focus events: Track which window is the last active instance of a forum Edit","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-12T18:01:04Z","excerpt":"This was the link \n\nmetric_fu \n\n[metric_fu](https://github.com/metricfu/metric_fu/blob/b1bf8feb921916fc265f041efa3157a6a6530a9b/lib/metric_fu/logging/mf_debugger.rb#L24)\n\nSeems to work fine now that @eviltrout worked so hard to get us MDTest 1.1 compliant.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"underscores-in-linked-text-can-cause-markdown-bug","topic_id":10848,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Underscores in linked text can cause markdown bug","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-12T04:14:06Z","excerpt":"Awesome plugin, but doesn't seem to work out of the box with images \n\nhttps://github.com/discourse/discourse-spoiler-alert/issues/2","avatar_template":"//localhost:3000/uploads/default/avatars/276/f19/3826efe463/{size}.jpg","acting_avatar_template":"//localhost:3000/uploads/default/avatars/276/f19/3826efe463/{size}.jpg","slug":"brand-new-plugin-interface","topic_id":8793,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":64,"reply_to_post_number":44,"username":"xrvk","name":"Eero Heikkinen","user_id":8068,"acting_username":"xrvk","acting_name":"Eero Heikkinen","acting_user_id":8068,"title":"Brand new plugin interface","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T23:36:11Z","excerpt":"A few things, \n\n@eviltrout myself and many others have discourse_docker hosted on DigitalOcean, my user cpu is usually around 2% I have plenty of capacity. \n\nI know that stonehearth and other larger scale discourse work on DigitalOcean fine. Officially we strongly recommend a 2GB instance, thoug…","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon","slug":"performance-issue-on-digital-ocean-with-discourse-docker","topic_id":11895,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":2,"reply_to_post_number":null,"username":"sam","name":"Sam Saffron","user_id":1,"acting_username":"sam","acting_name":"Sam Saffron","acting_user_id":1,"title":"Performance issue on DigitalOcean with discourse_docker","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:58:23Z","excerpt":"Confirmed on try.discourse.org, this is still an issue. \n\n@eviltrout can you add that to your list -- unless you are a staff member you should not be able to delete (your own) posts from an archived topic.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"archived-discussions-still-allow-posts-to-be-deleted","topic_id":6479,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":3,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Archived discussions still allow posts to be deleted","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:35:38Z","excerpt":"Agree, @eviltrout can you make sure the usercard is using the same logic as the user page in displaying profile info?","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"usercard-does-not-resize-for-obnoxiously-large-images","topic_id":11007,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":4,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Usercard does not resize for obnoxiously large images","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-11T00:34:06Z","excerpt":"@eviltrout can you make sure the "import post" button is suppressed on the user page when editing "about me"? \n\n(I agree it is like a "lose all my work" button on that page if you happen to press it..) \n\nThen I can archive this.","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"quote-post-button-should-be-disabled-or-raise-an-error-when-creating-a-new-topic","topic_id":834,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":4,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"\"Quote Post\" button should be disabled or raise an error when creating a new topic","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":7,"created_at":"2014-01-10T21:00:11Z","excerpt":">\n\nLooks good now. Thanks for these fixes @eviltrout, we (and markdown-js) are now MDTest 1.1 compliant!","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"text-editor-issue-with-the-code-block","topic_id":10050,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":5,"reply_to_post_number":null,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Text Editor issue with the code block","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":1,"created_at":"2014-01-10T20:07:46Z","excerpt":"We can't repro that one, also seems a bit obscure. But thank you very much for all the reports, whenever I see a bug entry from YOU I always know it is going to be a good one based on experience here and elsewhere. [trophy]","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","slug":"security-error-on-console-noticed-on-meta","topic_id":11825,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":12,"reply_to_post_number":11,"username":"codinghorror","name":"Jeff Atwood","user_id":32,"acting_username":"eviltrout","acting_name":"Robin Ward","acting_user_id":19,"title":"Security Error on console (noticed on meta)","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T19:48:08Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"codinghorror","acting_name":"Jeff Atwood","acting_user_id":32,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T19:47:17Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/42776c4982dff1fa45ee8248532f8ad0.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"neil","acting_name":"Neil","acting_user_id":2,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:39:24Z","excerpt":"We should consider doing what Google Drive does: they intercept cmd-f and pop up a box that allows you to dynamically search.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"ctrl-f-search-is-interrupted-by-quotation-popup","topic_id":7114,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":12,"reply_to_post_number":11,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Ctrl+F search is interrupted by quotation popup","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:29:15Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/5120fc4e345db0d1a964888272073819.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"riking","acting_name":"Kane York","acting_user_id":6626,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T17:24:37Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"zogstrip","acting_name":"Régis Hanol","acting_user_id":1995,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":6,"created_at":"2014-01-10T17:02:35Z","excerpt":"Fixed [smile] \n\ntop - 12:02:00 up 12 days, 2:16, 1 user, load average: 0.28, 0.92, 0.97\nTasks: 115 total, 1 running, 114 sleeping, 0 stopped, 0 zombie\nCpu0 : 0.7%us, 0.3%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st\nCpu1 : 0.7%us, 0.3%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi,…","avatar_template":"//localhost:3000/uploads/default/avatars/886/ea8/e533d87fd9/{size}.png","acting_avatar_template":"//localhost:3000/uploads/default/avatars/886/ea8/e533d87fd9/{size}.png","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":23,"reply_to_post_number":22,"username":"michaeld","name":"Michael","user_id":6548,"acting_username":"michaeld","acting_name":"Michael","acting_user_id":6548,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null},{"action_type":2,"created_at":"2014-01-10T16:58:12Z","excerpt":"Thanks for letting us know. It turns out that by using minutely(5) instead of minutely causes ice_cube to peg a core at 100% usage. I've pushed out a fix in master.","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","acting_avatar_template":"//localhost:3000/uploads/default/avatars/527/614/d16e1504d9/{size}.jpg","slug":"sidekiq-cpu-load-since-latest-release","topic_id":9515,"target_user_id":19,"target_name":"Robin Ward","target_username":"eviltrout","post_number":22,"reply_to_post_number":null,"username":"eviltrout","name":"Robin Ward","user_id":19,"acting_username":"trident","acting_name":"Ben T","acting_user_id":5707,"title":"Sidekiq CPU load since latest release","deleted":false,"hidden":false,"moderator_action":false,"edit_reason":null}]}, "/topics/created-by/eviltrout.json": {"users":[{"id":19,"username":"eviltrout","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon"},{"id":5460,"username":"ned","avatar_template":"//localhost:3000/uploads/default/avatars/06b/90d/3b3ea7e56b/{size}.png"},{"id":402,"username":"thebrianbarlow","avatar_template":"//www.gravatar.com/avatar/5ddf2459e8edd6cf52dfff6cb41ca70d.png?s={size}&r=pg&d=identicon"},{"id":5707,"username":"trident","avatar_template":"//localhost:3000/uploads/default/avatars/527/614/d16e1504d9/{size}.jpg"},{"id":32,"username":"codinghorror","avatar_template":"//www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon"},{"id":1995,"username":"zogstrip","avatar_template":"//www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon"},{"id":2702,"username":"ryanflorence","avatar_template":"//www.gravatar.com/avatar/749001c9fe6927c4b069a45c2a3d68f7.png?s={size}&r=pg&d=identicon"},{"id":9,"username":"tms","avatar_template":"//www.gravatar.com/avatar/3981cd271c302f5cba628c6b6d2b32ee.png?s={size}&r=pg&d=identicon"},{"id":1,"username":"sam","avatar_template":"//www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon"},{"id":2636,"username":"lonnon","avatar_template":"//www.gravatar.com/avatar/9489ef302fbff6c19bba507d09f8cd1d.png?s={size}&r=pg&d=identicon"}],"topic_list":{"can_create_topic":false,"draft":null,"draft_key":"new_topic","draft_sequence":null,"topics":[{"id":7764,"title":"New: Reply via Email Support!","fancy_title":"New: Reply via Email Support!","slug":"new-reply-via-email-support","posts_count":32,"reply_count":24,"highest_post_number":35,"image_url":"/uploads/meta_discourse/1227/8f4e5818dfaa56c7.png","created_at":"2013-06-25T11:58:39.000-04:00","last_posted_at":"2014-01-09T18:53:06.000-05:00","bumped":true,"bumped_at":"2014-01-09T17:09:40.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":2201,"like_count":46,"has_summary":false,"archetype":"regular","last_poster_username":"codinghorror","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":19},{"extras":null,"description":"Most Posts","user_id":5460},{"extras":null,"description":"Frequent Poster","user_id":402},{"extras":null,"description":"Frequent Poster","user_id":5707},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":9318,"title":"Discourse has a new Markdown Parser!","fancy_title":"Discourse has a new Markdown Parser!","slug":"discourse-has-a-new-markdown-parser","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-08-24T14:08:06.000-04:00","last_posted_at":"2013-08-24T14:08:06.000-04:00","bumped":true,"bumped_at":"2013-08-24T14:13:25.000-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":812,"like_count":13,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":19}]},{"id":7019,"title":"Discourse Ember Refactorings","fancy_title":"Discourse Ember Refactorings","slug":"discourse-ember-refactorings","posts_count":5,"reply_count":3,"highest_post_number":5,"image_url":null,"created_at":"2013-05-30T11:16:36.000-04:00","last_posted_at":"2013-06-02T11:22:58.000-04:00","bumped":true,"bumped_at":"2013-06-02T11:22:58.000-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":1075,"like_count":15,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":19},{"extras":null,"description":"Most Posts","user_id":1995},{"extras":null,"description":"Frequent Poster","user_id":2702}]},{"id":4650,"title":"Migrating off Active Record Observers","fancy_title":"Migrating off Active Record Observers","slug":"migrating-off-active-record-observers","posts_count":8,"reply_count":7,"highest_post_number":8,"image_url":null,"created_at":"2013-03-11T11:26:13.000-04:00","last_posted_at":"2013-05-14T18:40:16.000-04:00","bumped":true,"bumped_at":"2013-05-14T18:40:16.000-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":377,"like_count":3,"has_summary":false,"archetype":"regular","last_poster_username":"sam","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":19},{"extras":null,"description":"Most Posts","user_id":9},{"extras":null,"description":"Frequent Poster","user_id":1995},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":4960,"title":"Vagrant Updates!","fancy_title":"Vagrant Updates!","slug":"vagrant-updates","posts_count":5,"reply_count":3,"highest_post_number":5,"image_url":"/plugins/emoji/images/fish.png","created_at":"2013-03-20T22:29:22.000-04:00","last_posted_at":"2013-03-21T19:06:40.000-04:00","bumped":true,"bumped_at":"2013-03-21T19:06:40.000-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":500,"like_count":4,"has_summary":false,"archetype":"regular","last_poster_username":"zogstrip","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":19},{"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":2918,"title":"New: Updated Docs","fancy_title":"New: Updated Docs","slug":"new-updated-docs","posts_count":3,"reply_count":2,"highest_post_number":3,"image_url":null,"created_at":"2013-02-12T12:13:02.000-05:00","last_posted_at":"2013-02-15T17:57:19.000-05:00","bumped":true,"bumped_at":"2013-02-15T17:57:19.000-05:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":457,"like_count":10,"has_summary":false,"archetype":"regular","last_poster_username":"eviltrout","category_id":10,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":19},{"extras":null,"description":"Most Posts","user_id":2636}]}]}} }; diff --git a/test/javascripts/lib/discourse-test.js.es6 b/test/javascripts/lib/discourse-test.js.es6 new file mode 100644 index 0000000000..8f3725fa44 --- /dev/null +++ b/test/javascripts/lib/discourse-test.js.es6 @@ -0,0 +1,7 @@ +module("lib:discourse"); + +test("getURL on subfolder install", function() { + Discourse.BaseUri = "/forum"; + equal(Discourse.getURL("/"), "/forum/", "root url has subfolder"); + equal(Discourse.getURL("/users/neil"), "/forum/users/neil", "relative url has subfolder"); +}); \ No newline at end of file diff --git a/vendor/assets/javascripts/mousetrap.js b/vendor/assets/javascripts/mousetrap.js index 108216bd71..48d2f625c2 100644 --- a/vendor/assets/javascripts/mousetrap.js +++ b/vendor/assets/javascripts/mousetrap.js @@ -1,6 +1,6 @@ /*global define:false */ /** - * Copyright 2013 Craig Campbell + * Copyright 2015 Craig Campbell * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ * Mousetrap is a simple keyboard shortcut library for Javascript with * no external dependencies * - * @version 1.4.6 + * @version 1.5.3 * @url craig.is/killing/mice */ (function(window, document, undefined) { @@ -32,162 +32,112 @@ * @type {Object} */ var _MAP = { - 8: 'backspace', - 9: 'tab', - 13: 'enter', - 16: 'shift', - 17: 'ctrl', - 18: 'alt', - 20: 'capslock', - 27: 'esc', - 32: 'space', - 33: 'pageup', - 34: 'pagedown', - 35: 'end', - 36: 'home', - 37: 'left', - 38: 'up', - 39: 'right', - 40: 'down', - 45: 'ins', - 46: 'del', - 91: 'meta', - 93: 'meta', - 224: 'meta' - }, + 8: 'backspace', + 9: 'tab', + 13: 'enter', + 16: 'shift', + 17: 'ctrl', + 18: 'alt', + 20: 'capslock', + 27: 'esc', + 32: 'space', + 33: 'pageup', + 34: 'pagedown', + 35: 'end', + 36: 'home', + 37: 'left', + 38: 'up', + 39: 'right', + 40: 'down', + 45: 'ins', + 46: 'del', + 91: 'meta', + 93: 'meta', + 224: 'meta' + }; - /** - * mapping for special characters so they can support - * - * this dictionary is only used incase you want to bind a - * keyup or keydown event to one of these keys - * - * @type {Object} - */ - _KEYCODE_MAP = { - 106: '*', - 107: '+', - 109: '-', - 110: '.', - 111 : '/', - 186: ';', - 187: '=', - 188: ',', - 189: '-', - 190: '.', - 191: '/', - 192: '`', - 219: '[', - 220: '\\', - 221: ']', - 222: '\'' - }, + /** + * mapping for special characters so they can support + * + * this dictionary is only used incase you want to bind a + * keyup or keydown event to one of these keys + * + * @type {Object} + */ + var _KEYCODE_MAP = { + 106: '*', + 107: '+', + 109: '-', + 110: '.', + 111 : '/', + 186: ';', + 187: '=', + 188: ',', + 189: '-', + 190: '.', + 191: '/', + 192: '`', + 219: '[', + 220: '\\', + 221: ']', + 222: '\'' + }; - /** - * this is a mapping of keys that require shift on a US keypad - * back to the non shift equivelents - * - * this is so you can use keyup events with these keys - * - * note that this will only work reliably on US keyboards - * - * @type {Object} - */ - _SHIFT_MAP = { - '~': '`', - '!': '1', - '@': '2', - '#': '3', - '$': '4', - '%': '5', - '^': '6', - '&': '7', - '*': '8', - '(': '9', - ')': '0', - '_': '-', - '+': '=', - ':': ';', - '\"': '\'', - '<': ',', - '>': '.', - '?': '/', - '|': '\\' - }, + /** + * this is a mapping of keys that require shift on a US keypad + * back to the non shift equivelents + * + * this is so you can use keyup events with these keys + * + * note that this will only work reliably on US keyboards + * + * @type {Object} + */ + var _SHIFT_MAP = { + '~': '`', + '!': '1', + '@': '2', + '#': '3', + '$': '4', + '%': '5', + '^': '6', + '&': '7', + '*': '8', + '(': '9', + ')': '0', + '_': '-', + '+': '=', + ':': ';', + '\"': '\'', + '<': ',', + '>': '.', + '?': '/', + '|': '\\' + }; - /** - * this is a list of special strings you can use to map - * to modifier keys when you specify your keyboard shortcuts - * - * @type {Object} - */ - _SPECIAL_ALIASES = { - 'option': 'alt', - 'command': 'meta', - 'return': 'enter', - 'escape': 'esc', - 'mod': /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? 'meta' : 'ctrl' - }, + /** + * this is a list of special strings you can use to map + * to modifier keys when you specify your keyboard shortcuts + * + * @type {Object} + */ + var _SPECIAL_ALIASES = { + 'option': 'alt', + 'command': 'meta', + 'return': 'enter', + 'escape': 'esc', + 'plus': '+', + 'mod': /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? 'meta' : 'ctrl' + }; - /** - * variable to store the flipped version of _MAP from above - * needed to check if we should use keypress or not when no action - * is specified - * - * @type {Object|undefined} - */ - _REVERSE_MAP, - - /** - * a list of all the callbacks setup via Mousetrap.bind() - * - * @type {Object} - */ - _callbacks = {}, - - /** - * direct map of string combinations to callbacks used for trigger() - * - * @type {Object} - */ - _directMap = {}, - - /** - * keeps track of what level each sequence is at since multiple - * sequences can start out with the same sequence - * - * @type {Object} - */ - _sequenceLevels = {}, - - /** - * variable to store the setTimeout call - * - * @type {null|number} - */ - _resetTimer, - - /** - * temporary state where we will ignore the next keyup - * - * @type {boolean|string} - */ - _ignoreNextKeyup = false, - - /** - * temporary state where we will ignore the next keypress - * - * @type {boolean} - */ - _ignoreNextKeypress = false, - - /** - * are we currently inside of a sequence? - * type of action ("keyup" or "keydown" or "keypress") or false - * - * @type {boolean|string} - */ - _nextExpectedAction = false; + /** + * variable to store the flipped version of _MAP from above + * needed to check if we should use keypress or not when no action + * is specified + * + * @type {Object|undefined} + */ + var _REVERSE_MAP; /** * loop through the f keys, f1 to f19 and add them to the map @@ -277,103 +227,6 @@ return modifiers1.sort().join(',') === modifiers2.sort().join(','); } - /** - * resets all sequence counters except for the ones passed in - * - * @param {Object} doNotReset - * @returns void - */ - function _resetSequences(doNotReset) { - doNotReset = doNotReset || {}; - - var activeSequences = false, - key; - - for (key in _sequenceLevels) { - if (doNotReset[key]) { - activeSequences = true; - continue; - } - _sequenceLevels[key] = 0; - } - - if (!activeSequences) { - _nextExpectedAction = false; - } - } - - /** - * finds all callbacks that match based on the keycode, modifiers, - * and action - * - * @param {string} character - * @param {Array} modifiers - * @param {Event|Object} e - * @param {string=} sequenceName - name of the sequence we are looking for - * @param {string=} combination - * @param {number=} level - * @returns {Array} - */ - function _getMatches(character, modifiers, e, sequenceName, combination, level) { - var i, - callback, - matches = [], - action = e.type; - - // if there are no events related to this keycode - if (!_callbacks[character]) { - return []; - } - - // if a modifier key is coming up on its own we should allow it - if (action == 'keyup' && _isModifier(character)) { - modifiers = [character]; - } - - // loop through all callbacks for the key that was pressed - // and see if any of them match - for (i = 0; i < _callbacks[character].length; ++i) { - callback = _callbacks[character][i]; - - // if a sequence name is not specified, but this is a sequence at - // the wrong level then move onto the next match - if (!sequenceName && callback.seq && _sequenceLevels[callback.seq] != callback.level) { - continue; - } - - // if the action we are looking for doesn't match the action we got - // then we should keep going - if (action != callback.action) { - continue; - } - - // if this is a keypress event and the meta key and control key - // are not pressed that means that we need to only look at the - // character, otherwise check the modifiers as well - // - // chrome will not fire a keypress if meta or control is down - // safari will fire a keypress if meta or meta+shift is down - // firefox will fire a keypress if meta or control is down - if ((action == 'keypress' && !e.metaKey && !e.ctrlKey) || _modifiersMatch(modifiers, callback.modifiers)) { - - // when you bind a combination or sequence a second time it - // should overwrite the first one. if a sequenceName or - // combination is specified in this call it does just that - // - // @todo make deleting its own method? - var deleteCombo = !sequenceName && callback.combo == combination; - var deleteSequence = sequenceName && callback.seq == sequenceName && callback.level == level; - if (deleteCombo || deleteSequence) { - _callbacks[character].splice(i, 1); - } - - matches.push(callback); - } - } - - return matches; - } - /** * takes a key event and figures out what the modifiers are * @@ -432,147 +285,6 @@ e.cancelBubble = true; } - /** - * actually calls the callback function - * - * if your callback function returns false this will use the jquery - * convention - prevent default and stop propogation on the event - * - * @param {Function} callback - * @param {Event} e - * @returns void - */ - function _fireCallback(callback, e, combo, sequence) { - - // if this event should not happen stop here - if (Mousetrap.stopCallback(e, e.target || e.srcElement, combo, sequence)) { - return; - } - - if (callback(e, combo) === false) { - _preventDefault(e); - _stopPropagation(e); - } - } - - /** - * handles a character key event - * - * @param {string} character - * @param {Array} modifiers - * @param {Event} e - * @returns void - */ - function _handleKey(character, modifiers, e) { - var callbacks = _getMatches(character, modifiers, e), - i, - doNotReset = {}, - maxLevel = 0, - processedSequenceCallback = false; - - // Calculate the maxLevel for sequences so we can only execute the longest callback sequence - for (i = 0; i < callbacks.length; ++i) { - if (callbacks[i].seq) { - maxLevel = Math.max(maxLevel, callbacks[i].level); - } - } - - // loop through matching callbacks for this key event - for (i = 0; i < callbacks.length; ++i) { - - // fire for all sequence callbacks - // this is because if for example you have multiple sequences - // bound such as "g i" and "g t" they both need to fire the - // callback for matching g cause otherwise you can only ever - // match the first one - if (callbacks[i].seq) { - - // only fire callbacks for the maxLevel to prevent - // subsequences from also firing - // - // for example 'a option b' should not cause 'option b' to fire - // even though 'option b' is part of the other sequence - // - // any sequences that do not match here will be discarded - // below by the _resetSequences call - if (callbacks[i].level != maxLevel) { - continue; - } - - processedSequenceCallback = true; - - // keep a list of which sequences were matches for later - doNotReset[callbacks[i].seq] = 1; - _fireCallback(callbacks[i].callback, e, callbacks[i].combo, callbacks[i].seq); - continue; - } - - // if there were no sequence matches but we are still here - // that means this is a regular match so we should fire that - if (!processedSequenceCallback) { - _fireCallback(callbacks[i].callback, e, callbacks[i].combo); - } - } - - // if the key you pressed matches the type of sequence without - // being a modifier (ie "keyup" or "keypress") then we should - // reset all sequences that were not matched by this event - // - // this is so, for example, if you have the sequence "h a t" and you - // type "h e a r t" it does not match. in this case the "e" will - // cause the sequence to reset - // - // modifier keys are ignored because you can have a sequence - // that contains modifiers such as "enter ctrl+space" and in most - // cases the modifier key will be pressed before the next key - // - // also if you have a sequence such as "ctrl+b a" then pressing the - // "b" key will trigger a "keypress" and a "keydown" - // - // the "keydown" is expected when there is a modifier, but the - // "keypress" ends up matching the _nextExpectedAction since it occurs - // after and that causes the sequence to reset - // - // we ignore keypresses in a sequence that directly follow a keydown - // for the same character - var ignoreThisKeypress = e.type == 'keypress' && _ignoreNextKeypress; - if (e.type == _nextExpectedAction && !_isModifier(character) && !ignoreThisKeypress) { - _resetSequences(doNotReset); - } - - _ignoreNextKeypress = processedSequenceCallback && e.type == 'keydown'; - } - - /** - * handles a keydown event - * - * @param {Event} e - * @returns void - */ - function _handleKeyEvent(e) { - - // normalize e.which for key events - // @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion - if (typeof e.which !== 'number') { - e.which = e.keyCode; - } - - var character = _characterFromEvent(e); - - // no character found then stop - if (!character) { - return; - } - - // need to use === for the character check because the character can be 0 - if (e.type == 'keyup' && _ignoreNextKeyup === character) { - _ignoreNextKeyup = false; - return; - } - - Mousetrap.handleKey(character, _eventModifiers(e), e); - } - /** * determines if the keycode specified is a modifier key or not * @@ -583,19 +295,6 @@ return key == 'shift' || key == 'ctrl' || key == 'alt' || key == 'meta'; } - /** - * called to set a 1 second timeout on the specified sequence - * - * this is so after each key press in the sequence you have 1 second - * to press the next key before you have to start over - * - * @returns void - */ - function _resetSequenceTimer() { - clearTimeout(_resetTimer); - _resetTimer = setTimeout(_resetSequences, 1000); - } - /** * reverses the map lookup so that we can look for specific keys * to see what can and can't use keypress @@ -645,74 +344,6 @@ return action; } - /** - * binds a key sequence to an event - * - * @param {string} combo - combo specified in bind call - * @param {Array} keys - * @param {Function} callback - * @param {string=} action - * @returns void - */ - function _bindSequence(combo, keys, callback, action) { - - // start off by adding a sequence level record for this combination - // and setting the level to 0 - _sequenceLevels[combo] = 0; - - /** - * callback to increase the sequence level for this sequence and reset - * all other sequences that were active - * - * @param {string} nextAction - * @returns {Function} - */ - function _increaseSequence(nextAction) { - return function() { - _nextExpectedAction = nextAction; - ++_sequenceLevels[combo]; - _resetSequenceTimer(); - }; - } - - /** - * wraps the specified callback inside of another function in order - * to reset all sequence counters as soon as this sequence is done - * - * @param {Event} e - * @returns void - */ - function _callbackAndReset(e) { - _fireCallback(callback, e, combo); - - // we should ignore the next key up if the action is key down - // or keypress. this is so if you finish a sequence and - // release the key the final key will not trigger a keyup - if (action !== 'keyup') { - _ignoreNextKeyup = _characterFromEvent(e); - } - - // weird race condition if a sequence ends with the key - // another sequence begins with - setTimeout(_resetSequences, 10); - } - - // loop through keys one at a time and bind the appropriate callback - // function. for any key leading up to the final one it should - // increase the sequence. after the final, it should reset all sequences - // - // if an action is specified in the original bind call then that will - // be used throughout. otherwise we will pass the action that the - // next key in the sequence should match. this allows a sequence - // to mix and match keypress and keydown events depending on which - // ones are better suited to the key provided - for (var i = 0; i < keys.length; ++i) { - var isFinal = i + 1 === keys.length; - var wrappedCallback = isFinal ? _callbackAndReset : _increaseSequence(action || _getKeyInfo(keys[i + 1]).action); - _bindSingle(keys[i], wrappedCallback, action, combo, i); - } - } - /** * Converts from a string key combination to an array * @@ -724,6 +355,7 @@ return ['+']; } + combination = combination.replace(/\+{2}/g, '+plus'); return combination.split('+'); } @@ -735,10 +367,10 @@ * @returns {Object} */ function _getKeyInfo(combination, action) { - var keys, - key, - i, - modifiers = []; + var keys; + var key; + var i; + var modifiers = []; // take the keys from this pattern and figure out what the actual // pattern is all about @@ -777,228 +409,613 @@ }; } - /** - * binds a single keyboard combination - * - * @param {string} combination - * @param {Function} callback - * @param {string=} action - * @param {string=} sequenceName - name of sequence if part of sequence - * @param {number=} level - what part of the sequence the command is - * @returns void - */ - function _bindSingle(combination, callback, action, sequenceName, level) { - - // store a direct mapped reference for use with Mousetrap.trigger - _directMap[combination + ':' + action] = callback; - - // make sure multiple spaces in a row become a single space - combination = combination.replace(/\s+/g, ' '); - - var sequence = combination.split(' '), - info; - - // if this pattern is a sequence of keys then run through this method - // to reprocess each pattern one key at a time - if (sequence.length > 1) { - _bindSequence(combination, sequence, callback, action); - return; + function _belongsTo(element, ancestor) { + if (element === null || element === document) { + return false; } - info = _getKeyInfo(combination, action); - - // make sure to initialize array if this is the first time - // a callback is added for this key - _callbacks[info.key] = _callbacks[info.key] || []; - - // remove an existing match if there is one - _getMatches(info.key, info.modifiers, {type: info.action}, sequenceName, combination, level); - - // add this call back to the array - // if it is a sequence put it at the beginning - // if not put it at the end - // - // this is important because the way these are processed expects - // the sequence ones to come first - _callbacks[info.key][sequenceName ? 'unshift' : 'push']({ - callback: callback, - modifiers: info.modifiers, - action: info.action, - seq: sequenceName, - level: level, - combo: combination - }); - } - - /** - * binds multiple combinations to the same callback - * - * @param {Array} combinations - * @param {Function} callback - * @param {string|undefined} action - * @returns void - */ - function _bindMultiple(combinations, callback, action) { - for (var i = 0; i < combinations.length; ++i) { - _bindSingle(combinations[i], callback, action); + if (element === ancestor) { + return true; } + + return _belongsTo(element.parentNode, ancestor); } - // start! - _addEvent(document, 'keypress', _handleKeyEvent); - _addEvent(document, 'keydown', _handleKeyEvent); - _addEvent(document, 'keyup', _handleKeyEvent); + function Mousetrap(targetElement) { + var self = this; - var Mousetrap = { + targetElement = targetElement || document; + + if (!(self instanceof Mousetrap)) { + return new Mousetrap(targetElement); + } /** - * binds an event to mousetrap + * element to attach key events to * - * can be a single key, a combination of keys separated with +, - * an array of keys, or a sequence of keys separated by spaces + * @type {Element} + */ + self.target = targetElement; + + /** + * a list of all the callbacks setup via Mousetrap.bind() * - * be sure to list the modifier keys first to make sure that the - * correct key ends up getting bound (the last key in the pattern) + * @type {Object} + */ + self._callbacks = {}; + + /** + * direct map of string combinations to callbacks used for trigger() + * + * @type {Object} + */ + self._directMap = {}; + + /** + * keeps track of what level each sequence is at since multiple + * sequences can start out with the same sequence + * + * @type {Object} + */ + var _sequenceLevels = {}; + + /** + * variable to store the setTimeout call + * + * @type {null|number} + */ + var _resetTimer; + + /** + * temporary state where we will ignore the next keyup + * + * @type {boolean|string} + */ + var _ignoreNextKeyup = false; + + /** + * temporary state where we will ignore the next keypress + * + * @type {boolean} + */ + var _ignoreNextKeypress = false; + + /** + * are we currently inside of a sequence? + * type of action ("keyup" or "keydown" or "keypress") or false + * + * @type {boolean|string} + */ + var _nextExpectedAction = false; + + /** + * resets all sequence counters except for the ones passed in + * + * @param {Object} doNotReset + * @returns void + */ + function _resetSequences(doNotReset) { + doNotReset = doNotReset || {}; + + var activeSequences = false, + key; + + for (key in _sequenceLevels) { + if (doNotReset[key]) { + activeSequences = true; + continue; + } + _sequenceLevels[key] = 0; + } + + if (!activeSequences) { + _nextExpectedAction = false; + } + } + + /** + * finds all callbacks that match based on the keycode, modifiers, + * and action + * + * @param {string} character + * @param {Array} modifiers + * @param {Event|Object} e + * @param {string=} sequenceName - name of the sequence we are looking for + * @param {string=} combination + * @param {number=} level + * @returns {Array} + */ + function _getMatches(character, modifiers, e, sequenceName, combination, level) { + var i; + var callback; + var matches = []; + var action = e.type; + + // if there are no events related to this keycode + if (!self._callbacks[character]) { + return []; + } + + // if a modifier key is coming up on its own we should allow it + if (action == 'keyup' && _isModifier(character)) { + modifiers = [character]; + } + + // loop through all callbacks for the key that was pressed + // and see if any of them match + for (i = 0; i < self._callbacks[character].length; ++i) { + callback = self._callbacks[character][i]; + + // if a sequence name is not specified, but this is a sequence at + // the wrong level then move onto the next match + if (!sequenceName && callback.seq && _sequenceLevels[callback.seq] != callback.level) { + continue; + } + + // if the action we are looking for doesn't match the action we got + // then we should keep going + if (action != callback.action) { + continue; + } + + // if this is a keypress event and the meta key and control key + // are not pressed that means that we need to only look at the + // character, otherwise check the modifiers as well + // + // chrome will not fire a keypress if meta or control is down + // safari will fire a keypress if meta or meta+shift is down + // firefox will fire a keypress if meta or control is down + if ((action == 'keypress' && !e.metaKey && !e.ctrlKey) || _modifiersMatch(modifiers, callback.modifiers)) { + + // when you bind a combination or sequence a second time it + // should overwrite the first one. if a sequenceName or + // combination is specified in this call it does just that + // + // @todo make deleting its own method? + var deleteCombo = !sequenceName && callback.combo == combination; + var deleteSequence = sequenceName && callback.seq == sequenceName && callback.level == level; + if (deleteCombo || deleteSequence) { + self._callbacks[character].splice(i, 1); + } + + matches.push(callback); + } + } + + return matches; + } + + /** + * actually calls the callback function + * + * if your callback function returns false this will use the jquery + * convention - prevent default and stop propogation on the event * - * @param {string|Array} keys * @param {Function} callback - * @param {string=} action - 'keypress', 'keydown', or 'keyup' + * @param {Event} e * @returns void */ - bind: function(keys, callback, action) { - keys = keys instanceof Array ? keys : [keys]; - _bindMultiple(keys, callback, action); - return this; - }, + function _fireCallback(callback, e, combo, sequence) { + + // if this event should not happen stop here + if (self.stopCallback(e, e.target || e.srcElement, combo, sequence)) { + return; + } + + if (callback(e, combo) === false) { + _preventDefault(e); + _stopPropagation(e); + } + } /** - * unbinds an event to mousetrap + * handles a character key event * - * the unbinding sets the callback function of the specified key combo - * to an empty function and deletes the corresponding key in the - * _directMap dict. - * - * TODO: actually remove this from the _callbacks dictionary instead - * of binding an empty function - * - * the keycombo+action has to be exactly the same as - * it was defined in the bind method - * - * @param {string|Array} keys - * @param {string} action + * @param {string} character + * @param {Array} modifiers + * @param {Event} e * @returns void */ - unbind: function(keys, action) { - return Mousetrap.bind(keys, function() {}, action); - }, + self._handleKey = function(character, modifiers, e) { + var callbacks = _getMatches(character, modifiers, e); + var i; + var doNotReset = {}; + var maxLevel = 0; + var processedSequenceCallback = false; + + // Calculate the maxLevel for sequences so we can only execute the longest callback sequence + for (i = 0; i < callbacks.length; ++i) { + if (callbacks[i].seq) { + maxLevel = Math.max(maxLevel, callbacks[i].level); + } + } + + // loop through matching callbacks for this key event + for (i = 0; i < callbacks.length; ++i) { + + // fire for all sequence callbacks + // this is because if for example you have multiple sequences + // bound such as "g i" and "g t" they both need to fire the + // callback for matching g cause otherwise you can only ever + // match the first one + if (callbacks[i].seq) { + + // only fire callbacks for the maxLevel to prevent + // subsequences from also firing + // + // for example 'a option b' should not cause 'option b' to fire + // even though 'option b' is part of the other sequence + // + // any sequences that do not match here will be discarded + // below by the _resetSequences call + if (callbacks[i].level != maxLevel) { + continue; + } + + processedSequenceCallback = true; + + // keep a list of which sequences were matches for later + doNotReset[callbacks[i].seq] = 1; + _fireCallback(callbacks[i].callback, e, callbacks[i].combo, callbacks[i].seq); + continue; + } + + // if there were no sequence matches but we are still here + // that means this is a regular match so we should fire that + if (!processedSequenceCallback) { + _fireCallback(callbacks[i].callback, e, callbacks[i].combo); + } + } + + // if the key you pressed matches the type of sequence without + // being a modifier (ie "keyup" or "keypress") then we should + // reset all sequences that were not matched by this event + // + // this is so, for example, if you have the sequence "h a t" and you + // type "h e a r t" it does not match. in this case the "e" will + // cause the sequence to reset + // + // modifier keys are ignored because you can have a sequence + // that contains modifiers such as "enter ctrl+space" and in most + // cases the modifier key will be pressed before the next key + // + // also if you have a sequence such as "ctrl+b a" then pressing the + // "b" key will trigger a "keypress" and a "keydown" + // + // the "keydown" is expected when there is a modifier, but the + // "keypress" ends up matching the _nextExpectedAction since it occurs + // after and that causes the sequence to reset + // + // we ignore keypresses in a sequence that directly follow a keydown + // for the same character + var ignoreThisKeypress = e.type == 'keypress' && _ignoreNextKeypress; + if (e.type == _nextExpectedAction && !_isModifier(character) && !ignoreThisKeypress) { + _resetSequences(doNotReset); + } + + _ignoreNextKeypress = processedSequenceCallback && e.type == 'keydown'; + }; /** - * triggers an event that has already been bound + * handles a keydown event * - * @param {string} keys + * @param {Event} e + * @returns void + */ + function _handleKeyEvent(e) { + + // normalize e.which for key events + // @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion + if (typeof e.which !== 'number') { + e.which = e.keyCode; + } + + var character = _characterFromEvent(e); + + // no character found then stop + if (!character) { + return; + } + + // need to use === for the character check because the character can be 0 + if (e.type == 'keyup' && _ignoreNextKeyup === character) { + _ignoreNextKeyup = false; + return; + } + + self.handleKey(character, _eventModifiers(e), e); + } + + /** + * called to set a 1 second timeout on the specified sequence + * + * this is so after each key press in the sequence you have 1 second + * to press the next key before you have to start over + * + * @returns void + */ + function _resetSequenceTimer() { + clearTimeout(_resetTimer); + _resetTimer = setTimeout(_resetSequences, 1000); + } + + /** + * binds a key sequence to an event + * + * @param {string} combo - combo specified in bind call + * @param {Array} keys + * @param {Function} callback * @param {string=} action * @returns void */ - trigger: function(keys, action) { - if (_directMap[keys + ':' + action]) { - _directMap[keys + ':' + action]({}, keys); + function _bindSequence(combo, keys, callback, action) { + + // start off by adding a sequence level record for this combination + // and setting the level to 0 + _sequenceLevels[combo] = 0; + + /** + * callback to increase the sequence level for this sequence and reset + * all other sequences that were active + * + * @param {string} nextAction + * @returns {Function} + */ + function _increaseSequence(nextAction) { + return function() { + _nextExpectedAction = nextAction; + ++_sequenceLevels[combo]; + _resetSequenceTimer(); + }; } - return this; - }, + + /** + * wraps the specified callback inside of another function in order + * to reset all sequence counters as soon as this sequence is done + * + * @param {Event} e + * @returns void + */ + function _callbackAndReset(e) { + _fireCallback(callback, e, combo); + + // we should ignore the next key up if the action is key down + // or keypress. this is so if you finish a sequence and + // release the key the final key will not trigger a keyup + if (action !== 'keyup') { + _ignoreNextKeyup = _characterFromEvent(e); + } + + // weird race condition if a sequence ends with the key + // another sequence begins with + setTimeout(_resetSequences, 10); + } + + // loop through keys one at a time and bind the appropriate callback + // function. for any key leading up to the final one it should + // increase the sequence. after the final, it should reset all sequences + // + // if an action is specified in the original bind call then that will + // be used throughout. otherwise we will pass the action that the + // next key in the sequence should match. this allows a sequence + // to mix and match keypress and keydown events depending on which + // ones are better suited to the key provided + for (var i = 0; i < keys.length; ++i) { + var isFinal = i + 1 === keys.length; + var wrappedCallback = isFinal ? _callbackAndReset : _increaseSequence(action || _getKeyInfo(keys[i + 1]).action); + _bindSingle(keys[i], wrappedCallback, action, combo, i); + } + } /** - * resets the library back to its initial state. this is useful - * if you want to clear out the current keyboard shortcuts and bind - * new ones - for example if you switch to another page + * binds a single keyboard combination * + * @param {string} combination + * @param {Function} callback + * @param {string=} action + * @param {string=} sequenceName - name of sequence if part of sequence + * @param {number=} level - what part of the sequence the command is * @returns void */ - reset: function() { - _callbacks = {}; - _directMap = {}; - return this; - }, + function _bindSingle(combination, callback, action, sequenceName, level) { - /** - * should we stop this event before firing off callbacks - * - * @param {Event} e - * @param {Element} element - * @return {boolean} - */ - stopCallback: function(e, element) { + // store a direct mapped reference for use with Mousetrap.trigger + self._directMap[combination + ':' + action] = callback; - // if the element has the class "mousetrap" then no need to stop - if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) { - return false; + // make sure multiple spaces in a row become a single space + combination = combination.replace(/\s+/g, ' '); + + var sequence = combination.split(' '); + var info; + + // if this pattern is a sequence of keys then run through this method + // to reprocess each pattern one key at a time + if (sequence.length > 1) { + _bindSequence(combination, sequence, callback, action); + return; } - // stop for input, select, and textarea - return element.tagName == 'INPUT' || element.tagName == 'SELECT' || element.tagName == 'TEXTAREA' || element.isContentEditable; - }, + info = _getKeyInfo(combination, action); + + // make sure to initialize array if this is the first time + // a callback is added for this key + self._callbacks[info.key] = self._callbacks[info.key] || []; + + // remove an existing match if there is one + _getMatches(info.key, info.modifiers, {type: info.action}, sequenceName, combination, level); + + // add this call back to the array + // if it is a sequence put it at the beginning + // if not put it at the end + // + // this is important because the way these are processed expects + // the sequence ones to come first + self._callbacks[info.key][sequenceName ? 'unshift' : 'push']({ + callback: callback, + modifiers: info.modifiers, + action: info.action, + seq: sequenceName, + level: level, + combo: combination + }); + } /** - * exposes _handleKey publicly so it can be overwritten by extensions + * binds multiple combinations to the same callback + * + * @param {Array} combinations + * @param {Function} callback + * @param {string|undefined} action + * @returns void */ - handleKey: _handleKey + self._bindMultiple = function(combinations, callback, action) { + for (var i = 0; i < combinations.length; ++i) { + _bindSingle(combinations[i], callback, action); + } + }; + + // start! + _addEvent(targetElement, 'keypress', _handleKeyEvent); + _addEvent(targetElement, 'keydown', _handleKeyEvent); + _addEvent(targetElement, 'keyup', _handleKeyEvent); + } + + /** + * binds an event to mousetrap + * + * can be a single key, a combination of keys separated with +, + * an array of keys, or a sequence of keys separated by spaces + * + * be sure to list the modifier keys first to make sure that the + * correct key ends up getting bound (the last key in the pattern) + * + * @param {string|Array} keys + * @param {Function} callback + * @param {string=} action - 'keypress', 'keydown', or 'keyup' + * @returns void + */ + Mousetrap.prototype.bind = function(keys, callback, action) { + var self = this; + keys = keys instanceof Array ? keys : [keys]; + self._bindMultiple.call(self, keys, callback, action); + return self; }; + /** + * unbinds an event to mousetrap + * + * the unbinding sets the callback function of the specified key combo + * to an empty function and deletes the corresponding key in the + * _directMap dict. + * + * TODO: actually remove this from the _callbacks dictionary instead + * of binding an empty function + * + * the keycombo+action has to be exactly the same as + * it was defined in the bind method + * + * @param {string|Array} keys + * @param {string} action + * @returns void + */ + Mousetrap.prototype.unbind = function(keys, action) { + var self = this; + return self.bind.call(self, keys, function() {}, action); + }; + + /** + * triggers an event that has already been bound + * + * @param {string} keys + * @param {string=} action + * @returns void + */ + Mousetrap.prototype.trigger = function(keys, action) { + var self = this; + if (self._directMap[keys + ':' + action]) { + self._directMap[keys + ':' + action]({}, keys); + } + return self; + }; + + /** + * resets the library back to its initial state. this is useful + * if you want to clear out the current keyboard shortcuts and bind + * new ones - for example if you switch to another page + * + * @returns void + */ + Mousetrap.prototype.reset = function() { + var self = this; + self._callbacks = {}; + self._directMap = {}; + return self; + }; + + /** + * should we stop this event before firing off callbacks + * + * @param {Event} e + * @param {Element} element + * @return {boolean} + */ + Mousetrap.prototype.stopCallback = function(e, element) { + var self = this; + + // if the element has the class "mousetrap" then no need to stop + if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) { + return false; + } + + if (_belongsTo(element, self.target)) { + return false; + } + + // stop for input, select, and textarea + return element.tagName == 'INPUT' || element.tagName == 'SELECT' || element.tagName == 'TEXTAREA' || element.isContentEditable; + }; + + /** + * exposes _handleKey publicly so it can be overwritten by extensions + */ + Mousetrap.prototype.handleKey = function() { + var self = this; + return self._handleKey.apply(self, arguments); + }; + + /** + * Init the global mousetrap functions + * + * This method is needed to allow the global mousetrap functions to work + * now that mousetrap is a constructor function. + */ + Mousetrap.init = function() { + var documentMousetrap = Mousetrap(document); + for (var method in documentMousetrap) { + if (method.charAt(0) !== '_') { + Mousetrap[method] = (function(method) { + return function() { + return documentMousetrap[method].apply(documentMousetrap, arguments); + }; + } (method)); + } + } + }; + + Mousetrap.init(); + // expose mousetrap to the global object window.Mousetrap = Mousetrap; + // expose as a common js module + if (typeof module !== 'undefined' && module.exports) { + module.exports = Mousetrap; + } + // expose mousetrap as an AMD module if (typeof define === 'function' && define.amd) { - define(Mousetrap); + define(function() { + return Mousetrap; + }); } }) (window, document); - -/** - * adds a bindGlobal method to Mousetrap that allows you to - * bind specific keyboard shortcuts that will still work - * inside a text input field - * - * usage: - * Mousetrap.bindGlobal('ctrl+s', _saveChanges); - * Mousetrap.unbindGlobal('ctrl+s'); - */ -/* global Mousetrap:true */ -Mousetrap = (function(Mousetrap) { - var _globalCallbacks = {}, - _originalStopCallback = Mousetrap.stopCallback; - - Mousetrap.stopCallback = function(e, element, combo, sequence) { - if (_globalCallbacks[combo] || _globalCallbacks[sequence]) { - return false; - } - - return _originalStopCallback(e, element, combo); - }; - - Mousetrap.bindGlobal = function(keys, callback, action) { - Mousetrap.bind(keys, callback, action); - - if (keys instanceof Array) { - for (var i = 0; i < keys.length; i++) { - _globalCallbacks[keys[i]] = true; - } - return; - } - - _globalCallbacks[keys] = true; - }; - - Mousetrap.unbindGlobal = function(keys, action) { - Mousetrap.unbind(keys, action); - - if (keys instanceof Array) { - for (var i = 0; i < keys.length; i++) { - _globalCallbacks[keys[i]] = false; - } - return; - } - - _globalCallbacks[keys] = false; - }; - - return Mousetrap; -}) (Mousetrap);