diff --git a/.gitignore b/.gitignore index cf4493d442..57dab91d5e 100644 --- a/.gitignore +++ b/.gitignore @@ -122,3 +122,5 @@ vendor/bundle/* # ignore nodejs files /node_modules /package-lock.json + +/vendor/data/GeoLite2-City.mmdb diff --git a/.overcommit.yml b/.overcommit.yml index 2de35d6df9..8a48ff500e 100644 --- a/.overcommit.yml +++ b/.overcommit.yml @@ -19,5 +19,27 @@ PreCommit: command: ['bundle', 'exec', 'rubocop'] EsLint: enabled: true - command: ['eslint', '--ext', '.es6', '-f', 'compact'] + required_executable: './node_modules/.bin/eslint' + install_command: 'yarn install' + command: ['yarn', 'eslint', '--ext', '.es6', '-f', 'compact'] include: '**/*.es6' + YamlSyntax: + enabled: true + +PostCheckout: + BundleInstall: + enabled: true + YarnInstall: + enabled: true + +PostMerge: + BundleInstall: + enabled: true + YarnInstall: + enabled: true + +PostRewrite: + BundleInstall: + enabled: true + YarnInstall: + enabled: true diff --git a/.travis.yml b/.travis.yml index 3e90410c5d..29b6d0fd7a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -84,6 +84,7 @@ script: else if [ '$QUNIT_RUN' == '1' ]; then bundle exec rake qunit:test['500000'] && \ + bundle exec rake qunit:test['500000','/wizard/qunit'] && \ bundle exec rake plugin:qunit else bundle exec rspec && bundle exec rake plugin:spec diff --git a/Dangerfile b/Dangerfile index 3941cffbed..a2cae25a6c 100644 --- a/Dangerfile +++ b/Dangerfile @@ -2,8 +2,9 @@ if github.pr_json && (github.pr_json["additions"] || 0) > 250 || (github.pr_json warn("This pull request is big! We prefer smaller PRs whenever possible, as they are easier to review. Can this be split into a few smaller PRs?") end -prettier_offenses = `prettier --list-different "app/assets/stylesheets/**/*.scss" "app/assets/javascripts/**/*.es6" "test/javascripts/**/*.es6"`.split('\n') -if !prettier_offenses.empty? +prettier_offenses = `yarn --silent prettier --list-different "app/assets/stylesheets/**/*.scss" "app/assets/javascripts/**/*.es6" "test/javascripts/**/*.es6"`.split("\n") + +unless prettier_offenses.empty? fail(%{ This PR doesn't match our required code formatting standards, as enforced by prettier.io. Here's how to set up prettier in your code editor.\n #{prettier_offenses.map { |o| github.html_link(o) }.join("\n")} diff --git a/Gemfile b/Gemfile index ca22ff21f3..dd079ee829 100644 --- a/Gemfile +++ b/Gemfile @@ -34,7 +34,7 @@ gem 'redis-namespace' gem 'active_model_serializers', '~> 0.8.3' -gem 'onebox', '1.8.60' +gem 'onebox', '1.8.63' gem 'http_accept_language', '~>2.0.5', require: false @@ -194,3 +194,4 @@ end gem 'webpush', require: false gem 'colored2', require: false +gem 'maxminddb' diff --git a/Gemfile.lock b/Gemfile.lock index 69567ed4a4..bdf24bd5ef 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -44,20 +44,20 @@ GEM arel (9.0.0) ast (2.4.0) aws-eventstream (1.0.1) - aws-partitions (1.92.0) - aws-sdk-core (3.21.2) + aws-partitions (1.104.0) + aws-sdk-core (3.27.0) aws-eventstream (~> 1.0) aws-partitions (~> 1.0) aws-sigv4 (~> 1.0) jmespath (~> 1.0) - aws-sdk-kms (1.5.0) - aws-sdk-core (~> 3) + aws-sdk-kms (1.9.0) + aws-sdk-core (~> 3, >= 3.26.0) aws-sigv4 (~> 1.0) - aws-sdk-s3 (1.14.0) - aws-sdk-core (~> 3, >= 3.21.2) + aws-sdk-s3 (1.19.0) + aws-sdk-core (~> 3, >= 3.26.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.0) - aws-sigv4 (1.0.2) + aws-sigv4 (1.0.3) barber (0.12.0) ember-source (>= 1.0, < 3.1) execjs (>= 1.2, < 3) @@ -191,14 +191,15 @@ GEM lru_redux (1.1.0) mail (2.7.1.rc1) mini_mime (>= 0.1.1) - memory_profiler (0.9.10) + maxminddb (0.1.21) + memory_profiler (0.9.12) message_bus (2.1.5) rack (>= 1.1.3) metaclass (0.0.4) method_source (0.8.2) mini_mime (1.0.0) mini_portile2 (2.3.0) - mini_racer (0.2.0) + mini_racer (0.2.3) libv8 (>= 6.3) mini_scheduler (0.8.1) mini_sql (0.1.10) @@ -216,7 +217,7 @@ GEM mustache (1.0.5) nap (1.1.0) no_proxy_fix (0.1.2) - nokogiri (1.8.3) + nokogiri (1.8.5) mini_portile2 (~> 2.3.0) nokogumbo (1.5.0) nokogiri @@ -257,7 +258,7 @@ GEM omniauth-twitter (1.4.0) omniauth-oauth (~> 1.1) rack - onebox (1.8.60) + onebox (1.8.63) htmlentities (~> 4.3) moneta (~> 1.0) multi_json (~> 1.11) @@ -488,6 +489,7 @@ DEPENDENCIES logster lru_redux mail (= 2.7.1.rc1) + maxminddb memory_profiler message_bus mini_mime @@ -510,7 +512,7 @@ DEPENDENCIES omniauth-oauth2 omniauth-openid omniauth-twitter - onebox (= 1.8.60) + onebox (= 1.8.63) openid-redis-store pg pry-nav @@ -555,4 +557,4 @@ DEPENDENCIES webpush BUNDLED WITH - 1.16.4 + 1.16.6 diff --git a/README.md b/README.md index a34a9619b1..e5de54ccff 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,15 @@ Browse [lots more notable Discourse instances](https://www.discourse.org/custome ## Development -1. If you're **brand new to Ruby and Rails**, please see [**Discourse as Your First Rails App**](http://blog.discourse.org/2013/04/discourse-as-your-first-rails-app/). +To get your environment setup, follow the community setup guide for your operating system. -2. If you're familiar with how Rails works and are comfortable setting up your own environment, use our [**Discourse Advanced Developer Guide**](docs/DEVELOPER-ADVANCED.md). +1. If you're on macOS, try the [macOS development guide](https://meta.discourse.org/t/beginners-guide-to-install-discourse-on-macos-for-development/15772). +1. If you're on Ubuntu, try the [Ubuntu development guide](https://meta.discourse.org/t/beginners-guide-to-install-discourse-on-ubuntu-for-development/14727). +1. If you're on Windows, try the [Windows 10 development guide](https://meta.discourse.org/t/beginners-guide-to-install-discourse-on-windows-10-for-development/75149). -Before you get started, ensure you have the following minimum versions: [Ruby 2.4+](http://www.ruby-lang.org/en/downloads/), [PostgreSQL 9.3+](http://www.postgresql.org/download/), [Redis 2.6+](http://redis.io/download). If you're having trouble, please see our [**TROUBLESHOOTING GUIDE**](docs/TROUBLESHOOTING.md) first! +If you're familiar with how Rails works and are comfortable setting up your own environment, you can also try out the [**Discourse Advanced Developer Guide**](docs/DEVELOPER-ADVANCED.md), which is aimed primarily at Ubuntu and macOS environments. + +Before you get started, ensure you have the following minimum versions: [Ruby 2.4+](http://www.ruby-lang.org/en/downloads/), [PostgreSQL 10+](http://www.postgresql.org/download/), [Redis 2.6+](http://redis.io/download). If you're having trouble, please see our [**TROUBLESHOOTING GUIDE**](docs/TROUBLESHOOTING.md) first! ## Setting up Discourse @@ -38,12 +42,12 @@ If you're looking for business class hosting, see [discourse.org/buy](https://ww Discourse is built for the *next* 10 years of the Internet, so our requirements are high: -| Browsers | Tablets | Phones | -| -------- | ------- | ----------- | -| Safari 6.1+ | iPad 3+ | iOS 8+ | -| Google Chrome 32+ | Android 4.3+ | Android 4.3+ | -| Internet Explorer 11+ | | | -| Firefox 27+ | | | +| Browsers | Tablets | Phones | +| --------------------- | ------------ | ------------ | +| Safari 6.1+ | iPad 3+ | iOS 8+ | +| Google Chrome 32+ | Android 4.3+ | Android 4.3+ | +| Internet Explorer 11+ | | | +| Firefox 27+ | | | ## Built With diff --git a/app/assets/images/chosen-sprite.png b/app/assets/images/chosen-sprite.png deleted file mode 100644 index ea5f706b20..0000000000 Binary files a/app/assets/images/chosen-sprite.png and /dev/null differ diff --git a/app/assets/javascripts/admin/components/ace-editor.js.es6 b/app/assets/javascripts/admin/components/ace-editor.js.es6 index 192bc4b410..f0f5750469 100644 --- a/app/assets/javascripts/admin/components/ace-editor.js.es6 +++ b/app/assets/javascripts/admin/components/ace-editor.js.es6 @@ -1,8 +1,6 @@ import loadScript from "discourse/lib/load-script"; import { observes } from "ember-addons/ember-computed-decorators"; -const LOAD_ASYNC = !Ember.testing; - export default Ember.Component.extend({ mode: "css", classNames: ["ace-wrapper"], @@ -26,7 +24,7 @@ export default Ember.Component.extend({ @observes("mode") modeChanged() { - if (LOAD_ASYNC && this._editor && !this._skipContentChangeEvent) { + if (this._editor && !this._skipContentChangeEvent) { this._editor.getSession().setMode("ace/mode/" + this.get("mode")); } }, @@ -71,21 +69,17 @@ export default Ember.Component.extend({ didInsertElement() { this._super(); - loadScript("/javascripts/ace/ace.js", { scriptTag: true }).then(() => { + loadScript("/javascripts/ace/ace.js").then(() => { window.ace.require(["ace/ace"], loadedAce => { if (!this.element || this.isDestroying || this.isDestroyed) { return; } const editor = loadedAce.edit(this.$(".ace")[0]); - if (LOAD_ASYNC) { - editor.setTheme("ace/theme/chrome"); - } + editor.setTheme("ace/theme/chrome"); editor.setShowPrintMargin(false); editor.setOptions({ fontSize: "14px" }); - if (LOAD_ASYNC) { - editor.getSession().setMode("ace/mode/" + this.get("mode")); - } + editor.getSession().setMode("ace/mode/" + this.get("mode")); editor.on("change", () => { this._skipContentChangeEvent = true; this.set("content", editor.getSession().getValue()); diff --git a/app/assets/javascripts/admin/components/admin-backups-logs.js.es6 b/app/assets/javascripts/admin/components/admin-backups-logs.js.es6 index c2f9df5205..9c92228b8c 100644 --- a/app/assets/javascripts/admin/components/admin-backups-logs.js.es6 +++ b/app/assets/javascripts/admin/components/admin-backups-logs.js.es6 @@ -2,6 +2,7 @@ import debounce from "discourse/lib/debounce"; import { renderSpinner } from "discourse/helpers/loading-spinner"; import { escapeExpression } from "discourse/lib/utilities"; import { bufferedRender } from "discourse-common/lib/buffered-render"; +import { observes, on } from "ember-addons/ember-computed-decorators"; export default Ember.Component.extend( bufferedRender({ @@ -21,30 +22,38 @@ export default Ember.Component.extend( $div.scrollTop = $div.scrollHeight; }, - _updateFormattedLogs: debounce(function() { - const logs = this.get("logs"); - if (logs.length === 0) { + @on("init") + @observes("logs.[]") + _resetFormattedLogs() { + if (this.get("logs").length === 0) { this._reset(); // reset the cached logs whenever the model is reset - } else { - // do the log formatting only once for HELLish performance - let formattedLogs = this.get("formattedLogs"); - for (let i = this.get("index"), length = logs.length; i < length; i++) { - const date = logs[i].get("timestamp"), - message = escapeExpression(logs[i].get("message")); - formattedLogs += "[" + date + "] " + message + "\n"; - } - // update the formatted logs & cache index - this.setProperties({ - formattedLogs: formattedLogs, - index: logs.length - }); - // force rerender this.rerenderBuffer(); } + }, + + @on("init") + @observes("logs.[]") + _updateFormattedLogs: debounce(function() { + const logs = this.get("logs"); + if (logs.length === 0) return; + + // do the log formatting only once for HELLish performance + let formattedLogs = this.get("formattedLogs"); + for (let i = this.get("index"), length = logs.length; i < length; i++) { + const date = logs[i].get("timestamp"), + message = escapeExpression(logs[i].get("message")); + formattedLogs += "[" + date + "] " + message + "\n"; + } + // update the formatted logs & cache index + this.setProperties({ + formattedLogs: formattedLogs, + index: logs.length + }); + // force rerender + this.rerenderBuffer(); + Ember.run.scheduleOnce("afterRender", this, this._scrollDown); - }, 150) - .observes("logs.[]") - .on("init"), + }, 150), buildBuffer(buffer) { const formattedLogs = this.get("formattedLogs"); diff --git a/app/assets/javascripts/admin/components/themes-list-item.js.es6 b/app/assets/javascripts/admin/components/themes-list-item.js.es6 new file mode 100644 index 0000000000..44f337dd76 --- /dev/null +++ b/app/assets/javascripts/admin/components/themes-list-item.js.es6 @@ -0,0 +1,136 @@ +import { + default as computed, + observes +} from "ember-addons/ember-computed-decorators"; + +const MAX_COMPONENTS = 4; + +export default Ember.Component.extend({ + childrenExpanded: false, + classNames: ["themes-list-item"], + classNameBindings: ["theme.selected:selected"], + hasComponents: Em.computed.gt("children.length", 0), + displayComponents: Em.computed.and("hasComponents", "theme.isActive"), + displayHasMore: Em.computed.gt("theme.childThemes.length", MAX_COMPONENTS), + + click(e) { + if (!$(e.target).hasClass("others-count")) { + this.navigateToTheme(); + } + }, + + init() { + this._super(...arguments); + this.scheduleAnimation(); + }, + + @observes("theme.selected") + triggerAnimation() { + this.animate(); + }, + + scheduleAnimation() { + Ember.run.schedule("afterRender", () => { + this.animate(true); + }); + }, + + animate(isInitial) { + const $container = this.$(); + const $list = this.$(".components-list"); + if ($list.length === 0 || Ember.testing) { + return; + } + const duration = 300; + if (this.get("theme.selected")) { + this.collapseComponentsList($container, $list, duration); + } else if (!isInitial) { + this.expandComponentsList($container, $list, duration); + } + }, + + @computed( + "theme.component", + "theme.childThemes.@each.name", + "theme.childThemes.length", + "childrenExpanded" + ) + children() { + const theme = this.get("theme"); + let children = theme.get("childThemes"); + if (theme.get("component") || !children) { + return []; + } + children = this.get("childrenExpanded") + ? children + : children.slice(0, MAX_COMPONENTS); + return children.map(t => t.get("name")); + }, + + @computed( + "theme.childThemes.length", + "theme.component", + "childrenExpanded", + "children.length" + ) + moreCount(childrenCount, component, expanded) { + if (component || !childrenCount || expanded) { + return 0; + } + return childrenCount - MAX_COMPONENTS; + }, + + expandComponentsList($container, $list, duration) { + $container.css("height", `${$container.height()}px`); + $list.css("display", ""); + $container.animate( + { + height: `${$container.height() + $list.outerHeight(true)}px` + }, + { + duration, + done: () => { + $list.css("display", ""); + $container.css("height", ""); + } + } + ); + $list.animate( + { + opacity: 1 + }, + { + duration + } + ); + }, + + collapseComponentsList($container, $list, duration) { + $container.animate( + { + height: `${$container.height() - $list.outerHeight(true)}px` + }, + { + duration, + done: () => { + $list.css("display", "none"); + $container.css("height", ""); + } + } + ); + $list.animate( + { + opacity: 0 + }, + { + duration + } + ); + }, + + actions: { + toggleChildrenExpanded() { + this.toggleProperty("childrenExpanded"); + } + } +}); diff --git a/app/assets/javascripts/admin/components/themes-list.js.es6 b/app/assets/javascripts/admin/components/themes-list.js.es6 index 5e40d157fb..da14b6492a 100644 --- a/app/assets/javascripts/admin/components/themes-list.js.es6 +++ b/app/assets/javascripts/admin/components/themes-list.js.es6 @@ -1,4 +1,87 @@ +import { THEMES, COMPONENTS } from "admin/models/theme"; +import { default as computed } from "ember-addons/ember-computed-decorators"; + export default Ember.Component.extend({ + THEMES: THEMES, + COMPONENTS: COMPONENTS, + classNames: ["themes-list"], - hasThemes: Ember.computed.gt("themes.length", 0) + + hasThemes: Em.computed.gt("themesList.length", 0), + hasUserThemes: Em.computed.gt("userThemes.length", 0), + hasInactiveThemes: Em.computed.gt("inactiveThemes.length", 0), + + themesTabActive: Em.computed.equal("currentTab", THEMES), + componentsTabActive: Em.computed.equal("currentTab", COMPONENTS), + + @computed("themes", "components", "currentTab") + themesList(themes, components) { + if (this.get("themesTabActive")) { + return themes; + } else { + return components; + } + }, + + @computed( + "themesList", + "currentTab", + "themesList.@each.user_selectable", + "themesList.@each.default" + ) + inactiveThemes(themes) { + if (this.get("componentsTabActive")) { + return []; + } + return themes.filter( + theme => !theme.get("user_selectable") && !theme.get("default") + ); + }, + + @computed( + "themesList", + "currentTab", + "themesList.@each.user_selectable", + "themesList.@each.default" + ) + userThemes(themes) { + if (this.get("componentsTabActive")) { + return []; + } + themes = themes.filter( + theme => theme.get("user_selectable") || theme.get("default") + ); + return _.sortBy(themes, t => { + return [ + !t.get("default"), + !t.get("user_selectable"), + t.get("name").toLowerCase() + ]; + }); + }, + + didRender() { + this._super(...arguments); + + // hide scrollbar + const $container = this.$(".themes-list-container"); + const containerNode = $container[0]; + if (containerNode) { + const width = containerNode.offsetWidth - containerNode.clientWidth; + $container.css("width", `calc(100% + ${width}px)`); + } + }, + + actions: { + changeView(newTab) { + if (newTab !== this.get("currentTab")) { + this.set("currentTab", newTab); + } + }, + navigateToTheme(theme) { + Em.getOwner(this) + .lookup("router:main") + .transitionTo("adminCustomizeThemes.show", theme); + } + } }); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-themes-edit.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-themes-edit.js.es6 index 7cbe893fe5..c8082cc84d 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-themes-edit.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-themes-edit.js.es6 @@ -5,8 +5,10 @@ import { } from "ember-addons/ember-computed-decorators"; export default Ember.Controller.extend({ - maximized: false, section: null, + currentTarget: 0, + maximized: false, + previewUrl: url("model.id", "/admin/themes/%@/preview"), editRouteName: "adminCustomizeThemes.edit", @@ -86,8 +88,6 @@ export default Ember.Controller.extend({ return this.get("model").hasEdited(target); }, - currentTarget: 0, - setTargetName: function(name) { const target = this.get("targets").find(t => t.name === name); this.set("currentTarget", target && target.id); @@ -152,21 +152,20 @@ export default Ember.Controller.extend({ }); }, - previewUrl: url("model.id", "/admin/themes/%@/preview"), + @computed("maximized") + maximizeIcon(maximized) { + return maximized ? "compress" : "expand"; + }, - maximizeIcon: function() { - return this.get("maximized") ? "compress" : "expand"; - }.property("maximized"), + @computed("model.isSaving") + saveButtonText(isSaving) { + return isSaving ? I18n.t("saving") : I18n.t("admin.customize.save"); + }, - saveButtonText: function() { - return this.get("model.isSaving") - ? I18n.t("saving") - : I18n.t("admin.customize.save"); - }.property("model.isSaving"), - - saveDisabled: function() { - return !this.get("model.changed") || this.get("model.isSaving"); - }.property("model.changed", "model.isSaving"), + @computed("model.changed", "model.isSaving") + saveDisabled(changed, isSaving) { + return !changed || isSaving; + }, actions: { save() { diff --git a/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6 index 40ce1b37c7..66f72768de 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6 @@ -1,119 +1,88 @@ -import { - default as computed, - observes -} from "ember-addons/ember-computed-decorators"; +import { default as computed } from "ember-addons/ember-computed-decorators"; import { url } from "discourse/lib/computed"; import { popupAjaxError } from "discourse/lib/ajax-error"; import showModal from "discourse/lib/show-modal"; import ThemeSettings from "admin/models/theme-settings"; +import { THEMES, COMPONENTS } from "admin/models/theme"; const THEME_UPLOAD_VAR = 2; -const SETTINGS_TYPE_ID = 5; export default Ember.Controller.extend({ + downloadUrl: url("model.id", "/admin/themes/%@"), + previewUrl: url("model.id", "/admin/themes/%@/preview"), + addButtonDisabled: Em.computed.empty("selectedChildThemeId"), editRouteName: "adminCustomizeThemes.edit", - @observes("allowChildThemes") - setSelectedThemeId() { - const available = this.get("selectableChildThemes"); - if ( - !this.get("selectedChildThemeId") && - available && - available.length > 0 - ) { - this.set("selectedChildThemeId", available[0].get("id")); - } - }, - @computed("model", "allThemes", "model.component") parentThemes(model, allThemes) { if (!model.get("component")) { return null; } - let parents = allThemes.filter(theme => + const parents = allThemes.filter(theme => _.contains(theme.get("childThemes"), model) ); return parents.length === 0 ? null : parents; }, - @computed("model.theme_fields.@each") - hasEditedFields(fields) { - return fields.any( - f => !Em.isBlank(f.value) && f.type_id !== SETTINGS_TYPE_ID - ); - }, - - @computed("model.theme_fields.@each") - editedDescriptions(fields) { - let descriptions = []; - let description = target => { - let current = fields.filter( - field => field.target === target && !Em.isBlank(field.value) - ); - if (current.length > 0) { - let text = I18n.t("admin.customize.theme." + target); - let localized = current.map(f => - I18n.t("admin.customize.theme." + f.name + ".text") - ); - return text + ": " + localized.join(" , "); - } - }; + @computed("model.editedFields") + editedFieldsFormatted() { + const descriptions = []; ["common", "desktop", "mobile"].forEach(target => { - descriptions.push(description(target)); + const fields = this.editedFieldsForTarget(target); + if (fields.length < 1) { + return; + } + let resultString = I18n.t("admin.customize.theme." + target); + const formattedFields = fields + .map(f => I18n.t("admin.customize.theme." + f.name + ".text")) + .join(" , "); + resultString += `: ${formattedFields}`; + descriptions.push(resultString); }); - return descriptions.reject(d => Em.isBlank(d)); + return descriptions; }, - previewUrl: url("model.id", "/admin/themes/%@/preview"), - @computed("colorSchemeId", "model.color_scheme_id") colorSchemeChanged(colorSchemeId, existingId) { colorSchemeId = colorSchemeId === null ? null : parseInt(colorSchemeId); return colorSchemeId !== existingId; }, - @computed( - "availableChildThemes", - "model.childThemes.@each", - "model", - "allowChildThemes" - ) - selectableChildThemes(available, childThemes, allowChildThemes) { - if (!allowChildThemes && (!childThemes || childThemes.length === 0)) { - return null; + @computed("availableChildThemes", "model.childThemes.@each", "model") + selectableChildThemes(available, childThemes) { + if (available) { + const themes = !childThemes + ? available + : available.filter(theme => childThemes.indexOf(theme) === -1); + return themes.length === 0 ? null : themes; } - - let themes = []; - available.forEach(t => { - if (!childThemes || childThemes.indexOf(t) === -1) { - themes.push(t); - } - }); - return themes.length === 0 ? null : themes; }, - @computed("allThemes", "allThemes.length", "model.component", "model") - availableChildThemes(allThemes, count, component) { - if (count === 1 || component) { - return null; + @computed("allThemes", "model.component", "model") + availableChildThemes(allThemes) { + if (!this.get("model.component")) { + const themeId = this.get("model.id"); + return allThemes.filter( + theme => theme.get("id") !== themeId && theme.get("component") + ); } - - const themeId = this.get("model.id"); - - let themes = []; - allThemes.forEach(theme => { - if (themeId !== theme.get("id") && theme.get("component")) { - themes.push(theme); - } - }); - - return themes; }, @computed("model.component") - switchKey(component) { + convertKey(component) { const type = component ? "component" : "theme"; - return `admin.customize.theme.switch_${type}`; + return `admin.customize.theme.convert_${type}`; + }, + + @computed("model.component") + convertIcon(component) { + return component ? "cube" : ""; + }, + + @computed("model.component") + convertTooltip(component) { + const type = component ? "component" : "theme"; + return `admin.customize.theme.convert_${type}_tooltip`; }, @computed("model.settings") @@ -126,8 +95,65 @@ export default Ember.Controller.extend({ return settings.length > 0; }, - downloadUrl: url("model.id", "/admin/themes/%@"), + @computed("model.remoteError", "updatingRemote") + showRemoteError(errorMessage, updating) { + return errorMessage && !updating; + }, + editedFieldsForTarget(target) { + return this.get("model.editedFields").filter( + field => field.target === target + ); + }, + + commitSwitchType() { + const model = this.get("model"); + const newValue = !model.get("component"); + model.set("component", newValue); + + if (newValue) { + this.set("parentController.currentTab", COMPONENTS); + } else { + this.set("parentController.currentTab", THEMES); + } + + model + .saveChanges("component") + .then(() => { + this.set("colorSchemeId", null); + + model.setProperties({ + default: false, + color_scheme_id: null, + user_selectable: false, + child_themes: [], + childThemes: [] + }); + + this.get("parentController.model.content").forEach(theme => { + const children = _.toArray(theme.get("childThemes")); + const rawChildren = _.toArray(theme.get("child_themes") || []); + const index = children ? children.indexOf(model) : -1; + if (index > -1) { + children.splice(index, 1); + rawChildren.splice(index, 1); + theme.setProperties({ + childThemes: children, + child_themes: rawChildren + }); + } + }); + }) + .catch(popupAjaxError); + }, + transitionToEditRoute() { + this.transitionToRoute( + this.get("editRouteName"), + this.get("model.id"), + "common", + "scss" + ); + }, actions: { updateToLatest() { this.set("updatingRemote", true); @@ -184,25 +210,17 @@ export default Ember.Controller.extend({ }, editTheme() { - let edit = () => - this.transitionToRoute( - this.get("editRouteName"), - this.get("model.id"), - "common", - "scss" - ); - if (this.get("model.remote_theme")) { bootbox.confirm( I18n.t("admin.customize.theme.edit_confirm"), result => { if (result) { - edit(); + this.transitionToEditRoute(); } } ); } else { - edit(); + this.transitionToEditRoute(); } }, @@ -264,30 +282,26 @@ export default Ember.Controller.extend({ }, switchType() { - return bootbox.confirm( - I18n.t(`${this.get("switchKey")}_alert`), - I18n.t("no_value"), - I18n.t("yes_value"), - result => { - if (result) { - const model = this.get("model"); - model.set("component", !model.get("component")); - model - .saveChanges("component") - .then(() => { - this.set("colorSchemeId", null); - model.setProperties({ - default: false, - color_scheme_id: null, - user_selectable: false, - child_themes: [], - childThemes: [] - }); - }) - .catch(popupAjaxError); + const relatives = this.get("model.component") + ? this.get("parentThemes") + : this.get("model.childThemes"); + if (relatives && relatives.length > 0) { + const names = relatives.map(relative => relative.get("name")); + bootbox.confirm( + I18n.t(`${this.get("convertKey")}_alert`, { + relatives: names.join(", ") + }), + I18n.t("no_value"), + I18n.t("yes_value"), + result => { + if (result) { + this.commitSwitchType(); + } } - } - ); + ); + } else { + this.commitSwitchType(); + } } } }); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-themes.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-themes.js.es6 index 8468634a0a..641ec62826 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-themes.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-themes.js.es6 @@ -1,18 +1,15 @@ import { default as computed } from "ember-addons/ember-computed-decorators"; +import { THEMES } from "admin/models/theme"; export default Ember.Controller.extend({ - @computed("model", "model.@each", "model.@each.component") + currentTab: THEMES, + + @computed("model", "model.@each.component") fullThemes(themes) { - return _.sortBy(themes.filter(t => !t.get("component")), t => { - return [ - !t.get("default"), - !t.get("user_selectable"), - t.get("name").toLowerCase() - ]; - }); + return themes.filter(t => !t.get("component")); }, - @computed("model", "model.@each", "model.@each.component") + @computed("model", "model.@each.component") childThemes(themes) { return themes.filter(t => t.get("component")); } diff --git a/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 index 2fbac162ce..0020dae6ec 100644 --- a/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 @@ -11,6 +11,7 @@ export default Ember.Controller.extend(CanCheckEmails, { editingName: false, editingTitle: false, originalPrimaryGroupId: null, + customGroupIdsBuffer: null, availableGroups: null, userTitleValue: null, @@ -30,6 +31,20 @@ export default Ember.Controller.extend(CanCheckEmails, { "model.can_disable_second_factor" ), + @computed("model.customGroups") + customGroupIds(customGroups) { + return customGroups.mapBy("id"); + }, + + @computed("customGroupIdsBuffer", "customGroupIds") + customGroupsDirty(buffer, original) { + if (buffer === null) return false; + + return buffer.length === original.length + ? buffer.any(id => !original.includes(id)) + : true; + }, + @computed("model.automaticGroups") automaticGroups(automaticGroups) { return automaticGroups @@ -105,6 +120,27 @@ export default Ember.Controller.extend(CanCheckEmails, { } }, + groupAdded(added) { + this.get("model") + .groupAdded(added) + .catch(function() { + bootbox.alert(I18n.t("generic_error")); + }); + }, + + groupRemoved(groupId) { + this.get("model") + .groupRemoved(groupId) + .then(() => { + if (groupId === this.get("originalPrimaryGroupId")) { + this.set("originalPrimaryGroupId", null); + } + }) + .catch(function() { + bootbox.alert(I18n.t("generic_error")); + }); + }, + actions: { impersonate() { return this.get("model").impersonate(); @@ -278,20 +314,22 @@ export default Ember.Controller.extend(CanCheckEmails, { this.get("model").generateApiKey(); }, - groupAdded(added) { - this.get("model") - .groupAdded(added) - .catch(function() { - bootbox.alert(I18n.t("generic_error")); - }); + saveCustomGroups() { + const currentIds = this.get("customGroupIds"); + const bufferedIds = this.get("customGroupIdsBuffer"); + const availableGroups = this.get("availableGroups"); + + bufferedIds.filter(id => !currentIds.includes(id)).forEach(id => { + this.groupAdded(availableGroups.findBy("id", id)); + }); + + currentIds + .filter(id => !bufferedIds.includes(id)) + .forEach(id => this.groupRemoved(id)); }, - groupRemoved(groupId) { - this.get("model") - .groupRemoved(groupId) - .catch(function() { - bootbox.alert(I18n.t("generic_error")); - }); + resetCustomGroups() { + this.set("customGroupIdsBuffer", null); }, savePrimaryGroup() { diff --git a/app/assets/javascripts/admin/controllers/admin.js.es6 b/app/assets/javascripts/admin/controllers/admin.js.es6 index b17b4e86c1..afc8b7c46b 100644 --- a/app/assets/javascripts/admin/controllers/admin.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin.js.es6 @@ -3,9 +3,14 @@ import computed from "ember-addons/ember-computed-decorators"; export default Ember.Controller.extend({ application: Ember.inject.controller(), - @computed - showBadges() { - return this.currentUser.get("admin") && this.siteSettings.enable_badges; + @computed("siteSettings.enable_group_directory") + showGroups(enableGroupDirectory) { + return !enableGroupDirectory; + }, + + @computed("siteSettings.enable_badges") + showBadges(enableBadges) { + return this.currentUser.get("admin") && enableBadges; }, @computed("application.currentPath") diff --git a/app/assets/javascripts/admin/controllers/modals/admin-create-theme.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-create-theme.js.es6 index 343be61eb1..4b25e006c2 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-create-theme.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/admin-create-theme.js.es6 @@ -1,27 +1,56 @@ import ModalFunctionality from "discourse/mixins/modal-functionality"; import { default as computed } from "ember-addons/ember-computed-decorators"; import { popupAjaxError } from "discourse/lib/ajax-error"; +import { THEMES, COMPONENTS } from "admin/models/theme"; -const COMPONENT = "component"; +const MIN_NAME_LENGTH = 4; export default Ember.Controller.extend(ModalFunctionality, { - types: [ - { name: I18n.t("admin.customize.theme.theme"), value: "theme" }, - { name: I18n.t("admin.customize.theme.component"), value: COMPONENT } - ], - selectedType: "theme", - name: I18n.t("admin.customize.new_style"), + saving: false, + triggerError: false, themesController: Ember.inject.controller("adminCustomizeThemes"), - loading: false, + types: [ + { name: I18n.t("admin.customize.theme.theme"), value: THEMES }, + { name: I18n.t("admin.customize.theme.component"), value: COMPONENTS } + ], + + @computed("triggerError", "nameTooShort") + showError(trigger, tooShort) { + return trigger && tooShort; + }, + + @computed("name") + nameTooShort(name) { + return !name || name.length < MIN_NAME_LENGTH; + }, + + @computed("component") + placeholder(component) { + if (component) { + return I18n.t("admin.customize.theme.component_name"); + } else { + return I18n.t("admin.customize.theme.theme_name"); + } + }, + + @computed("themesController.currentTab") + selectedType(tab) { + return tab; + }, @computed("selectedType") component(type) { - return type === COMPONENT; + return type === COMPONENTS; }, actions: { createTheme() { - this.set("loading", true); + if (this.get("nameTooShort")) { + this.set("triggerError", true); + return; + } + + this.set("saving", true); const theme = this.store.createRecord("theme"); theme .save({ name: this.get("name"), component: this.get("component") }) @@ -30,7 +59,7 @@ export default Ember.Controller.extend(ModalFunctionality, { this.send("closeModal"); }) .catch(popupAjaxError) - .finally(() => this.set("loading", false)); + .finally(() => this.set("saving", false)); } } }); diff --git a/app/assets/javascripts/admin/controllers/modals/admin-import-theme.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-import-theme.js.es6 index 9ce6105acb..4b9a5aa6dd 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-import-theme.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/admin-import-theme.js.es6 @@ -44,7 +44,8 @@ export default Ember.Controller.extend(ModalFunctionality, { options.data.append("theme", $("#file-input")[0].files[0]); } else { options.data = { - remote: this.get("uploadUrl") + remote: this.get("uploadUrl"), + branch: this.get("branch") }; if (this.get("privateChecked")) { diff --git a/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 index 18237198ba..7bd96b326a 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 @@ -1,24 +1,17 @@ import ModalFunctionality from "discourse/mixins/modal-functionality"; -import Backup from "admin/models/backup"; export default Ember.Controller.extend(ModalFunctionality, { adminBackupsLogs: Ember.inject.controller(), - _startBackup(withUploads) { - this.currentUser.set("hideReadOnlyAlert", true); - Backup.start(withUploads).then(() => { - this.get("adminBackupsLogs.logs").clear(); - this.send("backupStarted"); - }); - }, - actions: { - startBackup() { - this._startBackup(); + startBackupWithUploads() { + this.send("closeModal"); + this.send("startBackup", true); }, - startBackupWithoutUpload() { - this._startBackup(false); + startBackupWithoutUploads() { + this.send("closeModal"); + this.send("startBackup", false); }, cancel() { diff --git a/app/assets/javascripts/admin/models/theme.js.es6 b/app/assets/javascripts/admin/models/theme.js.es6 index c3d7fd800d..da881abf9b 100644 --- a/app/assets/javascripts/admin/models/theme.js.es6 +++ b/app/assets/javascripts/admin/models/theme.js.es6 @@ -4,8 +4,15 @@ import { popupAjaxError } from "discourse/lib/ajax-error"; const THEME_UPLOAD_VAR = 2; +export const THEMES = "themes"; +export const COMPONENTS = "components"; +const SETTINGS_TYPE_ID = 5; + const Theme = RestModel.extend({ FIELDS_IDS: [0, 1], + isActive: Em.computed.or("default", "user_selectable"), + isPendingUpdates: Em.computed.gt("remote_theme.commits_behind", 0), + hasEditedFields: Em.computed.gt("editedFields.length", 0), @computed("theme_fields") themeFields(fields) { @@ -33,6 +40,27 @@ const Theme = RestModel.extend({ ); }, + @computed("theme_fields", "theme_fields.@each.error") + isBroken(fields) { + return ( + fields && fields.some(field => field.error && field.error.length > 0) + ); + }, + + @computed("theme_fields.@each") + editedFields(fields) { + return fields.filter( + field => !Em.isBlank(field.value) && field.type_id !== SETTINGS_TYPE_ID + ); + }, + + @computed("remote_theme.last_error_text") + remoteError(errorText) { + if (errorText && errorText.length > 0) { + return errorText; + } + }, + getKey(field) { return `${field.target} ${field.name}`; }, diff --git a/app/assets/javascripts/admin/routes/admin-backups.js.es6 b/app/assets/javascripts/admin/routes/admin-backups.js.es6 index 2d9f185cca..a0b9342c61 100644 --- a/app/assets/javascripts/admin/routes/admin-backups.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-backups.js.es6 @@ -10,6 +10,7 @@ export default Discourse.Route.extend({ activate() { this.messageBus.subscribe(LOG_CHANNEL, log => { if (log.message === "[STARTED]") { + Discourse.User.currentProp("hideReadOnlyAlert", true); this.controllerFor("adminBackups").set( "model.isOperationRunning", true @@ -62,15 +63,14 @@ export default Discourse.Route.extend({ }, actions: { - startBackup() { + showStartBackupModal() { showModal("admin-start-backup", { admin: true }); this.controllerFor("modal").set("modalClass", "start-backup-modal"); }, - backupStarted() { - this.controllerFor("adminBackups").set("isOperationRunning", true); + startBackup(withUploads) { this.transitionTo("admin.backups.logs"); - this.send("closeModal"); + Backup.start(withUploads); }, destroyBackup(backup) { @@ -100,17 +100,8 @@ export default Discourse.Route.extend({ I18n.t("yes_value"), function(confirmed) { if (confirmed) { - Discourse.User.currentProp("hideReadOnlyAlert", true); - backup.restore().then(function() { - self - .controllerFor("adminBackupsLogs") - .get("logs") - .clear(); - self - .controllerFor("adminBackups") - .set("model.isOperationRunning", true); - self.transitionTo("admin.backups.logs"); - }); + self.transitionTo("admin.backups.logs"); + backup.restore(); } } ); diff --git a/app/assets/javascripts/admin/routes/admin-customize-themes-edit.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-themes-edit.js.es6 index 7b63658ac0..5bab290091 100644 --- a/app/assets/javascripts/admin/routes/admin-customize-themes-edit.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-customize-themes-edit.js.es6 @@ -35,5 +35,29 @@ export default Ember.Route.extend({ controller.setTargetName(wrapper.target || "common"); controller.set("fieldName", wrapper.field_name || "scss"); this.controllerFor("adminCustomizeThemes").set("editingTheme", true); + this.set("shouldAlertUnsavedChanges", true); + }, + + actions: { + willTransition(transition) { + if ( + this.get("controller.model.changed") && + this.get("shouldAlertUnsavedChanges") && + transition.intent.name !== this.routeName + ) { + transition.abort(); + bootbox.confirm( + I18n.t("admin.customize.theme.unsaved_changes_alert"), + I18n.t("admin.customize.theme.discard"), + I18n.t("admin.customize.theme.stay"), + result => { + if (!result) { + this.set("shouldAlertUnsavedChanges", false); + transition.retry(); + } + } + ); + } + } } }); diff --git a/app/assets/javascripts/admin/routes/admin-customize-themes-index.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-themes-index.js.es6 index e1a5bf51db..ea09122d62 100644 --- a/app/assets/javascripts/admin/routes/admin-customize-themes-index.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-customize-themes-index.js.es6 @@ -1,5 +1,30 @@ +import { emojiUrlFor } from "discourse/lib/text"; + +const externalResources = [ + { + key: "admin.customize.theme.beginners_guide_title", + link: "https://meta.discourse.org/t/91966", + icon: "book" + }, + { + key: "admin.customize.theme.developers_guide_title", + link: "https://meta.discourse.org/t/93648", + icon: "book" + }, + { + key: "admin.customize.theme.browse_themes", + link: "https://meta.discourse.org/c/theme", + icon: "paint-brush" + } +]; + export default Ember.Route.extend({ - setupController() { + setupController(controller) { + this._super(...arguments); this.controllerFor("adminCustomizeThemes").set("editingTheme", false); + controller.setProperties({ + externalResources, + womanArtistEmojiURL: emojiUrlFor("woman_artist:t5") + }); } }); diff --git a/app/assets/javascripts/admin/routes/admin-customize-themes-show.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-themes-show.js.es6 index e9ca55bb38..f39b747ef7 100644 --- a/app/assets/javascripts/admin/routes/admin-customize-themes-show.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-customize-themes-show.js.es6 @@ -1,4 +1,5 @@ import { scrollTop } from "discourse/mixins/scroll-top"; +import { THEMES, COMPONENTS } from "admin/models/theme"; export default Ember.Route.extend({ serialize(model) { @@ -14,19 +15,21 @@ export default Ember.Route.extend({ setupController(controller, model) { this._super(...arguments); - controller.set("model", model); - const parentController = this.controllerFor("adminCustomizeThemes"); - parentController.set("editingTheme", false); - controller.set("allThemes", parentController.get("model")); + parentController.setProperties({ + editingTheme: false, + currentTab: model.get("component") ? COMPONENTS : THEMES + }); + + controller.setProperties({ + model: model, + parentController: parentController, + allThemes: parentController.get("model"), + colorSchemeId: model.get("color_scheme_id"), + colorSchemes: parentController.get("model.extras.color_schemes") + }); this.handleHighlight(model); - - controller.set( - "colorSchemes", - parentController.get("model.extras.color_schemes") - ); - controller.set("colorSchemeId", model.get("color_scheme_id")); }, deactivate() { @@ -34,9 +37,11 @@ export default Ember.Route.extend({ }, handleHighlight(theme) { - this.get("controller.allThemes").forEach(t => t.set("active", false)); + this.get("controller.allThemes") + .filter(t => t.get("selected")) + .forEach(t => t.set("selected", false)); if (theme) { - theme.set("active", true); + theme.set("selected", true); } }, diff --git a/app/assets/javascripts/admin/templates/admin.hbs b/app/assets/javascripts/admin/templates/admin.hbs index 495a51cf46..415239a656 100644 --- a/app/assets/javascripts/admin/templates/admin.hbs +++ b/app/assets/javascripts/admin/templates/admin.hbs @@ -10,6 +10,9 @@ {{nav-item route='adminSiteSettings' label='admin.site_settings.title'}} {{/if}} {{nav-item route='adminUsersList' label='admin.users.title'}} + {{#if showGroups}} + {{nav-item route='groups' label='admin.groups.title'}} + {{/if}} {{#if showBadges}} {{nav-item route='adminBadges' label='admin.badges.title'}} {{/if}} diff --git a/app/assets/javascripts/admin/templates/backups.hbs b/app/assets/javascripts/admin/templates/backups.hbs index 2dcd6e02ba..fe7861839f 100644 --- a/app/assets/javascripts/admin/templates/backups.hbs +++ b/app/assets/javascripts/admin/templates/backups.hbs @@ -21,7 +21,7 @@ label="admin.backups.operations.cancel.label" icon="times"}} {{else}} - {{d-button action="startBackup" + {{d-button action="showStartBackupModal" class="btn-primary" title="admin.backups.operations.backup.title" label="admin.backups.operations.backup.label" diff --git a/app/assets/javascripts/admin/templates/components/site-settings/bool.hbs b/app/assets/javascripts/admin/templates/components/site-settings/bool.hbs index f1ac669900..5892174168 100644 --- a/app/assets/javascripts/admin/templates/components/site-settings/bool.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/bool.hbs @@ -1,5 +1,5 @@ diff --git a/app/assets/javascripts/admin/templates/components/themes-list-item.hbs b/app/assets/javascripts/admin/templates/components/themes-list-item.hbs new file mode 100644 index 0000000000..a12ddb4123 --- /dev/null +++ b/app/assets/javascripts/admin/templates/components/themes-list-item.hbs @@ -0,0 +1,44 @@ +
{{i18n 'admin.customize.about'}}
+- {{i18n "admin.customize.theme.about_theme"}} -
- {{#if model.remote_theme.license_url}} -- {{i18n "admin.customize.theme.license"}} {{d-icon "copyright"}} -
+ {{i18n "admin.customize.theme.about_theme"}} + {{#if model.remote_theme.license_url}} + {{i18n "admin.customize.theme.license"}} {{d-icon "copyright"}} + {{/if}} {{/if}} - {{/if}} - {{#if parentThemes}} -+
{{i18n "admin.customize.theme.color_scheme_select"}}
-{{combo-box content=colorSchemes - filterable=true - forceEscape=true - value=colorSchemeId - icon="paint-brush"}} - {{#if colorSchemeChanged}} - {{d-button action="changeScheme" class="btn-primary btn-small submit-edit" icon="check"}} - {{d-button action="cancelChangeScheme" class="btn-small cancel-edit" icon="times"}} - {{/if}} -
- {{#link-to 'adminCustomize.colors' class="btn edit"}}{{i18n 'admin.customize.colors.edit'}}{{/link-to}} +{{i18n "admin.customize.theme.custom_sections"}}
-- {{i18n "admin.customize.theme.edit_css_html_help"}} -
- {{/if}} +{{#if model.remote_theme}} {{#if model.remote_theme.commits_behind}} {{#d-button action="updateToLatest" icon="download" class='btn-primary'}}{{i18n "admin.customize.theme.update_to_latest"}}{{/d-button}} @@ -75,7 +81,6 @@ {{/if}} {{#d-button action="editTheme" class="btn edit"}}{{i18n 'admin.customize.theme.edit_css_html'}}{{/d-button}} - {{#if model.remote_theme}} + {{#if showRemoteError}} +
+{{model.remoteError}}
+ {{i18n "admin.customize.theme.no_uploads"}}
- {{/if}} -+
- -
- {{else}} -- {{combo-box forceEscape=true filterable=true content=selectableChildThemes value=selectedChildThemeId}} - {{#d-button action="addChildTheme" icon="plus"}}{{i18n "admin.customize.theme.add"}}{{/d-button}} -
- {{/if}} +"); - buffer.push(desc); - buffer.push("
"); - } - } - }) -); diff --git a/app/assets/javascripts/discourse/components/group-member-dropdown.js.es6 b/app/assets/javascripts/discourse/components/group-member-dropdown.js.es6 index bb7533630c..92770a2d14 100644 --- a/app/assets/javascripts/discourse/components/group-member-dropdown.js.es6 +++ b/app/assets/javascripts/discourse/components/group-member-dropdown.js.es6 @@ -1,19 +1,22 @@ -import { iconHTML } from "discourse-common/lib/icon-library"; -import DropdownButton from "discourse/components/dropdown-button"; import computed from "ember-addons/ember-computed-decorators"; +import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box"; -export default DropdownButton.extend({ - buttonExtraClasses: "no-text", - title: "", - text: iconHTML("wrench"), - classNames: ["group-member-dropdown"], +export default DropdownSelectBoxComponent.extend({ + pluginApiIdentifiers: ["group-member-dropdown"], + classNames: "group-member-dropdown", + showFullTitle: false, + allowInitialValueMutation: false, + allowAutoSelectFirst: false, + headerIcon: ["wrench"], + + autoHighlight() {}, @computed("member.owner") - dropDownContent(isOwner) { + content(isOwner) { const items = [ { id: "removeMember", - title: I18n.t("groups.members.remove_member"), + name: I18n.t("groups.members.remove_member"), description: I18n.t("groups.members.remove_member_description", { username: this.get("member.username") }), @@ -25,7 +28,7 @@ export default DropdownButton.extend({ if (isOwner) { items.push({ id: "removeOwner", - title: I18n.t("groups.members.remove_owner"), + name: I18n.t("groups.members.remove_owner"), description: I18n.t("groups.members.remove_owner_description", { username: this.get("member.username") }), @@ -34,7 +37,7 @@ export default DropdownButton.extend({ } else { items.push({ id: "makeOwner", - title: I18n.t("groups.members.make_owner"), + name: I18n.t("groups.members.make_owner"), description: I18n.t("groups.members.make_owner_description", { username: this.get("member.username") }), @@ -46,7 +49,7 @@ export default DropdownButton.extend({ return items; }, - clicked(id) { + mutateValue(id) { switch (id) { case "removeMember": this.sendAction("removeMember", this.get("member")); diff --git a/app/assets/javascripts/discourse/components/tags-admin-dropdown.js.es6 b/app/assets/javascripts/discourse/components/tags-admin-dropdown.js.es6 index e1ea9aabb6..e599f3d9b5 100644 --- a/app/assets/javascripts/discourse/components/tags-admin-dropdown.js.es6 +++ b/app/assets/javascripts/discourse/components/tags-admin-dropdown.js.es6 @@ -1,23 +1,24 @@ -import { iconHTML } from "discourse-common/lib/icon-library"; -import DropdownButton from "discourse/components/dropdown-button"; -import computed from "ember-addons/ember-computed-decorators"; +import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box"; -export default DropdownButton.extend({ - buttonExtraClasses: "no-text", - title: "", - text: iconHTML("bars") + " " + iconHTML("caret-down"), - classNames: ["tags-admin-menu"], +export default DropdownSelectBoxComponent.extend({ + pluginApiIdentifiers: ["tags-admin-dropdown"], + classNames: "tags-admin-dropdown", + showFullTitle: false, + allowInitialValueMutation: false, + headerIcon: ["bars", "caret-down"], - @computed() - dropDownContent() { + autoHighlight() {}, + + computeContent() { const items = [ { id: "manageGroups", - title: I18n.t("tagging.manage_groups"), + name: I18n.t("tagging.manage_groups"), description: I18n.t("tagging.manage_groups_description"), icon: "wrench" } ]; + return items; }, @@ -25,7 +26,7 @@ export default DropdownButton.extend({ manageGroups: "showTagGroups" }, - clicked(id) { - this.sendAction("actionNames." + id); + mutateValue(id) { + this.sendAction(`actionNames.${id}`); } }); diff --git a/app/assets/javascripts/discourse/components/topic-progress.js.es6 b/app/assets/javascripts/discourse/components/topic-progress.js.es6 index 66351564a5..eca9ebb124 100644 --- a/app/assets/javascripts/discourse/components/topic-progress.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-progress.js.es6 @@ -162,7 +162,7 @@ export default Ember.Component.extend({ const windowHeight = $(window).height(); const composerHeight = $("#reply-control").height() || 0; const isDocked = offset >= maximumOffset - windowHeight + composerHeight; - const bottom = $("#main").height() - maximumOffset; + const bottom = $("body").height() - maximumOffset; if (composerHeight > 0) { $wrapper.css("bottom", isDocked ? bottom : composerHeight); @@ -181,7 +181,7 @@ export default Ember.Component.extend({ }, click(e) { - if ($(e.target).parents("#topic-progress").length) { + if ($(e.target).closest("#topic-progress").length) { this.send("toggleExpansion"); } }, diff --git a/app/assets/javascripts/discourse/controllers/auth-token.js.es6 b/app/assets/javascripts/discourse/controllers/auth-token.js.es6 new file mode 100644 index 0000000000..88ca16b406 --- /dev/null +++ b/app/assets/javascripts/discourse/controllers/auth-token.js.es6 @@ -0,0 +1,41 @@ +import ModalFunctionality from "discourse/mixins/modal-functionality"; +import { ajax } from "discourse/lib/ajax"; +import { userPath } from "discourse/lib/url"; + +export default Ember.Controller.extend(ModalFunctionality, { + expanded: false, + + onShow() { + ajax( + userPath(`${this.get("currentUser.username_lower")}/activity.json`) + ).then(posts => { + if (posts.length > 0) { + this.set("latest_post", posts[0]); + } + }); + }, + + actions: { + toggleExpanded() { + this.set("expanded", !this.get("expanded")); + }, + + highlightSecure() { + this.send("closeModal"); + + Ember.run.next(() => { + const $prefPasswordDiv = $(".pref-password"); + + $prefPasswordDiv.addClass("highlighted"); + $prefPasswordDiv.on("animationend", () => + $prefPasswordDiv.removeClass("highlighted") + ); + + window.scrollTo({ + top: $prefPasswordDiv.offset().top, + behavior: "smooth" + }); + }); + } + } +}); diff --git a/app/assets/javascripts/discourse/controllers/preferences/account.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/account.js.es6 index b91f0e66ff..ca3fe8e7ee 100644 --- a/app/assets/javascripts/discourse/controllers/preferences/account.js.es6 +++ b/app/assets/javascripts/discourse/controllers/preferences/account.js.es6 @@ -9,6 +9,9 @@ import { findAll } from "discourse/models/login-method"; import { ajax } from "discourse/lib/ajax"; import { userPath } from "discourse/lib/url"; +// Number of tokens shown by default. +const DEFAULT_AUTH_TOKENS_COUNT = 2; + export default Ember.Controller.extend( CanCheckEmails, PreferencesTabController, @@ -23,6 +26,8 @@ export default Ember.Controller.extend( passwordProgress: null, + showAllAuthTokens: false, + cannotDeleteAccount: Em.computed.not("currentUser.can_delete_account"), deleteDisabled: Em.computed.or( "model.isSaving", @@ -99,6 +104,22 @@ export default Ember.Controller.extend( ); }, + @computed("showAllAuthTokens", "model.user_auth_tokens") + authTokens(showAllAuthTokens, tokens) { + tokens.sort( + (a, b) => (a.is_active ? -1 : b.is_active ? 1 : a.seen_at < b.seen_at) + ); + + return showAllAuthTokens + ? tokens + : tokens.slice(0, DEFAULT_AUTH_TOKENS_COUNT); + }, + + @computed("model.user_auth_tokens") + canShowAllAuthTokens(tokens) { + return tokens.length > DEFAULT_AUTH_TOKENS_COUNT; + }, + actions: { save() { this.set("saved", false); @@ -200,19 +221,26 @@ export default Ember.Controller.extend( }); }, - toggleToken(token) { - Ember.set(token, "visible", !token.visible); + toggleShowAllAuthTokens() { + this.set("showAllAuthTokens", !this.get("showAllAuthTokens")); }, - revokeAuthToken() { + revokeAuthToken(token) { ajax( userPath( `${this.get("model.username_lower")}/preferences/revoke-auth-token` ), - { type: "POST" } + { + type: "POST", + data: token ? { token_id: token.id } : {} + } ); }, + showToken(token) { + showModal("auth-token", { model: token }); + }, + connectAccount(method) { method.doLogin(); } diff --git a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 index 8cf32d9cc6..97cab16b0d 100644 --- a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 +++ b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 @@ -31,7 +31,8 @@ export default Ember.Controller.extend(PreferencesTabController, { "disable_jump_reply", "automatically_unpin_topics", "allow_private_messages", - "homepage_id" + "homepage_id", + "hide_profile_and_presence" ]; if (makeDefault) { diff --git a/app/assets/javascripts/discourse/controllers/user.js.es6 b/app/assets/javascripts/discourse/controllers/user.js.es6 index 96b2a333f2..80162bff88 100644 --- a/app/assets/javascripts/discourse/controllers/user.js.es6 +++ b/app/assets/javascripts/discourse/controllers/user.js.es6 @@ -16,9 +16,9 @@ export default Ember.Controller.extend(CanCheckEmails, { return currentUser && username === currentUser.get("username"); }, - @computed("viewingSelf") - canExpandProfile(viewingSelf) { - return viewingSelf; + @computed("viewingSelf", "model.profile_hidden") + canExpandProfile(viewingSelf, profileHidden) { + return !profileHidden && viewingSelf; }, @computed("model.profileBackground") @@ -26,8 +26,11 @@ export default Ember.Controller.extend(CanCheckEmails, { return !Ember.isEmpty(background.toString()); }, - @computed("indexStream", "viewingSelf", "forceExpand") - collapsedInfo(indexStream, viewingSelf, forceExpand) { + @computed("model.profile_hidden", "indexStream", "viewingSelf", "forceExpand") + collapsedInfo(profileHidden, indexStream, viewingSelf, forceExpand) { + if (profileHidden) { + return true; + } return (!indexStream || viewingSelf) && !forceExpand; }, diff --git a/app/assets/javascripts/discourse/lib/click-track.js.es6 b/app/assets/javascripts/discourse/lib/click-track.js.es6 index 96ea6f2f9c..c638cd7302 100644 --- a/app/assets/javascripts/discourse/lib/click-track.js.es6 +++ b/app/assets/javascripts/discourse/lib/click-track.js.es6 @@ -127,32 +127,39 @@ export default { const isInternal = DiscourseURL.isInternal(href); - // If we're on the same site, use the router and track via AJAX - if (tracking && isInternal && !$link.hasClass("attachment")) { - ajax("/clicks/track", { - data: { - url: href, - post_id: postId, - topic_id: topicId, - redirect: false - }, - dataType: "html" - }); - DiscourseURL.routeTo(href); - return false; - } - const modifierLeftClicked = (e.ctrlKey || e.metaKey) && e.which === 1; const middleClicked = e.which === 2; const openExternalInNewTab = Discourse.User.currentProp( "external_links_in_new_tab" ); - if ( + const openWindow = modifierLeftClicked || middleClicked || - (!isInternal && openExternalInNewTab) - ) { + (!isInternal && openExternalInNewTab); + + // If we're on the same site, use the router and track via AJAX + if (isInternal && !$link.hasClass("attachment")) { + if (tracking) { + ajax("/clicks/track", { + data: { + url: href, + post_id: postId, + topic_id: topicId, + redirect: false + }, + dataType: "html" + }); + } + if (openWindow) { + window.open(destUrl, "_blank").focus(); + } else { + DiscourseURL.routeTo(href); + } + return false; + } + + if (openWindow) { window.open(destUrl, "_blank").focus(); } else { DiscourseURL.redirectTo(destUrl); diff --git a/app/assets/javascripts/discourse/lib/load-script.js.es6 b/app/assets/javascripts/discourse/lib/load-script.js.es6 index bd64c64ec1..34b3f2897b 100644 --- a/app/assets/javascripts/discourse/lib/load-script.js.es6 +++ b/app/assets/javascripts/discourse/lib/load-script.js.es6 @@ -11,7 +11,6 @@ function loadWithTag(path, cb) { if (Ember.Test) { Ember.Test.registerWaiter(() => finished); } - head.appendChild(s); s.onload = s.onreadystatechange = function(_, abort) { finished = true; @@ -27,6 +26,8 @@ function loadWithTag(path, cb) { } } }; + + head.appendChild(s); } export function loadCSS(url) { @@ -41,17 +42,19 @@ export default function loadScript(url, opts) { opts = opts || {}; + // Scripts should always load from CDN + // CSS is type text, to accept it from a CDN we would need to handle CORS + url = opts.css ? Discourse.getURL(url) : Discourse.getURLWithCDN(url); + $("script").each((i, tag) => { const src = tag.getAttribute("src"); - if (src && (opts.scriptTag || src !== url)) { - _loaded[tag.getAttribute("src")] = true; + if (src && src !== url && !_loading[src]) { + _loaded[src] = true; } }); return new Ember.RSVP.Promise(function(resolve) { - url = Discourse.getURL(url); - // If we already loaded this url if (_loaded[url]) { return resolve(); @@ -78,30 +81,15 @@ export default function loadScript(url, opts) { _loaded[url] = true; }; - let cdnUrl = url; - - // Scripts should always load from CDN - // CSS is type text, to accept it from a CDN we would need to handle CORS - if (!opts.css && Discourse.CDN && url[0] === "/" && url[1] !== "/") { - cdnUrl = Discourse.CDN.replace(/\/$/, "") + url; - } - - // Some javascript depends on the path of where it is loaded (ace editor) - // to dynamically load more JS. In that case, add the `scriptTag: true` - // option. - if (opts.scriptTag) { - if (Ember.testing) { - throw new Error( - `In test mode scripts cannot be loaded async ${cdnUrl}` - ); - } - loadWithTag(cdnUrl, cb); - } else { + if (opts.css) { ajax({ - url: cdnUrl, - dataType: opts.css ? "text" : "script", + url: url, + dataType: "text", cache: true }).then(cb); + } else { + // Always load JavaScript with script tag to avoid Content Security Policy inline violations + loadWithTag(url, cb); } }); } diff --git a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 index e544c80ed9..fb62d4d3e3 100644 --- a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 +++ b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 @@ -1,6 +1,7 @@ import { iconNode } from "discourse-common/lib/icon-library"; import { addDecorator } from "discourse/widgets/post-cooked"; import ComposerEditor from "discourse/components/composer-editor"; +import DiscourseBanner from "discourse/components/discourse-banner"; import { addButton } from "discourse/widgets/post-menu"; import { includeAttributes } from "discourse/lib/transform-post"; import { addToolbarCallback } from "discourse/components/d-editor"; @@ -175,6 +176,7 @@ class PluginApi { if (!opts.onlyStream) { decorate(ComposerEditor, "previewRefreshed", callback); + decorate(DiscourseBanner, "didInsertElement", callback); decorate( this.container.factoryFor("component:user-stream").class, "didInsertElement", diff --git a/app/assets/javascripts/discourse/lib/render-tag.js.es6 b/app/assets/javascripts/discourse/lib/render-tag.js.es6 index 533058adf0..8420638b3b 100644 --- a/app/assets/javascripts/discourse/lib/render-tag.js.es6 +++ b/app/assets/javascripts/discourse/lib/render-tag.js.es6 @@ -1,6 +1,7 @@ export default function renderTag(tag, params) { params = params || {}; - tag = Handlebars.Utils.escapeExpression(tag); + const visibleName = Handlebars.Utils.escapeExpression(tag); + tag = visibleName.toLowerCase(); const classes = ["discourse-tag"]; const tagName = params.tagName || "a"; let path; @@ -29,7 +30,7 @@ export default function renderTag(tag, params) { " class='" + classes.join(" ") + "'>" + - tag + + visibleName + "" + tagName + ">"; diff --git a/app/assets/javascripts/discourse/lib/url.js.es6 b/app/assets/javascripts/discourse/lib/url.js.es6 index 786ed36081..e7f46eb870 100644 --- a/app/assets/javascripts/discourse/lib/url.js.es6 +++ b/app/assets/javascripts/discourse/lib/url.js.es6 @@ -187,13 +187,7 @@ const DiscourseURL = Ember.Object.extend({ const pathname = path.replace(/(https?\:)?\/\/[^\/]+/, ""); const baseUri = Discourse.BaseUri; - // If we have a baseUri and an absolute URL, make sure the baseUri - // is the same. Otherwise we could be switching forums. - if ( - baseUri && - path.indexOf("http") === 0 && - pathname.indexOf(baseUri) !== 0 - ) { + if (!DiscourseURL.isInternal(path)) { return redirectTo(path); } @@ -207,11 +201,6 @@ const DiscourseURL = Ember.Object.extend({ return; } - // Protocol relative URLs - if (path.indexOf("//") === 0) { - return redirectTo(path); - } - // Scroll to the same page, different anchor const m = /^#(.+)$/.exec(path); if (m) { diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6 index b3e91306d3..acb2ad2ff4 100644 --- a/app/assets/javascripts/discourse/models/user.js.es6 +++ b/app/assets/javascripts/discourse/models/user.js.es6 @@ -284,7 +284,8 @@ const User = RestModel.extend({ "include_tl0_in_digests", "theme_ids", "allow_private_messages", - "homepage_id" + "homepage_id", + "hide_profile_and_presence" ]; if (fields) { diff --git a/app/assets/javascripts/discourse/routes/app-route-map.js.es6 b/app/assets/javascripts/discourse/routes/app-route-map.js.es6 index df489fa5a1..30dd8fc755 100644 --- a/app/assets/javascripts/discourse/routes/app-route-map.js.es6 +++ b/app/assets/javascripts/discourse/routes/app-route-map.js.es6 @@ -102,6 +102,7 @@ export default function() { "user", { path: "/u/:username", resetNamespace: true }, function() { + this.route("profile-hidden"); this.route("summary"); this.route( "userActivity", diff --git a/app/assets/javascripts/discourse/routes/discovery.js.es6 b/app/assets/javascripts/discourse/routes/discovery.js.es6 index 8b7d6c7fb5..e7ff98a591 100644 --- a/app/assets/javascripts/discourse/routes/discovery.js.es6 +++ b/app/assets/javascripts/discourse/routes/discovery.js.es6 @@ -13,6 +13,7 @@ export default Discourse.Route.extend(OpenComposer, { beforeModel(transition) { if ( (transition.intent.url === "/" || + transition.intent.url === "/latest" || transition.intent.url === "/categories") && transition.targetName.indexOf("discovery.top") === -1 && Discourse.User.currentProp("should_be_redirected_to_top") diff --git a/app/assets/javascripts/discourse/routes/groups-index.js.es6 b/app/assets/javascripts/discourse/routes/groups-index.js.es6 index ea30d026c4..e7189d778f 100644 --- a/app/assets/javascripts/discourse/routes/groups-index.js.es6 +++ b/app/assets/javascripts/discourse/routes/groups-index.js.es6 @@ -11,8 +11,6 @@ export default Discourse.Route.extend({ username: { refreshModel: true } }, - refreshQueryWithoutTransition: true, - model(params) { this._params = params; return this.store.findAll("group", params); diff --git a/app/assets/javascripts/discourse/routes/new-topic.js.es6 b/app/assets/javascripts/discourse/routes/new-topic.js.es6 index b1ee1ae8f7..46f38d4ef3 100644 --- a/app/assets/javascripts/discourse/routes/new-topic.js.es6 +++ b/app/assets/javascripts/discourse/routes/new-topic.js.es6 @@ -11,24 +11,17 @@ export default Discourse.Route.extend({ category = Category.findById(category_id); } else if (transition.queryParams.category) { const splitCategory = transition.queryParams.category.split("/"); - - if (!splitCategory[1]) { - category = this.site - .get("categories") - .findBy("nameLower", splitCategory[0].toLowerCase()); - } else { - const categories = this.site.get("categories"); - const mainCategory = categories.findBy( - "nameLower", - splitCategory[0].toLowerCase() + category = this._getCategory( + splitCategory[0], + splitCategory[1], + "nameLower" + ); + if (!category) { + category = this._getCategory( + splitCategory[0], + splitCategory[1], + "slug" ); - category = categories.find(function(item) { - return ( - item && - item.get("nameLower") === splitCategory[1].toLowerCase() && - item.get("parent_category_id") === mainCategory.id - ); - }); } if (category) { @@ -86,5 +79,27 @@ export default Discourse.Route.extend({ self.replaceWith("login"); } } + }, + + _getCategory(mainCategory, subCategory, type) { + let category; + if (!subCategory) { + category = this.site + .get("categories") + .findBy(type, mainCategory.toLowerCase()); + } else { + const categories = this.site.get("categories"); + const main = categories.findBy(type, mainCategory.toLowerCase()); + if (main) { + category = categories.find(function(item) { + return ( + item && + item.get(type) === subCategory.toLowerCase() && + item.get("parent_category_id") === main.id + ); + }); + } + } + return category; } }); diff --git a/app/assets/javascripts/discourse/routes/tags-show.js.es6 b/app/assets/javascripts/discourse/routes/tags-show.js.es6 index 437f3e4e82..72a02c2ed5 100644 --- a/app/assets/javascripts/discourse/routes/tags-show.js.es6 +++ b/app/assets/javascripts/discourse/routes/tags-show.js.es6 @@ -49,10 +49,12 @@ export default Discourse.Route.extend({ if (tag && tag.get("id") !== "none" && this.get("currentUser")) { // If logged in, we should get the tag's user settings - return this.store.find("tagNotification", tag.get("id")).then(tn => { - this.set("tagNotification", tn); - return tag; - }); + return this.store + .find("tagNotification", tag.get("id").toLowerCase()) + .then(tn => { + this.set("tagNotification", tn); + return tag; + }); } return tag; @@ -67,7 +69,7 @@ export default Discourse.Route.extend({ const categorySlug = this.get("categorySlug"); const parentCategorySlug = this.get("parentCategorySlug"); const filter = this.get("navMode"); - const tag_id = tag ? tag.id : "none"; + const tag_id = tag ? tag.id.toLowerCase() : "none"; if (categorySlug) { var category = Discourse.Category.findBySlug( @@ -100,6 +102,9 @@ export default Discourse.Route.extend({ params, {} ).then(list => { + if (list.topic_list.tags) { + tag.set("id", list.topic_list.tags[0].name); // Update name of tag (case might be different) + } controller.setProperties({ list: list, canCreateTopic: list.get("can_create_topic"), diff --git a/app/assets/javascripts/discourse/routes/user-activity.js.es6 b/app/assets/javascripts/discourse/routes/user-activity.js.es6 index 546e135cbe..a827e3d998 100644 --- a/app/assets/javascripts/discourse/routes/user-activity.js.es6 +++ b/app/assets/javascripts/discourse/routes/user-activity.js.es6 @@ -1,6 +1,11 @@ export default Discourse.Route.extend({ model() { - return this.modelFor("user"); + let user = this.modelFor("user"); + if (user.get("profile_hidden")) { + return this.replaceWith("user.profile-hidden"); + } + + return user; }, setupController(controller, user) { diff --git a/app/assets/javascripts/discourse/routes/user-summary.js.es6 b/app/assets/javascripts/discourse/routes/user-summary.js.es6 index 39d4571973..95db3c3ae1 100644 --- a/app/assets/javascripts/discourse/routes/user-summary.js.es6 +++ b/app/assets/javascripts/discourse/routes/user-summary.js.es6 @@ -2,7 +2,12 @@ export default Discourse.Route.extend({ showFooter: true, model() { - return this.modelFor("user").summary(); + let user = this.modelFor("user"); + if (user.get("profile_hidden")) { + return this.replaceWith("user.profile-hidden"); + } + + return user.summary(); }, actions: { diff --git a/app/assets/javascripts/discourse/templates/components/categories-boxes.hbs b/app/assets/javascripts/discourse/templates/components/categories-boxes.hbs index 0c90a54a03..16aeaf6195 100644 --- a/app/assets/javascripts/discourse/templates/components/categories-boxes.hbs +++ b/app/assets/javascripts/discourse/templates/components/categories-boxes.hbs @@ -17,6 +17,19 @@{{{i18n 'ip_lookup.powered_by'}}}
diff --git a/app/assets/javascripts/discourse/templates/components/user-fields/confirm.hbs b/app/assets/javascripts/discourse/templates/components/user-fields/confirm.hbs index 6b8726d4e4..18896a4dc3 100644 --- a/app/assets/javascripts/discourse/templates/components/user-fields/confirm.hbs +++ b/app/assets/javascripts/discourse/templates/components/user-fields/confirm.hbs @@ -1,4 +1,5 @@ - +{{i18n 'user.auth_tokens.was_this_you_description'}}
+{{{i18n 'user.second_factor.extended_description'}}}
+{{d-icon "clock-o"}} {{format-date model.seen_at}}
+{{d-icon "map-marker"}} {{model.location}}
+{{d-icon model.icon}} {{i18n "user.auth_tokens.browser_and_device" browser=model.browser device=model.device}}
+{{{latest_post.cooked}}}+ {{else}} +
{{{latest_post.excerpt}}}+ {{/if}} +
- {{{i18n 'topic.change_owner.instructions_warn'}}} -
<% end %> - <%- if @preloaded.present? %> - - <%- end %> + + <%= preload_script "preload-application-data" %> <%= yield :data %> - <%= render :partial => "common/discourse_javascript" %> + <%= preload_script 'browser-update' %> <%- unless customization_disabled? %> <%= raw theme_lookup("body_tag") %> diff --git a/app/views/qunit/index.html.erb b/app/views/qunit/index.html.erb index 0515dfc0d6..eef411cfd5 100644 --- a/app/views/qunit/index.html.erb +++ b/app/views/qunit/index.html.erb @@ -5,6 +5,7 @@ <%= stylesheet_link_tag "test_helper" %> <%= javascript_include_tag "test_helper" %> <%= csrf_meta_tags %> + diff --git a/config/application.rb b/config/application.rb index 90218a83eb..640f05f5b7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -117,6 +117,10 @@ module Discourse plugin-third-party.js markdown-it-bundle.js service-worker.js + google-tag-manager.js + google-universal-analytics.js + preload-application-data.js + authentication-complete.js } # Precompile all available locales diff --git a/config/initializers/000-post_migration.rb b/config/initializers/000-post_migration.rb new file mode 100644 index 0000000000..acff3e26d9 --- /dev/null +++ b/config/initializers/000-post_migration.rb @@ -0,0 +1,5 @@ +unless Discourse.skip_post_deployment_migrations? + Rails.application.config.paths['db/migrate'] << Rails.root.join( + Discourse::DB_POST_MIGRATE_PATH + ).to_s +end diff --git a/config/initializers/008-rack-cors.rb b/config/initializers/008-rack-cors.rb index 83419039e0..1512c2bda3 100644 --- a/config/initializers/008-rack-cors.rb +++ b/config/initializers/008-rack-cors.rb @@ -41,6 +41,7 @@ class Discourse::Cors headers['Access-Control-Allow-Origin'] = origin || cors_origins[0] headers['Access-Control-Allow-Headers'] = 'Content-Type, X-Requested-With, X-CSRF-Token, Discourse-Visible, User-Api-Key, User-Api-Client-Id' headers['Access-Control-Allow-Credentials'] = 'true' + headers['Access-Control-Allow-Methods'] = 'POST, PUT, GET, OPTIONS, DELETE' end headers diff --git a/config/initializers/012-web_hook_events.rb b/config/initializers/012-web_hook_events.rb index 0834b875f6..a99b958dc6 100644 --- a/config/initializers/012-web_hook_events.rb +++ b/config/initializers/012-web_hook_events.rb @@ -1,5 +1,4 @@ %i( - topic_destroyed topic_recovered ).each do |event| DiscourseEvent.on(event) do |topic, _| @@ -17,7 +16,6 @@ end %i( post_created - post_destroyed post_recovered ).each do |event| DiscourseEvent.on(event) do |post, _, _| @@ -41,7 +39,6 @@ end user_logged_in user_approved user_updated - user_destroyed ).each do |event| DiscourseEvent.on(event) do |user| WebHook.enqueue_object_hooks(:user, user, event) @@ -51,7 +48,6 @@ end %i( group_created group_updated - group_destroyed ).each do |event| DiscourseEvent.on(event) do |group| WebHook.enqueue_object_hooks(:group, group, event) @@ -61,7 +57,6 @@ end %i( category_created category_updated - category_destroyed ).each do |event| DiscourseEvent.on(event) do |category| WebHook.enqueue_object_hooks(:category, category, event) @@ -71,7 +66,6 @@ end %i( tag_created tag_updated - tag_destroyed ).each do |event| DiscourseEvent.on(event) do |tag| WebHook.enqueue_object_hooks(:tag, tag, event, TagSerializer) diff --git a/config/locales/client.ar.yml b/config/locales/client.ar.yml index aea80facd5..6a2115124b 100644 --- a/config/locales/client.ar.yml +++ b/config/locales/client.ar.yml @@ -311,12 +311,8 @@ ar: bookmark: "انقر لوضع علامة مرجعية علي أوّل منشور في هذا الموضوع" unbookmark: "انقر لإزالة كلّ العلامات المرجعية في هذا الموضوع" bookmarks: - not_logged_in: "عذرا، عليك تسجيل الدخول لتضع علامات مرجعية علي المنشورات" created: "لقد وضعت علامة مرجعية علي هذا المنشور" - not_bookmarked: "لقد قرأت هذا المنشور، انقر لوضع علامة مرجعية علية" - last_read: "هذا آخر منشور قرأته، انقر لوضع علامة مرجعية علية" remove: "أزل العلامة المرجعية" - confirm_clear: "أمتأكد من إزالة كل العلامات لمرجعية من هذا الموضوع؟" preview: "معاينة" cancel: "ألغِ" save: "احفظ التعديلات" @@ -324,7 +320,6 @@ ar: saved: "حُفظت!" upload: "ارفع" uploading: "يرفع..." - uploading_filename: "يرفع {{filename}}..." uploaded: "رُفع!" pasting: "جاري النسخ" enable: "فعّل" @@ -621,6 +616,7 @@ ar: disable: "عطّل الإشعارات" enable: "فعّل الإشعارات" each_browser_note: "ملاحظة: عليك تغيير هذا الإعداد في كل متصفح تستخدمه." + consent_prompt: "هل تريد إشعارات مباشرة عندما يرد الأشخاص على مشاركاتك؟" dismiss: 'تجاهل' dismiss_notifications: "تجاهل الكل" dismiss_notifications_tooltip: "اجعل كل الإشعارات مقروءة" @@ -721,6 +717,9 @@ ar: set_password: " إعادة تعين كلمة المرور" choose_new: "اختر كلمة المرور الجديدة" choose: "اختر كلمة المرور" + second_factor_backup: + disable: "عطل" + enable: "فعل" second_factor: label: "كود" show_key_description: "أضف يدويا" @@ -998,9 +997,6 @@ ar: enabled: "هذا الموقع في وضع القراءة فقط. نأمل أن تتابع تصفحه، ولكن الرد، والإعجاب وغيرها من الصلاحيات معطلة حاليا." login_disabled: "تسجيل الدخول معطل في حال كان الموقع في وضع القراءة فقط." logout_disabled: "تسجيل الخروج معطّل في حال كان الموقع في وضع القراءة فقط." - too_few_topics_and_posts_notice: "دعونا نبدأ هذه المناقشة! يوجد حاليا %{currentTopics} / %{requiredTopics} موضوع و %{currentPosts} / %{requiredPosts} منشور. الزوار الجدد بحاجة لبعض المحادثات لقرأتها و الرد عليها." - too_few_topics_notice: "هيا لنبدء هذه المناقشة هناك حالياً%{currentTopics} \\ %{requiredTopics} موضوع. الزوار الجدد بحاجة لبعض المحادثات لقرأتها و الرد عليها." - too_few_posts_notice: "هيا لنبدء هذه المناقشة هناك حالياً %{currentPosts} \\ %{requiredPosts} منشور. الزوار الجدد بحاجة لبعض المحادثات لقرأتها و الرد عليها." logs_error_rate_notice: reached: "%{relativeAge} – %{rate} وصل الحد الاقصي لإعدادت الموقع %{siteSettingRate}." exceeded: "%{relativeAge} – %{rate} يتجاوز الحد الاقصي لإعدادت الموقع %{siteSettingRate}." @@ -1161,6 +1157,7 @@ ar: default_header_text: اختر... no_content: لا يوجد نتائج مطابقة filter_placeholder: بحث... + filter_placeholder_with_any: ابحث أو أنشئً ... emoji_picker: filter_placeholder: بحث عن الرموز التعبيرية people: الاشخاص @@ -1247,7 +1244,6 @@ ar: link_description: "ادخل وصف الرابط هنا " link_dialog_title: "اضف الرابط" link_optional_text: "عنوان اختياري" - link_url_placeholder: "http://example.com" quote_title: "اقتباس فقرة" quote_text: "اقتباس فقرة" code_title: "المحافظة على التنسيق" @@ -1785,18 +1781,9 @@ ar: action: "ادمج المنشورات المحددة" error: "حدث عطل أثناء دمج المنشورات المحدّدة." change_owner: - title: "تغيير كاتب المنشور" action: "تغيير الكاتب" error: "حدث عطل أثناء تغيير كاتب هذة المنشورات." - label: "الكاتب الجديد للمنشورات" placeholder: "اسم مستخدم الكاتب الجديد" - instructions: - zero: "لم يتم تحديد أي منشورات!" - one: "الرجاء اختيار المالك الجديد لمنشور نُشر بواسطة {{old_user}}." - two: "الرجاء اختيار المالك الجديد لمنشورين نُشروا بواسطة {{old_user}}." - few: "الرجاء اختيار المالك الجديد لـ {{count}} منشور نُشر بواسطة {{old_user}}." - many: "الرجاء اختيار المالك الجديد لـ {{count}} منشور نُشر بواسطة {{old_user}}." - other: "الرجاء اختيار الكاتب الجديد لـ {{count}} منشور نُشر بواسطة {{old_user}}." change_timestamp: title: "غير تاريخ النشر..." action: "غير تاريخ النشر..." @@ -2417,7 +2404,6 @@ ar: this_week: "أسبوع" today: "يوم" other_periods: "اعرض الاكثر مشاهدة" - browser_update: 'للأسف، متصفّحك قديم جدًّا ليعمل عليه هذا الموقع. من فضلك حدث المتصفح خاصتك.' permission_types: full: "انشاء / رد / مشاهدة" create_post: "رد / مشاهدة" @@ -2536,6 +2522,7 @@ ar: selector_no_tags: "لا أوسمة" changed: "الأوسمة المعدلة:" tags: "الأوسمة" + choose_for_topic: "الأوسمة الإختيارية" delete_tag: "احذف الوسم" delete_confirm: zero: "هل أنت متاكد انك تريد حذف هذا الوسم و إذالتة من {{count}} موضوع؟" @@ -2604,8 +2591,6 @@ ar: bookmarks: "لا يوجد المزيد من الموضوعات التي عليها علامة مرجعية." search: "لا نتائج بحث أخرى." invite: - custom_message: "اجعل دعوتك شخصيّة أكثر بكتابة" - custom_message_link: "رسالة مخصصة" custom_message_placeholder: "ادخل رسالتك المخصصة" custom_message_template_forum: "مرحبا. عليك الانضمام إلى هذا المجتمع!" custom_message_template_topic: "مرحبا. أظن أن هذا الموضوع سيسعدك!" @@ -2936,7 +2921,6 @@ ar: upload_file_tip: "اختر ملف للرفع ( png او woff2... إلخ )" variable_name: "SCSS var name:" upload: "ارفع" - child_themes_check: "تشمل الواجهة واجهات فرعية اخري" css_html: "CSS/HTML مخصص" edit_css_html: "تعدل CSS/HTML" edit_css_html_help: "انت لم تقم بتعديل اي CSS او HTML" @@ -3097,7 +3081,6 @@ ar: filter: "رشح:" title: "عمليات المشرفين" clear_filters: "إظهار كل شيء" - staff_user: "عضو إداري" target_user: "عضو مستهدف" subject: "الموضوع" when: "متى" diff --git a/config/locales/client.bg.yml b/config/locales/client.bg.yml index ae24af6497..06cdf8e762 100644 --- a/config/locales/client.bg.yml +++ b/config/locales/client.bg.yml @@ -226,12 +226,8 @@ bg: bookmark: "Щракнете за да добавите в отметки първата публикация в тази тема" unbookmark: "Щракнете тук за да изтриите всички отметки в тази тема" bookmarks: - not_logged_in: "съжаляваме, трябва да сте логнат, за да добавяте отметки" created: "Вие добавихте тази публикация в отметки" - not_bookmarked: "тази публикация е прочетена, добавете я в отметки" - last_read: "това е последната публикация която прочетохте, добавете я в отметки" remove: "Премахнете отметката" - confirm_clear: "Сигурен ли сте, че искате да премахните всичките отметки от тази тема ?" preview: "преглед" cancel: "прекрати" save: "Запазете промените" @@ -239,7 +235,6 @@ bg: saved: "Запазено!" upload: "Качване" uploading: "Качва се..." - uploading_filename: "Качва се {{filename}}..." uploaded: "Качено!" enable: "Позволи" disable: "Деактивиране" @@ -822,9 +817,6 @@ bg: enabled: "Сайта е в режим само за четене. Моля продължете да разглеждате, но отгавяне, харесване и всичко останали опции са спряни за сега." login_disabled: "Влизането е изключено докато страницата е в мод само за четене." logout_disabled: "Излизане от сайта е временно спряно, докато е пуснат режим \"само за четене\"." - too_few_topics_and_posts_notice: "Нека да започнем дискусията сега! В момента има %{currentTopics} / %{requiredTopics} теми и %{currentPosts} / %{requiredPosts} постове. Новите посетители се нуждаят от теми за разговор, за да има на какво да четат и да отговарят." - too_few_topics_notice: "Нека да започнем дискусията сега!В момента има %{currentTopics} / %{requiredTopics} теми. Новите посетители се нуждаят от теми за разговор, за да има на какво да четат и да отговарят." - too_few_posts_notice: "Нека да започнем дискусията сега! В момента има %{currentPosts} / %{requiredPosts} постове. Новите посетители се нуждаят от теми за разговор, за да има на какво да четат и да отговарят." logs_error_rate_notice: rate: one: "1 грешка/%{duration}" @@ -999,7 +991,6 @@ bg: link_description: "добави описание на връзката тук" link_dialog_title: "Добави хипервръзка" link_optional_text: "заглавие по избор" - link_url_placeholder: "http://example.com" quote_title: "Текстов блок" quote_text: "Текстов блок" code_title: "Форматиран текст" @@ -1372,15 +1363,9 @@ bg: one: "Моля изберете тема в която искате да преместите тази публикация. " other: "Моля, изберете тема, в която искате да преместите тези {{count}} публикации. " change_owner: - title: "Смени собственика на публикацията." action: "смени собственика" error: "Възникна грешка при смяната на собственика" - label: "Нов собственик на публикациите" placeholder: "име на новия собственик" - instructions: - one: "Моля изберете нов собственик на публикацията от {{old_user}}." - other: "Моля, изберете новият собственик на {{count}} публикации от {{old_user}}. " - instructions_warn: "Имайте предвид, че известията към тази публикация няма да бъдат прехвърлени със задна дата към новия потребител." change_timestamp: action: "смени времевия показател" invalid_timestamp: "Времевия показател неможе да бъде в бъдещето." @@ -1791,7 +1776,6 @@ bg: this_week: "Седмица" today: "Днес" other_periods: "виж отгоре" - browser_update: 'За съжаление, вашият браузър е твърде стар, за да работи с този сайт. Моля, обновете вашия браузър.' permission_types: full: "Създай / Отговори / Виж" create_post: "Отговари / Виж" @@ -1880,8 +1864,6 @@ bg: bookmarks: "Няма теми в Отметки." search: "Няма повече резултати от търсенето." invite: - custom_message: "Направете поканата си малко по-лична, като напишете " - custom_message_link: "персонализирано съобщение" custom_message_placeholder: "Въведете вашето персонализирано съобщение" custom_message_template_forum: "Хей, трябва да се присъединиш към този форум!" custom_message_template_topic: "Хей, мисля си, че ще се насладиш на тази тема!" @@ -2099,7 +2081,6 @@ bg: new_style: "Нов стил" import: "Импорт" delete: "Изтрий" - about: "Променете CSS стиловете и HTML хедърите на сайта. Добавете нова настройка за да започнете." color: "Цвят" opacity: "Прозрачност" copy: "Копирай" @@ -2228,7 +2209,6 @@ bg: staff_actions: title: "Действия на персонала" clear_filters: "Покажи всичко " - staff_user: "Член на персонала" target_user: "Целеви потребител " subject: "Тема " when: "Кога " diff --git a/config/locales/client.bs_BA.yml b/config/locales/client.bs_BA.yml index 2593e0c1f1..e919abd46b 100644 --- a/config/locales/client.bs_BA.yml +++ b/config/locales/client.bs_BA.yml @@ -184,6 +184,7 @@ bs_BA: eu_central_1: "EU (Frankfurt)" eu_west_1: "EU (Irska)" eu_west_2: "EU (London)" + eu_west_3: "EU (Pariz)" sa_east_1: "Južna Amerika (Sao Paulo)" us_east_1: "SAD Istok (Sjeverna Virdžinija)" us_east_2: "SAD Istok (Ohio)" @@ -215,6 +216,7 @@ bs_BA: privacy_policy: "Izjava o privatnosti" privacy: "Privatnost" tos: "Uslovi korištenja" + rules: "Pravila" mobile_view: "Mobilni zaslon" desktop_view: "Standardni zaslon" you: "Vi" @@ -263,12 +265,8 @@ bs_BA: bookmark: "Klikni kako bi dodao zabilješku na prvu objavu u temi" unbookmark: "Klikni da ukloniš sve zabilješke iz ove teme" bookmarks: - not_logged_in: "nažalost, morate biti ulogovani kako bi ste dodali oznaku zabilješke" created: "zabilježili ste ovu stranicu" - not_bookmarked: "pročitali ste objavu; kliknite kako bi ste je zabilježili" - last_read: "ovo je zadnja objava koju ste pročitali; kliknite kako bi ste je zabilježili" remove: "Ukloni zabilješku" - confirm_clear: "Jeste li sigurni da želite očistiti sve zabilješke iz ove kategorije?" topic_count_latest: one: "Pogledaj {{count}} novu ili ažuriranu temu" few: "Pogledaj {{count}} nove ili ažurirane teme" @@ -288,7 +286,6 @@ bs_BA: saved: "Spremljeno!" upload: "Učitaj" uploading: "Učitava se..." - uploading_filename: "Učitavam {{filename}}..." uploaded: "Učitano!" pasting: "Lijepim..." enable: "Omogući" @@ -435,7 +432,6 @@ bs_BA: all: "Sve grupe" empty: "Vidljive grupe još ne postoje." filter: "Filtriraj prema tipu grupe" - owner_groups: "Grupe koje sam ja vlasnik" close_groups: "Zatvorene grupe" automatic_groups: "Automatske grupe" automatic: "Automatsko" @@ -556,6 +552,7 @@ bs_BA: post_count: "# postova" confirm_delete_other_accounts: "Jeste sigurni da želite da izbrišete ove račune?" powered_by: "powered by ipinfo.io" + copied: "koprian" user_fields: none: "(odaberi opciju)" user: @@ -976,9 +973,6 @@ bs_BA: enabled: "Ovaj sajt je u read only mod-u: Dozvoljeno je čitati. Možete nastaviti sa pregledom, ali odgovaranje na objave, lajkanje i ostale akcije su isključene za sada." login_disabled: "Ulogovanje je isključeno jer je sajt u read only načinu rada." logout_disabled: "Odjava je isključena sve dok je sajt u read only tj. samo čitanje je dozvoljeno načinu rada." - too_few_topics_and_posts_notice: "Odpočnimo sa diskusijom! Trenutno postoje %{currentTopics} / %{requiredTopics} teme i %{currentPosts} / %{requiredPosts} objave. Novi posjetioci trebaju par novih diskusija za čitanje i shodne reakcije." - too_few_topics_notice: "Odpočnimo sa diskusijom! Trenutno postoje %{currentTopics} / %{requiredTopics} teme. Novi posjetioci trebaju par novih diskusija za čitanje i shodne reakcije." - too_few_posts_notice: "Odpočnimo sa diskusijom! Trenutno postoje %{currentPosts} / %{requiredPosts} objave. Novi posjetioci trebaju par novih diskusija za čitanje i shodne reakcije." logs_error_rate_notice: reached: "%{relativeAge} – %{rate} dosegnut postavljeni limit sajta od %{siteSettingRate}." exceeded: "%{relativeAge} – %{rate} prelazi postavljeni limit sajta od %{siteSettingRate}." @@ -1257,7 +1251,6 @@ bs_BA: link_description: "ubaci opis linka" link_dialog_title: "Unesi Link" link_optional_text: "naslov neobavezan" - link_url_placeholder: "http://example.com" quote_title: "Blok Citat" quote_text: "Citat u bloku" code_title: "Formatiran Tekst" @@ -1806,16 +1799,9 @@ bs_BA: action: "spoji izabrane postove" error: "Desila se greška prilikom spajanja označenih objava." change_owner: - title: "Change Owner of Posts" action: "change ownership" error: "There was an error changing the ownership of the posts." - label: "New Owner of Posts" placeholder: "username of new owner" - instructions: - one: "Molimo da odaberete novog vlasnika objave od starog korisnika {{old_user}}." - few: "Molimo da odaberete novog vlasnika za {{count}} objave od starog korisnika {{old_user}}." - other: "Molimo da odaberete novog vlasnika za {{count}} objava od starog korisnika {{old_user}}." - instructions_warn: "Imajte na umu da bilo koje obavijesti o ovoj objavi neće biti proslijeđene novom korisniku retroaktivno (naknadno). " change_timestamp: title: "Promijeni vremensku zabilješku..." action: "izmijeni vrijeme" @@ -2152,6 +2138,7 @@ bs_BA: title_in: "Kategorija - {{categoryName}}" help: "sve teme grupisane po kategoriji" unread: + title: "Nepročitanih" help: "teme koje trenutno pratite i motrite sa nepročitanim postovima" new: lower_title_with_count: @@ -2185,7 +2172,6 @@ bs_BA: title: "Popularne Dnevno" all_time: "Sve vrijeme" today: "Danas" - browser_update: 'Nažalost, vaš internet browser je prestar za ovaj korišćenje ovog foruma. Idite na i obnovite vaš browser.' permission_types: full: "Kreiraj / Odgovori / Vidi" create_post: "Odgovori / Vidi" @@ -2367,7 +2353,6 @@ bs_BA: new: "New" new_style: "New Style" delete: "Delete" - about: "Modify CSS stylesheets and HTML headers on the site. Add a customization to start." color: "Color" opacity: "Opacity" copy: "Copy" @@ -2487,7 +2472,6 @@ bs_BA: staff_actions: title: "Staff Actions" clear_filters: "Show Everything" - staff_user: "Staff User" target_user: "Target User" subject: "Subject" when: "When" diff --git a/config/locales/client.ca.yml b/config/locales/client.ca.yml index f8ecb9dc95..8629ebf908 100644 --- a/config/locales/client.ca.yml +++ b/config/locales/client.ca.yml @@ -235,12 +235,8 @@ ca: bookmark: "Clica per marcar com a preferit la primera publicació d'aquest tema" unbookmark: "Clica per eliminar tots els preferits d'aquest tema" bookmarks: - not_logged_in: "disculpa, ha d'identificar-te per marcar publicacions com a preferits" created: "has marcat aquesta publicació com a preferit" - not_bookmarked: "has llegit aquesta publicació; cilca per marcar-la com a preferit" - last_read: "aquesta és la darrera publicació que has llegit; clica per marcar-la com a preferit" remove: "Elimina Preferit" - confirm_clear: "Segur que vols eliminar tots els preferits d'aquest tema?" preview: "previsualitza" cancel: "cancel·la" save: "Desa els canvis" @@ -248,7 +244,6 @@ ca: saved: "Desat!" upload: "Actualitza" uploading: "Actualitzant..." - uploading_filename: "Actualitzant {{filename}}..." uploaded: "Actualitzat!" pasting: "Enganxant..." enable: "Activa" @@ -812,9 +807,6 @@ ca: enabled: "El lloc web es troba en mode només de lectura. Si us plau, continua navegant però per ara estan desactivades respondre i altres accions." login_disabled: "S'ha desactivat l'inici de sessió mentre aquest lloc es trobi en mode només de lectura." logout_disabled: "S'ha desactivat el tancament de sessió mentre aquest lloc es trobi en mode només de lectura." - too_few_topics_and_posts_notice: "Comencem aquesta discussió! Actualment hi ha %{currentTopics} / %{requiredTopics} temes i %{currentPosts} / %{requiredPosts} entrades. Les noves visites necessiten algunes converses per llegir i respondre." - too_few_topics_notice: "Comencem aquesta discussió! Actualment hi ha %{currentTopics} / %{requiredTopics} temes. Les noves visites necessiten algunes converses per llegir i respondre." - too_few_posts_notice: "Comencem aquesta discussió! Actualment hi ha %{currentPosts} / %{requiredPosts} entrades. Les noves visites necessiten algunes converses per llegir i respondre." logs_error_rate_notice: reached: "%{relativeAge} – %{rate} ha arribat al límit de configuració de %{siteSettingRate}." exceeded: "%{relativeAge} – %{rate} ha superat el límit de configuració de %{siteSettingRate}." @@ -1016,7 +1008,6 @@ ca: link_description: "introdueix una descripció de l'enllaç" link_dialog_title: "Insereix un enllaç" link_optional_text: "títol opcional" - link_url_placeholder: "http://exemple.com" quote_title: "Cita en bloc" quote_text: "Cita en bloc" code_title: "Text preformatat" @@ -1422,14 +1413,9 @@ ca: action: "uneix les publicacions seleccionades" error: "Hi ha hagut una errada en unir les publicacions seleccionades." change_owner: - title: "Canvia la persona propietària de les publicacions" action: "canvia la propietat" error: "Hi ha hagut una errada en canviar la propietat de les publicacions." - label: "Nova persona propietària de les publicacions" placeholder: "identitat de la nova persona propietària" - instructions: - one: "Si us plau, selecciona la nova persona propietària de la publicació per {{old_user}}." - other: "Si us plau, selecciona la nova persona propietària de les {{count}} publicacions per {{old_user}}." change_timestamp: action: "canvia la marca de temps" invalid_timestamp: "La hi haurà marca en el futur." @@ -1876,7 +1862,6 @@ ca: this_week: "Setmana" today: "D'avui" other_periods: "mira amunt" - browser_update: 'Malauradament, el teu navegador és massa vell per treballar amb aquest lloc web. Si us plau actualitza el teu navegador.' permission_types: full: "Crea / Respon / Mira" create_post: "Respon / Mira" @@ -2037,8 +2022,6 @@ ca: bookmarks: "No hi ha més temes marcats com a preferits." search: "No hi ha més resultats de la cerca." invite: - custom_message: "Personalitza una mica més la teva invitació tot escrivint " - custom_message_link: "un missatge personalitzat" custom_message_placeholder: "Introdueix el teu missatge personalizat" custom_message_template_forum: "Ep! Hauries d'unir-te a aquest fòrum!" custom_message_template_topic: "Ep! Crec que gaudiràs d'aquest tema!" @@ -2311,7 +2294,6 @@ ca: new_style: "Nou estil" import: "Importa" delete: "Esborra" - about: "Modifica les fulles d'estil CSS i els encapçalaments HTML a aquest lloc web. Afegeix una personalització per començar." color: "Color" opacity: "Opacitat" copy: "Còpia" @@ -2463,7 +2445,6 @@ ca: filter: "Filtre:" title: "Accions d'equip" clear_filters: "Mostra-ho tot" - staff_user: "Persona de l'equip" target_user: "Identitat objectiu" subject: "Tema" when: "Quan" diff --git a/config/locales/client.cs.yml b/config/locales/client.cs.yml index 3147b2fc10..338fa03f04 100644 --- a/config/locales/client.cs.yml +++ b/config/locales/client.cs.yml @@ -285,12 +285,8 @@ cs: bookmark: "Kliknutím vložíte záložku na první příspěvek tohoto tématu" unbookmark: "Kliknutím odstraníte všechny záložky v tématu" bookmarks: - not_logged_in: "Pro přidání záložky se musíte přihlásit." created: "Záložka byla přidána." - not_bookmarked: "Tento příspěvek jste již četli. Klikněte pro přidání záložky." - last_read: "Toto je váš poslední přečtený příspěvek. Klikněte pro přidání záložky." remove: "Odstranit záložku" - confirm_clear: "Opravdu chcete odstranit všechny záložky z tohoto tématu?" topic_count_latest: one: "Zobrazit {{count}} nové nebo upravené téma" few: "Zobrazit {{count}} nová nebo upravená témata" @@ -313,7 +309,6 @@ cs: saved: "Uloženo!" upload: "Obrázek" uploading: "Nahrávám..." - uploading_filename: "Nahrávání {{filename}}..." uploaded: "Nahráno!" pasting: "Vkládám..." enable: "Zapnout" @@ -456,7 +451,6 @@ cs: all: "Všechny skupiny" empty: "Žádné viditelné skupiny." filter: "Filtrovat podle typu skupiny" - owner_groups: "Skupiny, jejichž jsem majitelem" close_groups: "Uzavřené skupiny" automatic_groups: "Automatické skupiny" automatic: "Automatické" @@ -996,9 +990,6 @@ cs: enabled: "Tato stránka je v režimu jen pro čtení. Prosim pokračujte v prohlížení, ale odpovídání a ostatní operace jsou momentálně vypnuté." login_disabled: "Přihlášení je zakázáno jelikož je stránka v režimu jen pro čtení." logout_disabled: "Odhlášení je zakázáno zatímco je stránka v režimu jen pro čtení." - too_few_topics_and_posts_notice: "Začněme tuto diskusi! V současné době tu je %{currentTopics} / %{requiredTopics} témat a %{currentPosts} / %{requiredPosts} příspěvků. Noví návštěvníci potřebují číst nějaké příspěvky a reagovat na ně." - too_few_topics_notice: "Začněme tuto diskusi! V současné době tu je %{currentTopics} / %{requiredTopics} témat. Noví návštěvníci potřebují číst nějaké příspěvky a reagovat na ně." - too_few_posts_notice: "Začněme tuto diskusi! V současné době tu je %{currentPosts}/%{requiredPosts} příspěvků. Noví návštěvníci potřebují číst nějaké příspěvky a reagovat na ně." logs_error_rate_notice: reached: "%{relativeAge} – %{rate} dosáhlo limitu stránky, který je %{siteSettingRate}." exceeded: "%{relativeAge} – %{rate} přesahuje limit stránky, který je %{siteSettingRate}." @@ -1266,7 +1257,6 @@ cs: link_description: "sem vložte popis odkazu" link_dialog_title: "Vložit odkaz" link_optional_text: "volitelný popis" - link_url_placeholder: "http://example.com" quote_title: "Bloková citace" quote_text: "Bloková citace" code_title: "Ukázka kódu" @@ -1828,16 +1818,9 @@ cs: action: "sluč vybrané příspěvky" error: "Během slučování vybraných příspěvků došlo k chybě." change_owner: - title: "Změnit autora" action: "změna autora" error: "Chyba při měnění autora u příspevků." - label: "Nový autor příspěvků" placeholder: "uživatelské jméno nového autora" - instructions: - one: "Vyberte prosím nového autora příspěvku od {{old_user}}." - few: "Vyberte prosím nového autora {{count}} příspěvků od {{old_user}}." - many: "Vyberte prosím nového autora {{count}} příspěvků od {{old_user}}." - other: "Vyberte prosím nového autora {{count}} příspěvků od {{old_user}}." change_timestamp: title: "Změnit časové razítko..." action: "změnit časovou značku" @@ -2435,7 +2418,6 @@ cs: this_week: "Týden" today: "Dnes" other_periods: "viz nahoře" - browser_update: 'Bohužel, váš prohlížeč je příliš starý, aby na něm Discourse mohl fungovat. Prosím aktualizujte svůj prohlížeč.' permission_types: full: "Vytvářet / Odpovídat / Prohlížet" create_post: "Odpovídat / Prohlížet" @@ -2621,8 +2603,6 @@ cs: bookmarks: "Žádná další oblíbená témata nejsou k dispozici." search: "Vyhledávání nic nenašlo." invite: - custom_message: "Aby byla pozvánka osobnější, napište" - custom_message_link: "vlastní zprávu" custom_message_placeholder: "Vložte vlastní zprávu" custom_message_template_forum: "Ahoj! Měl by se připojit na toto fórum!" custom_message_template_topic: "Ahoj, myslím si, že by se ti mohlo tohle téma líbit!" @@ -2988,7 +2968,6 @@ cs: import: "Import" delete: "Smazat" delete_confirm: "Smazat tento motiv? " - about: "Změn CSS styly a hlavičky HTML na stránkách. Přidej přizpůsobení na začátek." color: "Barva" opacity: "Neprůhlednost" copy: "Kopírovat" @@ -3028,7 +3007,6 @@ cs: upload_file_tip: "Vybrat položku k nahrání (png, woff2, etc...)" variable_name: "Název SCSS var:" upload: "Nahrát" - child_themes_check: "Motiv zahrnuje jiné dětské motivy" css_html: "Vlastí CSS/HTML" edit_css_html: "Upravit CSS/HTML" edit_css_html_help: "Neupravil jsi CSS nebo HTML" @@ -3212,7 +3190,6 @@ cs: filter: "Filtr:" title: "Akce redaktorů" clear_filters: "Zobrazit vše" - staff_user: "Člen redakce" target_user: "Cílový uživatel" subject: "Předmět" when: "Kdy" diff --git a/config/locales/client.da.yml b/config/locales/client.da.yml index 5c82358e4f..9150dd890a 100644 --- a/config/locales/client.da.yml +++ b/config/locales/client.da.yml @@ -232,12 +232,8 @@ da: bookmark: "Klik for at sætte et bogmærke i det første indlæg i denne tråd" unbookmark: "Klik for at fjerne alle bogmærker i dette emne" bookmarks: - not_logged_in: "Beklager, du skal været logget ind for at bogmærke indlæg" created: "Du har bogmærket dette indlæg." - not_bookmarked: "Du har læst dette indlæg; klik for at bogmærke det" - last_read: "Dette er det seneste indlæg, du har læst; klik for at bogmærke det" remove: "Fjern bogmærke" - confirm_clear: "Er du sikker på du vil slette alle bogmærker fra dette emne?" preview: "forhåndsvising" cancel: "annullér" save: "Gem ændringer" @@ -245,7 +241,6 @@ da: saved: "Gemt!" upload: "Upload" uploading: "Uploader…" - uploading_filename: "Overfører {{filename}}..." uploaded: "Uploadet!" enable: "Aktiver" disable: "Deaktiver" @@ -831,9 +826,6 @@ da: enabled: "Dette website kan kun læses lige nu. Fortsæt endelig med at kigge, men der kan ikke svares, likes eller andet indtil videre." login_disabled: "Log in er deaktiveret midlertidigt, da forummet er i \"kun læsnings\" tilstand." logout_disabled: "Log ud er deaktivere mens websitet kun kan læses." - too_few_topics_and_posts_notice: "Lad os få startet denne diskussion! Der er i øjeblikket %{currentTopics} / %{requiredTopics} emner og %{currentPosts} / %{requiredPosts} indlæg. Nye besøgende har brug for samtaler at læse og svare på." - too_few_topics_notice: "Lad os få startet denne diskussion ! Der er i øjeblikket %{currentTopics} / %{requiredTopics} emner. Nye besøgende har brug for samtaler at læse og svare på." - too_few_posts_notice: "Lad os få startet denne diskussion ! Der er i øjeblikket %{currentPosts} / %{requiredPosts} indlæg. Nye besøgende har brug for samtaler at læse og svare på." logs_error_rate_notice: reached: "%{relativeAge} – %{rate} nåede grænse for konfiguration af sitet på %{siteSettingRate}." exceeded: "%{relativeAge} – %{rate} overskred grænse for konfiguration af sitet på %{siteSettingRate}." @@ -1048,7 +1040,6 @@ da: link_description: "skriv linkets beskrivelse her" link_dialog_title: "Indsæt link" link_optional_text: "evt. titel" - link_url_placeholder: "http://example.com" quote_title: "Citatblok" quote_text: "Citatblok" code_title: "Præformateret tekst" @@ -1487,14 +1478,9 @@ da: action: "flet valgte indlæg" error: "Der opstod en fejl med at flette de valgte indlæg." change_owner: - title: "Skift hvem der ejer emnet" action: "skift ejerskab" error: "Der opstod en fejl da ejerskabet skulle skiftes." - label: "Ny ejer af emner" placeholder: "brugernavn på ny ejer" - instructions: - one: "Vælg den nye ejer af indlægget, oprindeligt skrevet af {{old_user}}." - other: "Vælg den nye ejer af {{count}} indlæg, oprindeligt skrevet af {{old_user}}." change_timestamp: title: "Tilpas tidsstempel..." action: "ret tidsstempel" @@ -1961,7 +1947,6 @@ da: this_week: "Uge" today: "I dag" other_periods: "se top" - browser_update: 'Desværre, din browser er for gammel til at kunne virke med dette forum. Opgradér venligst din browser.' permission_types: full: "Opret / Besvar / Se" create_post: "Besvar / Se" @@ -2123,8 +2108,6 @@ da: bookmarks: "Der er ikke flere bogmærkede emner." search: "Der er ikke flere søgeresultater." invite: - custom_message: "Gør din invitation lidt mere personlig ved at skrive en " - custom_message_link: "personlig besked" custom_message_placeholder: "Skriv en personlig besked" custom_message_template_forum: "Hej, du burde tilmelde dig dette forum!" custom_message_template_topic: "Hej, jeg tænkte du måske ville synes om dette emne!" @@ -2412,7 +2395,6 @@ da: import: "Importer" delete: "Slet" delete_confirm: "Slet dette tema?" - about: "Modificer CSS stylesheets og HTML headere på sitet. Tilføj en tilpasning for at starte." color: "Farve" opacity: "Gennemsigtighed" copy: "Kopier" @@ -2447,7 +2429,6 @@ da: custom_sections: "Tilpassede sektioner:" theme_components: "Temakomponenter" variable_name: "SCSS var navn:" - child_themes_check: "Tema inkluderer andre underordnede temaer" css_html: "Tilpasset CSS/HTML" edit_css_html: "Redigér CSS/HTML" edit_css_html_help: "Du har ikke redigeret i hverken CSS eller HTML" @@ -2607,7 +2588,6 @@ da: staff_actions: title: "Handlinger" clear_filters: "Vis alt" - staff_user: "Bruger" target_user: "Bruger" subject: "Subjekt" when: "Hvorår" diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml index f7754f1174..3fde484ae8 100644 --- a/config/locales/client.de.yml +++ b/config/locales/client.de.yml @@ -118,11 +118,11 @@ de: email: 'diesen Link per E-Mail senden' action_codes: public_topic: "hat das Thema öffentlich gemacht, %{when}" - private_topic: "hat dieses Thema in eine Nachricht umgewandelt %{when}" + private_topic: "hat dieses Thema in eine Nachricht umgewandelt, %{when}" split_topic: "Thema aufgeteilt, %{when}" invited_user: "%{who} eingeladen, %{when}" invited_group: "%{who} eingeladen, %{when}" - user_left: "%{who} hat sich selbst von dieser Nachricht entfernt %{when}" + user_left: "%{who} hat sich selbst von dieser Nachricht entfernt, %{when}" removed_user: "%{who} entfernt, %{when}" removed_group: "%{who} entfernt, %{when}" autobumped: "Thema wurde automatisch nach oben geschoben, %{when}" @@ -145,8 +145,8 @@ de: enabled: 'sichtbar gemacht, %{when}' disabled: 'unsichtbar gemacht, %{when}' banner: - enabled: 'hat dieses Banner erstellt %{when}. Es wird oberhalb jeder Seite angezeigt, bis es vom Benutzer weggeklickt wird.' - disabled: 'hat dieses Banner entfernt %{when}. Es wird nicht mehr oberhalb jeder Seite angezeigt.' + enabled: 'hat dieses Banner erstellt, %{when}. Es wird oberhalb jeder Seite angezeigt, bis es vom Benutzer weggeklickt wird.' + disabled: 'hat dieses Banner entfernt, %{when}. Es wird nicht mehr oberhalb jeder Seite angezeigt.' topic_admin_menu: "Thema administrieren" wizard_required: "Willkommen bei deinem neuen Discourse! Lass uns mit dem Setup-Assistenten ✨ starten" emails_are_disabled: "Die ausgehende E-Mail-Kommunikation wurde von einem Administrator global deaktiviert. Es werden keinerlei Benachrichtigungen per E-Mail verschickt." @@ -245,12 +245,10 @@ de: bookmark: "Klicke hier, um ein Lesezeichen auf den ersten Beitrag in diesem Thema zu setzen." unbookmark: "Klicke hier, um alle Lesezeichen in diesem Thema zu entfernen." bookmarks: - not_logged_in: "Entschuldige, du musst angemeldet sein, um ein Lesezeichen setzen zu können." created: "du hast ein Lesezeichen zu diesem Beitrag hinzugefügt" - not_bookmarked: "Du hast diesen Beitrag gelesen. Klicke, um ein Lesezeichen zu setzen." - last_read: "Das ist der letzte Beitrag, den du gelesen hast. Klicke, um ein Lesezeichen zu setzen." + not_bookmarked: "Lesezeichen auf diesen Beitrag setzen" remove: "Lesezeichen entfernen" - confirm_clear: "Bist du sicher, dass du alle Lesezeichen in diesem Thema entfernen möchtest?" + confirm_clear: "Bist du sicher, dass du alle Lesezeichen in diesem Thema entfernen möchtest? " drafts: resume: "Fortsetzen" remove: "Entfernen" @@ -273,7 +271,8 @@ de: saved: "Gespeichert!" upload: "Hochladen" uploading: "Wird hochgeladen…" - uploading_filename: "{{filename}} wird hochgeladen…" + uploading_filename: "wird hochgeladen: {{filename}}..." + clipboard: "Zwischenablage" uploaded: "Hochgeladen!" pasting: "Einfügen..." enable: "Aktivieren" @@ -521,7 +520,7 @@ de: topic_stat_sentence: one: "%{count} neues Thema seit 1 %{unit}." other: "%{count} neue Themen seit 1 %{unit}." - more: " (%{count} weitere) …" + n_more: "Kategorien (%{count} weitere) ..." ip_lookup: title: IP-Adressen-Abfrage hostname: Hostname @@ -782,16 +781,17 @@ de: title: "Wiederholung des Passworts" auth_tokens: title: "Kürzlich benutzte Geräte" - title_logs: "Authentifizierungs-Logs" - ip_address: "IP Adresse" - created: "Erzeugt" - first_seen: "Erstmalig gesehen" - last_seen: "Zuletzt gesehen" - operating_system: "Betriebssystem" - location: "Ort" - action: "Aktion" - login: "Einloggen" - logout: "Überall ausloggen" + ip: "IP" + details: "Details" + log_out_all: "Überall abmelden" + active: "gerade aktiv" + not_you: "Das bist nicht du?" + show_all: "Alle anzeigen ({{count}})" + show_few: "Weniger anzeigen" + was_this_you: "Warst das du?" + browser_and_device: "{{browser}} auf {{device}}" + secure_account: "Mein Konto absichern" + latest_post: "Dein letzter Beitrag..." last_posted: "Letzter Beitrag" last_emailed: "Letzte E-Mail" last_seen: "Zuletzt gesehen" @@ -987,9 +987,6 @@ de: enabled: "Diese Website befindet sich im Nur-Lesen-Modus. Du kannst weiterhin Inhalte lesen, aber das Erstellen von Beiträgen, Vergeben von Likes und Durchführen einiger weiterer Aktionen ist derzeit nicht möglich." login_disabled: "Die Anmeldung ist deaktiviert während sich die Website im Nur-Lesen-Modus befindet." logout_disabled: "Die Abmeldung ist deaktiviert während sich die Website im Nur-Lesen-Modus befindet." - too_few_topics_and_posts_notice: "Lass' die Diskussionen starten! Es existieren bisher %{currentTopics} von %{requiredTopics} benötigten Themen und %{currentPosts} von %{requiredPosts} benötigten Beiträgen. Neue Besucher benötigen bestehende Konversationen, die sie lesen und auf die sie antworten können." - too_few_topics_notice: "Lass' die Diskussionen starten! Es existieren bisher %{currentTopics} von %{requiredTopics} benötigten Themen. Neue Besucher benötigen bestehende Konversationen, die sie lesen und auf die sie antworten können." - too_few_posts_notice: "Lass' die Diskussionen starten! Es existieren bisher %{currentPosts} von %{requiredPosts} benötigten Beiträgen. Neue Besucher benötigen bestehende Konversationen, die sie lesen und auf die sie antworten können." logs_error_rate_notice: reached: "%{relativeAge} – %{rate} hat die eingestellte Grenze für die Site von %{siteSettingRate} erreicht." exceeded: "%{relativeAge} – %{rate} hat die eingestellte Grenze für die Site von %{siteSettingRate} überschritten." @@ -1165,6 +1162,7 @@ de: categories_with_featured_topics: "Kategorien mit empfohlenen Themen" categories_and_latest_topics: "Kategorien und aktuelle Themen" categories_and_top_topics: "Kategorien und angesagte Themen" + categories_boxes_with_topics: "Spalten mit hervorgehobenen Themen" shortcut_modifier_key: shift: 'Umschalt' ctrl: 'Strg' @@ -1279,7 +1277,6 @@ de: link_description: "gib hier eine Link-Beschreibung ein" link_dialog_title: "Link einfügen" link_optional_text: "Optionaler Titel" - link_url_placeholder: "http://example.com" quote_title: "Zitat" quote_text: "Zitat" code_title: "Vorformatierter Text" @@ -1327,7 +1324,7 @@ de: desc: "Entwerfe ein Thema, das nur für das Team sichtbar ist." toggle_topic_bump: label: "Bump des Themas umschalten" - desc: "Antworten ohne das Bump-Datum des Themas zu ändern." + desc: "Antworten ohne das Datum der neuesten Antwort zu ändern" notifications: tooltip: regular: @@ -1818,15 +1815,13 @@ de: action: "ausgewählte Beiträge zusammenführen" error: "Es gab einen Fehler beim Zusammenführen der ausgewählten Beiträge." change_owner: - title: "Eigentümer der Beiträge ändern" + title: "Eigentümer ändern" action: "Eigentümer ändern" error: "Beim Ändern des Eigentümers der Beiträge ist ein Fehler aufgetreten." - label: "Neuer Eigentümer der Beiträge" placeholder: "Benutzername des neuen Eigentümers" instructions: - one: "Bitte wähle den neuen Eigentümer für den Beitrag von {{old_user}}." - other: "Bitte wähle den neuen Eigentümer für {{count}} Beiträge von {{old_user}}." - instructions_warn: "Bitte beachte, dass alle Benachrichtigungen für diesen Beitrag nicht rückwirkend auf den neuen Benutzer übertragen werden." + one: "Bitte wähle einen neuen Eigentümer für den Beitrag von @{{old_user}}" + other: "Bitte wähle einen neuen Eigentümer für {{count}} Beiträge von @{{old_user}}" change_timestamp: title: "Zeitstempel ändern…" action: "Erstelldatum ändern" @@ -2346,7 +2341,6 @@ de: this_week: "Woche" today: "Heute" other_periods: "zeige angesagte Themen:" - browser_update: 'Dein Webbrowser ist leider zu alt, um dieses Forum zu besuchen. Bitte installiere einen neueren Browser.' permission_types: full: "Erstellen / Antworten / Ansehen" create_post: "Antworten / Ansehen" @@ -2529,8 +2523,7 @@ de: bookmarks: "Das waren alle Themen mit Lesezeichen." search: "Es gibt keine weiteren Suchergebnisse." invite: - custom_message: "Mache deine Einladung ein bisschen mehr persönlich, indem du etwas schreibst:" - custom_message_link: "persönliche Nachricht" + custom_message: "Gestalte deine Einladung etwas mehr persönlicher, in dem du eine eigene Nachricht schreibst." custom_message_placeholder: "Gib deine persönliche Nachricht ein" custom_message_template_forum: "Hey, du solltest diesem Forum beitreten!" custom_message_template_topic: "Hey, ich dachte, dir könnte dieses Thema gefallen!" @@ -2939,7 +2932,6 @@ de: import: "Importieren" delete: "Löschen" delete_confirm: "Dieses Theme löschen?" - about: "Ändere die Stylesheets (CSS) und den HTML-Header auf der Website. Füge eine Anpassung hinzu, um zu starten." color: "Farbe" opacity: "Transparenz" copy: "Kopieren" @@ -2959,13 +2951,19 @@ de: theme: "Theme" component: "Komponente" components: "Komponenten" + theme_name: "Theme-Name" + component_name: "Komponenten-Name" + themes_intro: "Wähle ein bestehendes Theme oder erstelle ein neues, um loszulegen" + beginners_guide_title: "Leitfaden für Einstieger zur Verwendung von Discourse-Themes" + developers_guide_title: "Leitfaden für Entwickler zur Verwendung von Discourse-Themes" + browse_themes: "Community-Themes durchsuchen" import_theme: "Design importieren" customize_desc: "Anpassen:" title: "Designs" - modal_title: "Erstelle Theme" create: "Erstelle" create_type: "Typ:" create_name: "Name:" + name_too_short: "Der Name muss mindestens 4 Zeichen lang sein." long_title: "Farben, CSS und HTML-Inhalte deiner Seite erweitern" edit: "Bearbeiten" edit_confirm: "Dies ist ein Remote-Theme, wenn du CSS/HTML bearbeitest, werden deine Änderungen zurückgesetzt, wenn du das Theme das nächste Mal aktualisierst." @@ -2980,10 +2978,17 @@ de: color_scheme_select: "Wähle Farben für dieses Theme" custom_sections: "Benutzerdefinierte Abschnitte:" theme_components: "Theme-Komponenten" - switch_component: "Erzeuge Theme" - switch_component_alert: "Bist Du sicher, dass Du diese Komponente in ein Theme konvertieren möchtest? Dies wird es zu einem unabhängigen Theme machen und es wird als Kind von allen Themes entfernt werden." - switch_theme: "Komponente erzeugen" - switch_theme_alert: "Bist Du sicher, dass Du dieses Theme zu einer Komponente konvertieren möchtest? Es will als Elternteil von all Komponenten entfernt werden." + convert: "Umwandeln" + convert_component_alert: "Bist Du sicher, dass du diese Komponente in ein Theme umwandeln möchtest? Sie wird als Komponente entfernt von %{relatives}." + convert_component_tooltip: "Wandle diese Komponente in ein Theme um" + convert_theme_alert: "Bist Du sicher, dass du dieses Theme in eine Komponente umwandeln möchtest? Sie wird als übergeordnetes Element entfernt von %{relatives}." + convert_theme_tooltip: "Wandle dieses Theme in eine Komponente um" + inactive_themes: "Inaktive Themes:" + broken_theme_tooltip: "Dieses Theme hat fehlerhaftes CSS, HTML oder YAML." + default_theme_tooltip: "Dieses Theme ist das Standardtheme der Seite." + updates_available_tooltip: "Updates sind verfügbar für dieses Theme" + and_x_more: "und {{count}} mehr." + collapse: Zuklappen uploads: "Uploads" no_uploads: "Du kannst Medieninhalte hochladen, die zu deinem Theme gehören, wie etwa Schriftarten und Bilder." add_upload: "Upload hinzufügen" @@ -2995,7 +3000,10 @@ de: no_overwrite: "Ungültiger Variablenname. Darf keine existierende Variable überschreiben." must_be_unique: "Ungültiger Variablenname. Muss eindeutig sein." upload: "Hochladen" - child_themes_check: "Theme beinhaltet andere Kinder-Themes" + select_component: "Komponente auswählen..." + unsaved_changes_alert: "Du hast deine Änderungen noch nicht gespeichert, möchtest du sie verwerfen und weitermachen?" + discard: "Verwerfen" + stay: "Bleiben" css_html: "Benutzerdefiniertes CSS/HTML" edit_css_html: "Bearbeite CSS/HTML" edit_css_html_help: "Du hast kein CSS oder HTML bearbeitet" @@ -3003,6 +3011,7 @@ de: import_web_tip: "Repository mit dem Theme" import_file_tip: ".dcstyle.json Datei mit dem Theme" is_private: "Theme ist in einem privaten Git-Repository" + remote_branch: "Branch-Name (optional)" public_key: "Gewähre dem folgenden öffentlichen Schlüssel den Zugriff auf das Repository:" about_theme: "Über das Theme" license: "Lizenz" @@ -3019,6 +3028,7 @@ de: one: "Theme liegt 1 Commit zurück!" other: "Theme liegt {{count}} Commits zurück!" compare_commits: "(Siehe neue Beiträge)" + repo_unreachable: "Das Git-Repository dieses Themes konnte nicht kontaktiert werden. Fehlermeldung:" scss: text: "CSS" title: "Gib benutzerdefiniertes CSS ein, wir akzeptieren alle gültigen CSS und SCSS-Stile" @@ -3180,7 +3190,7 @@ de: filter: "Filter:" title: "Team-Aktionen" clear_filters: "Alles anzeigen" - staff_user: "Team-Mitglied" + staff_user: "Benutzer" target_user: "Betroffener Benutzer" subject: "Objekt" when: "Wann" @@ -3250,6 +3260,7 @@ de: change_badge: "Abzeichen ändern" delete_badge: "Abzeichen löschen" merge_user: "Benutzer zusammenführen" + entity_export: "Entität exportieren" screened_emails: title: "Gefilterte E-Mails" description: "Wenn jemand ein Konto erstellt, werden die folgenden E-Mail-Adressen überprüft und es wird die Anmeldung blockiert oder eine andere Aktion ausgeführt." diff --git a/config/locales/client.el.yml b/config/locales/client.el.yml index 28d9781503..43bef6117a 100644 --- a/config/locales/client.el.yml +++ b/config/locales/client.el.yml @@ -234,12 +234,8 @@ el: bookmark: "Πάτα εδώ για να μπεί σελιδοδείκτης στην πρώτη ανάρτηση του νήματος." unbookmark: "Πάτα εδώ για να αφαιρεθούν όλοι οι σελιδοδείκτες από αυτό το νήμα." bookmarks: - not_logged_in: "λυπούμαστε, για να τοποθετήσεις έναν σελιδοδείκτη θα πρέπει να συνδεθείς πρώτα" created: "έχεις προσθέσει σελιδοδείκτη σε αυτή την ανάρτηση" - not_bookmarked: "έχεις διαβάσει αυτή την ανάρτηση, πάτησε για να προστεθεί σελιδοδείκτης" - last_read: "αυτή είναι η τελευταία ανάρτηση που διάβασες, πάτησε για να προστεθεί σελιδοδείκτης" remove: "Αφαίρεση Σελιδοδείκτη" - confirm_clear: "Είστε σίγουρος ότι θέλετε να αφαιρεθούν όλοι οι σελιδοδείκτες από αυτό το νήμα;" preview: "προεπισκόπιση" cancel: "ακύρωση" save: "Αποθήκευση Αλλαγών" @@ -247,7 +243,6 @@ el: saved: "Αποθηκεύτηκε!" upload: "Ανέβασμα" uploading: "Ανεβαίνει..." - uploading_filename: "Ανέβασμα {{filename}}..." uploaded: "Ανέβηκε!" enable: "Ενεργοποίηση" disable: "Απενεργοποίηση" @@ -832,9 +827,6 @@ el: enabled: "Αυτή η ιστοσελίδα είναι σε λειτουργία μόνο ανάγνωσης. Παρακαλώ συνέχισε να κάνεις περιήγηση, όμως το να απαντάς να πατάς \"μου αρέσει\" και κάποιες άλλες λειτουργίες δεν είναι διαθέσιμες τώρα." login_disabled: "Η δυνατότητα σύνδεσης έχει απενεργοποιηθεί όσο η ιστοσελίδα είναι σε κατάσταση μόνο ανάγνωσης." logout_disabled: "Η αποσύνδεση δεν είναι διαθέσιμη ενώ η ιστοσελίδα είναι σε λειτουργία μόνο ανάγνωσης." - too_few_topics_and_posts_notice: "Ας αρχίσουμε αυτή την συζήτηση! Υπάρχουν %{currentTopics} / %{requiredTopics} νήματα και %{currentPosts} / %{requiredPosts} αναρτήσεις. Οι νέοι επισκέπτες χρειάζονται κάποιες συνομιλίες για να τις διαβάσουν και να απαντήσουν σε αυτές." - too_few_topics_notice: "Ας αρχίσουμε αυτή την συζήτηση! Υπάρχουν %{currentTopics} / %{requiredTopics} νήματα. Οι νέοι επισκέπτες χρειάζονται κάποιες συνομιλίες για να τις διαβάσουν και να απαντήσουν σε αυτές." - too_few_posts_notice: "Ας ξεκινήσουμε αυτή τη συζήτηση! Υπάρχουν %{currentPosts} / %{requiredPosts} αναρτήσεις. Οι νέοι επισκέπτες χρειάζονται κάποιες συνομιλίες για να τις διαβάσουν και να απαντήσουν σε αυτές." logs_error_rate_notice: reached: "%{relativeAge} – %{rate} έχει φτάσει το όριο των ρυθμίσεων της ιστοσελίδας το οποίο είναι %{siteSettingRate}." exceeded: "%{relativeAge} - %{rate} υπερβαίνει το όριο των ρυθμίσεων της ιστοσελίδας το οποίο είναι %{siteSettingRate}." @@ -1071,7 +1063,6 @@ el: link_description: "δώσε εδώ μια περιγραφή για το σύνδεσμο" link_dialog_title: "Εισαγωγή Υπερσύνδεσμου" link_optional_text: "προαιρετικός τίτλος" - link_url_placeholder: "http://example.com" quote_title: "Μπλοκ Κειμένου" quote_text: "Μπλοκ κειμένου σε παράθεση" code_title: "Προ-διαμορφωμένο κείμενο" @@ -1546,14 +1537,9 @@ el: action: "συγχώνευσε επιλεγμένες αναρτήσεις" error: "Προέκυψε σφάλμα κατά τη συγχώνευση των επιλεγμένων αναρτήσεων." change_owner: - title: "Άλλαξε Ιδιοκτήτη των Αναρτήσεων" action: "αλλαγή ιδιοκτήτη" error: "Παρουσιάστηκε ένα σφάλμα κατά την αλλαγή του ιδιοκτήτη των αναρτήσεων." - label: "Νέος Ιδιοκτήτης των Αναρτήσεων" placeholder: "όνομα χρήστη του νέου ιδιοκτήτη" - instructions: - one: "Παρακαλώ επίλεξε τον νέο ιδιοκτήτη της ανάρτησης του {{old_user}}." - other: "Παρακαλώ επίλεξε τον νέο ιδιοκτήτη των {{count}} αναρτήσεων του {{old_user}}." change_timestamp: title: "Αλλαγή Χρονοσήμανσης..." action: "αλλαγή χρονοσήμανσης" @@ -2032,7 +2018,6 @@ el: this_week: "Εβδομάδα" today: "Σήμερα" other_periods: "δες τα κορυφαία" - browser_update: 'Δυστυχώς, το πρόγραμμα περιήγησής σου είναι πολύ παλιό για να δουλέψει σε αυτό τον ιστότοπο. Παρακαλώ αναβάθμισέ το.' permission_types: full: "Δημιούργησε / Απάντησε / Δες" create_post: "Απάντησε / Δες" @@ -2200,8 +2185,6 @@ el: bookmarks: "Δεν υπάρχουν άλλα νήματα με σελιδοδείκτη." search: "Δεν υπάρχουν άλλα αποτελέσματα για αυτή την αναζήτηση." invite: - custom_message: "Κάνε την πρόσκλησή σου λίγο πιο προσωπική γράφοντας ένα" - custom_message_link: "προσαρμοσμένο μήνυμα" custom_message_placeholder: "Πρόσθεσε το προσαρμοσμένο μήνυμά σου" custom_message_template_forum: "Γεια, θα πρέπει να λάβεις μέρος σε αυτό το χώρο συζητήσεων!" custom_message_template_topic: "Γεια, νομίζω ότι θα απολαύσεις αυτό το νήμα!" @@ -2509,7 +2492,6 @@ el: import: "Εισαγωγή" delete: "Σβήσιμο" delete_confirm: "Διαγραφή αυτού του θέματος;" - about: "Προσάρμοσε τα CSS stylesheets και τα HTML headers της ιστοσελίδας. Πρόσθεσε μια προσαρμογή για να ξεκινήσεις." color: "Χρώμα" opacity: "Αδιαφάνεια" copy: "Αντιγραφή" @@ -2548,7 +2530,6 @@ el: upload_file_tip: "Επιλέξτε στοιχείο για μεταφόρτωση (png, woff2, etc...)" variable_name: "SCSS var name:" upload: "Μεταφόρτωση" - child_themes_check: "Το θέμα περιλαμβάνει άλλα υποθέματα" css_html: "Custom CSS/HTML" edit_css_html: "Edit CSS/HTML" edit_css_html_help: "Δεν επεξεργαστήκατε το CSS ή το HTML" @@ -2714,7 +2695,6 @@ el: filter: "Φίλτρο:" title: "Ενέργειες Συνεργατών" clear_filters: "Δείξτα όλα" - staff_user: "Συνεργάτης" target_user: "Χρήστη που αφορά" subject: "Αντικείμενο" when: "Πότε" diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index fc28a6e444..e15b2eb44a 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -37,31 +37,31 @@ en: thousands: "{{number}}k" millions: "{{number}}M" dates: - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ time: "h:mm a" - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ timeline_date: "MMM YYYY" - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ long_no_year: "MMM D h:mm a" - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ long_no_year_no_time: "MMM D" - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ full_no_year_no_time: "MMMM Do" - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ long_with_year: "MMM D, YYYY h:mm a" - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ long_with_year_no_time: "MMM D, YYYY" - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ full_with_year_no_time: "MMMM Do, YYYY" - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ long_date_with_year: "MMM D, 'YY LT" - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ long_date_without_year: "MMM D, LT" - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ long_date_with_year_without_time: "MMM D, 'YY" - # Use Moment.js format string: http://momentjs.com/docs/#/displaying/format/ + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ long_date_without_year_with_linebreak: "MMM D{{username}} {{description}}" + invited_to_topic: "{{username}} {{description}}" + invitee_accepted: "{{username}} priėmė jūsų kvietimą" + moved_post: "{{username}} perkeltas {{description}}" + linked: "{{username}} {{description}}" + granted_badge: "Užsitanavo '{{description}}'" + topic_reminder: "{{username}} {{description}}" + watching_first_post: "Nauja tema {{description}}" + group_message_summary: + one: "{{count}} žinutė, jūsų {{group_name}}pato dėžutėje" + few: "{{count}} žinutės, jūsų {{group_name}}pato dėžutėje" + many: "{{count}}žinučių, jūsų {{group_name}} pato dėžutėje" + other: "{{count}} žinutės, jūsų {{group_name}} pašto dėžutėje" + popup: + mentioned: '{{username}} paminėjo tave "{{topic}}" - {{site_title}}' + group_mentioned: '{{username}} paminėjo tave "{{topic}}" - {{site_title}}' + quoted: '{{username}} pacitavo tave "{{topic}}" - {{site_title}}' + replied: '{{username}} atsakė tau "{{topic}}" - {{site_title}}' + posted: '{{username}} paskelbė "{{topic}}" - {{site_title}}' + private_message: '{{username}} atsiuntė privačią žinutė "{{topic}}" - {{site_title}}' + linked: '{{username}} panaudojo tavo įrašą "{{topic}}" - {{site_title}}' + confirm_title: 'Pranešimai įgalinti - %{site_title}' + confirm_body: 'Pavyko! Pranešimai buvo įgalinti.' + upload_selector: + title: "Pridėti nuotrauką" + title_with_attachments: "Pridėti nautrauką arba dokumentą" + from_my_computer: "Iš įrenginio" + from_the_web: "Iš naršyklės" + remote_tip: "nuoroda į nuotrauką" + remote_tip_with_attachments: "nuoroda į nuotrauką ar failą {{authorized_extensions}}" + local_tip: "Pasirinkti nuotraukas iš įrenginio" + local_tip_with_attachments: "pasirinkti nuotraukas ar failus iš įrenginio {{authorized_extensions}}" + hint: "(taip pat gali perstumti ir įmesti į redagavimo skydą)" + hint_for_supported_browsers: "gali perstumti, numesti ir kopijuoti nuotraukas į redagavimo skydą" + uploading: "Įkeliama" + select_file: "Pasirinkti failus" + image_link: "nurodyta nuotrauka skirta" + default_image_alt_text: pveikslėlis + search: + sort_by: "Rūšiuoti pagal" + relevance: "Tinkamumas" + latest_post: "Paskutiniai įrašai" + latest_topic: "Naujausios temos" + most_viewed: "Labiausiai Žiūrimos" + most_liked: "Labiausiai Mėgstamos" + select_all: "Pažymėti visus" + clear_all: "Ištrinti viską" + too_short: "Jūsų paieškos frazė, per trumpa." + result_count: + one: "1 rezultatas iš{{term}}" + few: "{{count}}{{plus}}rezultatų iš{{term}}" + many: "{{count}}{{plus}} rezultatai iš{{term}}" + other: "{{count}}{{plus}} rezultatai iš {{term}}" + title: "temų, įrašų, vartotojų ar kategorijų paieška" + full_page_title: "ieškoti temų arba įrašų" + no_results: "Nerasta jokių rezultatų." + no_more_results: "Nerasta jokių rezultatų." + searching: "Ieškoma..." + post_format: "#{{post_number}} nuo {{username}}" + results_page: "Paieškos rezultatai ir '{{term}}'" + start_new_topic: "Galbūt pradėkite naują temą?" + search_google_button: "Google" + search_google_title: "Ieškoti šioje svetainėje" + context: + user: "Ieškoti įrašų nuo @{{username}}" + category: "Ieškoti #{{category}}kategorijoje" + topic: "Ieškoti šioje temoje" + private_messages: "Ieškoti žinučių" + advanced: + title: Išplėstinė paieška + posted_by: + label: Paskelbė + in_category: + label: Kategorija + in_group: + label: Grupėje + with_badge: + label: Su Ženkleliu + with_tags: + label: Pažymėtas + filters: + likes: Man patiko + watching: Aš stebiu + tracking: Aš seku + private: Mano žinutėse + bookmarks: Aš išsaugojes + pinned: yra prisegtas + unpinned: neprisegtas + seen: Aš skaitau + unseen: Aš neskaitau + wiki: yra wiki + images: Įtraukti nuotrauką(as) + statuses: + label: Kur temos + open: atvira + closed: uždaryta + archived: archyvuota + noreplies: neturi atsakymų + post: + time: + label: Paskelbta + before: anksčiau + after: po to + hamburger_menu: "Eiti į kitą temų sąrašą ar kategoriją" + new_item: "Nauja" + go_back: 'grįžti atgal' + not_logged_in_user: 'Vartotojo puslapis su veiksmų ir nustatymų aprašymu' + current_user: 'eitį i savo vartotojo puslapį' + topics: + new_messages_marker: "paskutinis apsilankymas" + bulk: + select_all: "Pasirinkti viską" + clear_all: "Išvalyti viską" + unlist_topics: "Atžymėti temas" + reset_read: "Atkurti, kaip perskaityta" + delete: "Ištrinti temas" + dismiss: "Praleisti" + dismiss_read: "Praleisti visas neperskaitytas" + dismiss_button: "Praleisti..." + dismiss_tooltip: "Praleisti tik naujus įrašus ar nebesekti temos" + also_dismiss_topics: "Nebesekti šių temų, kad jos niekada nebūtų rodomos, kaip neperskaitytos" + dismiss_new: "Praleisti Naujas" + toggle: "perjungti temų pasirinkimus" + actions: "Veiksmai" + change_category: "Nustatyti kategoriją" + close_topics: "Uždaryti temas" + archive_topics: "Archyvuoti temas" + notification_level: "Pranešimai" + choose_new_category: "Pasirinkti naują kategoriją temoms:" + selected: + one: "Jūs pasirinkote {{count}} temą." + few: "Jūs pasirinkote {{count}} temas." + many: "Jūs pasirinkote {{count}} temų." + other: "Jūs pasirinkote {{count}} temų." + none: + unread: "Jūs neturite neperskaitytų temų." + new: "Jūs neturite naujų temų." + read: "Jūs dar neperskaitėte jokių temų." + posted: "Jūs dar nerašėte jokiose temose." + latest: "Nėra jokių paskutinių temų. Tai liūdina." + hot: "Nėra karštų temų." + bookmarks: "Jūs dar neturite pažymėtų temų." + category: "Nėra jokių temų kategorijoje {{category}}." + top: "Nėra jokių TOP temų." + search: "Nerasta jokių rezultatų." + bottom: + latest: "Daugiau nėra jokių naujausių temų." + hot: "Daugiau nėra jokių karštų temų." + posted: "Daugiau nėra jokių paskelbtų temų." + read: "Daugiau nėra jokių perskaitytų temų." + new: "Daugiau nėra jokių naujų temų." + unread: "Daugiau nėra jokių neperskaitytų temų." + category: "Daugiau nėra jokių temų kategorijoje {{category}}." + top: "Daugiau nėra jokių populiarių temų." + bookmarks: "Daugiau pažymėtų temų nėra" + search: "Daugiau paieškos rezultatų nėra" + topic: + filter_to: + one: "temoje 1 įrašas" + few: "temoje {{count}} įrašai" + many: "teoje {{count}} įrašų" + other: "temoje {{count}} įrašai" + create: 'Nauja Tema' + create_long: 'Sukurti naują temą' + open_draft: "Atviras juodraštis" + private_message: 'Rašyti žinutę' + archive_message: + help: 'Perkelti žinutes į archyvą' + title: 'Archyvuoti' + move_to_inbox: + title: 'Perkelti į Pranešimų dėžutę' + help: 'Perkelti žinutes atgal į Pranešimų dėžutę' + edit_message: + title: 'Redaguoti žinutę' + list: 'Temos' + new: 'nauja tema' + unread: 'Neperskaitytos' + new_topics: + one: '{{count}} nauja tema' + few: '{{count}} naujos temos' + many: '{{count}} naujų temų' + other: '{{count}} naujų temų' + unread_topics: + one: '{{count}} neperskaityta tema' + few: '{{count}} neperskaitytos temos' + many: '{{count}} neperskaitytų temų' + other: '{{count}} neperskaitytų temų' + title: 'Tema' + invalid_access: + title: "Tema yra privati" + description: "Atsiprašome, bet jūs neturite teisių šiai temai!" + login_required: "Jums reikia prisijungti, norint peržiūrėti šią temą." + server_error: + title: "Nepavyko užkrauti temos" + description: "Atsiprašome, įvyko klaida. Prašome pameginti vėl po kelių minučių. Jei problema pasikartos, prašome mums pranešti" + not_found: + title: "Tema nerasta" + description: "Atsiprašome, bet mes negalėjome rasti jūsų temos. Gal ji buvo ištrinta moderatoriaus?" + total_unread_posts: + one: "šioje temoje turi 1 neperskaitytą įrašą" + few: "šioje temoje tu turi {{count}} neperskaitytų įrašų" + many: "šioje temoje tu turi {{count}} neperskaitytų įrašų" + other: "šioje temoje tu turi {{count}} neperskaitytų įrašų" + unread_posts: + one: "šioje temoje tu turi 1 neperskaitytą seną įrašą" + few: "šioje temoje tu turi {{count}} neperskaitytų senų įrašų" + many: "šioje temoje tu turi {{count}} neperskaitytų senų įrašų" + other: "šioje temoje tu turi {{count}} neperskaitytų senų įrašų" + new_posts: + one: "šioje temoje yra 1 naujas įrašas nuo paskutinio tavo skaitymo" + few: "šioje temoje yra {{count}} naujų įrašų nuo paskutinio tavo skaitymo" + many: "šioje temoje yra {{count}} naujų įrašų nuo paskutinio tavo skaitymo" + other: "šioje temoje yra {{count}} naujų įrašų nuo paskutinio tavo skaitymo" + likes: + one: "Šiuo metu temą mėgsta 1 vartotojas" + few: "Šiuo metu temą mėgsta {{count}} vartotojų" + many: "Šiuo metu temą mėgsta {{count}} vartotojų" + other: "Šiuo metu temą mėgsta {{count}} vartotojų" + back_to_list: "Grįžti į temų sąrašą" + options: "Nustatymai" + show_links: "Rodyti šios temos nuorodas" + toggle_information: "perjungti temos detales" + read_more_in_category: "Nori skaityti daugiau? Ieškok kitų temų {{catLink}} arba {{latestLink}}." + read_more: "Norite skaityti daugiau? {{catLink}} arba {{latestLink}}." + read_more_MF: "Šiuo metu { UNREAD, plural, =0 {} one { yra 1 neperskaityta } other { yra # neperskaitytos } } { NEW, plural, =0 {} one { {BOTH, select, true{and } false {is } other{}} 1 nauja tema} other { {BOTH, select, true{and } false {are } other{}} # naujos temos} } remaining, or {CATEGORY, select, true {browse other topics in {catLink}} false {{latestLink}} other {}}" + browse_all_categories: Žiūrėkite visas kategorijas + view_latest_topics: peržiūrėkite paskutines temas + suggest_create_topic: "Kodėl gi nesukūrus naujos temos?" + jump_reply_up: Pereiti į ankstesnį atsakymą + jump_reply_down: Pereitį į sekantį atsakymą + deleted: "Tema buvo ištrinta" + topic_status_update: + title: "Temos laikmatis" + save: "Nustatyti laikmatį" + num_of_hours: "Valandų kiekis:" + remove: "Pašalinti laikmatį" + publish_to: "Publikuoki į:" + when: "Kada:" + public_timer_types: Temos laikmačiai + auto_update_input: + later_today: "Šiandien vėliau" + tomorrow: "Rytoj" + later_this_week: "Šia savaitę vėliau" + this_weekend: "Šį savaitgalį" + next_week: "Kitą savaitę" + two_weeks: "Dvi savaitės" + next_month: "Kitą mėnesį" + three_months: "Trys mėnesiai" + six_months: "Pusė metų" + one_year: "Metai" + forever: "Am-inai" + pick_date_and_time: "Pasirinkite datą ir laiką" + temp_open: + title: "Laikinai atidaryti" + temp_close: + title: "Laikinai u-daryti" + reminder: + title: "Man priminti" + status_update_notice: + auto_open: "Ši tema automatiškai atsidarys po %{timeLeft} ." + auto_close: "Ši tema automatiškai užsidarys po %{timeLeft}." + auto_close_title: 'Automatinio uždarymo nustatymai' + timeline: + back: "Atgal" + replies_short: "%{current} / %{total}" + progress: + title: temos progresas + go_top: "eiti į viršų" + go_bottom: "eiti į apačią" + go: "eiti" + jump_bottom: "Pereiti į sekantį įrašą" + jump_prompt: "peršokti į..." + jump_prompt_of: "iš %{count} įrašų" + jump_bottom_with_number: "pereiti į įrašą %{post_number}" + jump_prompt_or: "arba" + total: visi įrašai + current: Dabartinis įrašas + notifications: + reasons: + "3_6": 'Gausite pranešimus nes Stebite šią kategoriją.' + "3_5": 'Gausite pranešimus, nes pradėjote Stebėti šią temą.' + "3_2": 'Gausite pranešimus, nes Stebite šią temą.' + "3_1": 'Gausite pranešimus, nes sukūrėte šią temą.' + "3": 'Gausite pranešimus, nes Stebite šią temą.' + "1_2": 'Būsi perspėtas kai kažkas paminės tavo @vardą ar tau atsakys.' + "1": 'Būsi perspėtas kai kažkas paminės tavo @vardą ar tau atsakys.' + "0_7": 'Jūs ignoruojate visus šios temos pranešimus' + "0_2": 'Jūs ignoruojate visus pranešimus šioje temoje.' + "0": 'Jūs ignoruojate visus pranešimus šioje temoje.' + watching_pm: + title: "Stebimos" + description: "Būsite perspėtas dėl kiekvieno naujo atsakymo šioje žinutėje." + watching: + title: "Stebimos" + description: "Būsite perspėtas dėl kiekvieno naujo atsakymo šioje temoje." + tracking_pm: + title: "Sekamos" + description: "Bus rodomas šios žinutės naujų atsakymų skaičius. Būsi perspėtas kai kažkas paminės tavo @vardą ar tau atsakys." + tracking: + title: "Sekamos" + description: "Bus rodomas šios temos naujų atsakymų skaičius. Būsi perspėtas kai kažkas paminės tavo @vardą ar tau atsakys." + regular: + title: "Įprastas" + description: "Būsi perspėtas kai kažkas paminės tavo @vardą ar tau atsakys." + regular_pm: + title: "Įprastas" + description: "Būsi perspėtas kai kažkas paminės tavo @vardą ar tau atsakys." + muted_pm: + title: "Nutyldita" + description: "Tau nebus siunčiami pranešimai susiję su šia žinute." + muted: + title: "Nutildytos" + description: "Tau nebus siunčiami pranešimai susiję su šia žinute." + actions: + recover: "Atstatyti ištrintą Temą" + delete: "Ištrinti temą" + open: "Atidaryti temą" + close: "Uždaryti temą" + multi_select: "Pasirinkti Įrašai..." + pin: "Prisegti Temą..." + unpin: "Atsegti Temą..." + unarchive: "Atstatyti archyvuotą Tema" + archive: "Archyvuoti temą" + invisible: "Išimti iš Sąrašo" + visible: "Įkelti į Sąrašą" + reset_read: "Atkurti Perskaitymo Duomenis" + feature: + pin: "Prisegti Temą" + unpin: "Atsegti Temą" + pin_globally: "Prisegti Temą Globaliai" + make_banner: "Paryškinta Tema" + remove_banner: "Išjungti Paryškintą Temą" + reply: + title: 'Atsakyti' + clear_pin: + title: "Išstrinti Prisegimą" + help: "Ištrinti Prisegimą šioje temoje, kad tema daugiau nebūtų rodoma viršuje." + share: + title: 'Pasidalinti' + help: 'Pasidalink šios temos nuoroda' + print: + title: 'Spausdinti' + help: 'Atverti spausdinimui draugišką šios temos versiją' + flag_topic: + title: 'Uždėk vėliavą' + help: 'Uždėk temai vėliavą privačiai arba išsiųsk privatų pranešimą apie tai' + success_message: 'Tu sėkmingai uždėjai temai vėliavą.' + feature_topic: + title: "Charakterizuok šią temą" + pin: "Nustatyk šią temą, kad laikytųsi kategorijos {{categoryLink}} viršuje" + confirm_pin: "Tu jau turi {{count}} prisegtų temų. Per daug prisegtų temų gali atstumti anoniminius ir naujus vartotojus. Ar esi tikras, jog nori prisegti šią temą?" + unpin: "Pašalink šią temą iš {{categoryLink}} kategorijos sąrašo viršaus." + unpin_until: "Pašalinti temą iš {{categoryLink}} kategorijos viršaus arba palaukti iki %{until}." + pin_note: "Vartotojai gali Atsegti temą nuo viršaus individualiai sau." + pin_validation: "Terminas reikalauja Prisegti šią temą." + not_pinned: "{{categoryLink}} nėra prisegtų temų " + already_pinned: + one: "Tema prisegta šioje kategorijoje {{categoryLink}}: 1" + few: "Prisegtos temos šioje kategorijoje {{categoryLink}}: {{count}}" + many: "Prisegtos temos šioje kategorijoje {{categoryLink}}: {{count}}" + other: "Prisegtos temos šioje kategorijoje {{categoryLink}}: {{count}}" + pin_globally: "Iškelti temą virš visų kitų temų sąrašo iki " + confirm_pin_globally: "Jūs jau turite {{count}} globaliai Prisegtas temas. Per daug prisegtų temų gali atbaidyti naujus ir anoniminius vartotojus. Ar tikrai to norite?" + unpin_globally: "Pašalinti šią temą iš visų temų sąrašo viršaus." + unpin_globally_until: "Pašalinti temą iš visų temų sąrašo viršaus arba palaukti iki %{until}." + global_pin_note: "Vartotojai gali Atsegti temą nuo sąrašo viršaus individualiai." + not_pinned_globally: "Nėra jokių globaliai Prisegtų temų." + already_pinned_globally: + one: "Šiuo metu globaliai prisegta tema: 1" + few: "Šiuo metu globaliai Prisegtos temos: {{count}}" + many: "Šiuo metu globaliai Prisegtos temos: {{count}}" + other: "Šiuo metu globaliai Prisegtos temos: {{count}}" + make_banner: "Paryškink šią temą, kad ji atsidurtų visų puslapių sąrašo viršuje." + remove_banner: "Pašalinti paryškintą temą, kuri yra visų puslapių viršuje." + banner_note: "Vartotojai gali uždaryti paryškiuntą temą. Tik viena tema gali būti paryškinta tam tikru metu" + no_banner_exists: "Šiuo metu nėra jokių Paryškintų (banerinių) temų" + banner_exists: "Šiuo metu yra Paryškinta tema." + inviting: "Kviečiama..." + invite_private: + title: 'Pakviesti į Žinutę' + action: "Kviesti" + success: "Mes pakvietėme vartotoją atsakyti į šią žinutę." + group_name: "grupės pavadinimas" + controls: "Temų Nustatymai" + invite_reply: + title: 'Pakviesti' + username_placeholder: "Slapyvardis" + action: 'Siųsti pakvietimą' + help: 'pakviesk kitus į šią temą el. laišku ar pranešimu' + to_forum: "Mes išsiųsime trumpą el. laišką leidžiantį tavo draugui iš karto prisijungti tiesiog paspaudžiant nuorodą. Jokia registracija nebūtina." + sso_enabled: "Įveskite vartotojo vardą žmogaus, kurį norite pakviesti į šią temą." + to_topic_blank: "Įrašykite vartotojo vardą ar el. paštą žmogaus, kurį norite pakviesti į šią temą." + to_topic_email: "El. paštas įvestas. Mes išsiųsime trumpą el. laišką, kuris suteiks galimybę iš karto atsakyti į temą." + to_topic_username: "Vartotojo vardas įvestas. Mes išsiųsime pranešimą su nuoroda į šią temą." + to_username: "Įveskite vartotojo vardą žmogaus, kurį norite pakviesti. Mes išsiųsime pranešima su nuoroda į šią temą." + email_placeholder: 'vardas@pavizdys.lt' + success_email: "Mes išsiuntėme pakvietimą į {{emailOrUsername}}. Mes pranešime, kai pakvietimas bus patvirtintas. Stebėk pakvietimų kortelę savo paskyroje, kad žinotum pakvietimo statusą." + success_username: "Vartotojas buvo pakviestas dalyvauti temoje." + error: "Atsiprašome, tačiau nepavyko pakviesti šio žmogaus. Gal būt jis jau buvo pakviestas?" + login_reply: 'Prisijunk, kad atsakytum' + filters: + n_posts: + one: "1 įrašas" + few: "{{count}} įrašai" + many: "{{count}}įrašų" + other: "{{count}}įrašai" + cancel: "Išjungti filtrus" + split_topic: + title: "Perkelti į naują temą" + action: "perkelti į naują temą" + topic_name: "Naujos temos pavadinimas" + instructions: + one: "Jūs tuoj sukursite naują temą ir įkesite įrašą, kurį pažymėjote." + few: "Jūs tuoj sukursite naują temą ir įkesite {{count}} įrašus, kuriuos pažymėjote." + many: "Jūs tuoj sukursite naują temą ir įkesite {{count}} įrašus, kuriuos pažymėjote." + other: "Jūs tuoj sukursite naują temą ir įkesite {{count}} įrašus, kuriuos pažymėjote." + merge_topic: + title: "Perkelti į esamą temą" + action: "perkelti į esamą temą" + instructions: + one: "Prašome pasirinkti temą, į kurią norėtumėte perkelti šį įrašą." + few: "Prašome pasirinkti temą, į kurią norėtumėte perkelti šiuos {{count}} įrašus." + many: "Prašome pasirinkti temą, į kurią norėtumėte perkelti šiuos {{count}} įrašus." + other: "Prašome pasirinkti temą, į kurią norėtumėte perkelti šiuos {{count}} įrašus." + merge_posts: + title: "Sulieti pasirinktus įrašus" + action: "sulieti pasirinktus įrašus" + change_owner: + action: "pakeisti valdymo teises" + error: "Įvyko klaida keičiant įrašų valdymo teisę." + placeholder: "naujojo valdytojo vartotojo vardas" + change_timestamp: + action: "pakeisti laiko formatą" + invalid_timestamp: "Laiko formatas negali būti ateityje." + error: "Įvyko klaida keičiant šios temos laiko formatą." + instructions: "Prašome įvesti naują šios temos laiko formatą. Visi šios temos įrašai bus atnaujinti pagal nustatytą datą." + multi_select: + select: 'pasirinkti' + selected: 'pasirinkta ({{count}})' + select_post: + label: 'pasirinkti' + title: 'Pridėti įrašą prie pasirinktų' + selected_post: + label: 'pasirinktas' + title: 'Spustelk kad pašalinti įrašą iš pasirinktų' + select_replies: + label: 'pasirink +atsakyti' + select_below: + label: 'pasirink +žemiau' + delete: ištrinti pasirinktus + cancel: atšaukti pasirinkimus + select_all: pažymėti visus + deselect_all: nieko nepasirinkti + description: + one: Jūs pasirinkote 1 įrašą. + few: "Jūs pasirinkote {{count}} įrašus." + many: "Jūs pasirinkote {{count}} įrašus." + other: "Jūs pasirinkote {{count}} įrašus." + post: + quote_reply: "Citata" + edit: " {{link}} {{replyAvatar}} {{username}}" + edit_reason: "Priežastis:" + post_number: "įrašas {{number}}" + wiki_last_edited_on: "wiki paskutinį kartą redaguota " + last_edited_on: "įrašas paskutinį kartą atnaujintas" + reply_as_new_topic: "Atsakyti naujoje temoje" + continue_discussion: "Tęsiama {{postLink}} diskusija:" + follow_quote: "eiti į cituotą įrašą" + show_full: "Rodyti Pilną Įrašą" + show_hidden: 'Rodyti paslėptą turinį.' + deleted_by_author: + one: "(autoriaus išimtas įrašas automatiškai bus ištrintas per %{count} valandą, nebent turėjo vėliavą)" + few: "(autoriaus išimtas įrašas automatiškai bus ištrintas per %{count} valandas, nebent turėjo vėliavą)" + many: "(autoriaus išimtas įrašas automatiškai bus ištrintas per %{count} valandas, nebent turėjo vėliavą)" + other: "(autoriaus išimtas įrašas automatiškai bus ištrintas per %{count} valandas, nebent turėjo vėliavą)" + expand_collapse: "išskleisti/suskleisti" + gap: + one: "Peržiūrėti 1 paslėptą atsakymą" + few: "peržiūrėti {{count}} paslėptus atsakymus" + many: "peržiūrėti {{count}} paslėptus atsakymus" + other: "peržiūrėti {{count}} paslėptus atsakymus" + unread: "Įrašas yra neperskaitytas" + has_replies: + one: "{{count}} Atsakymas" + few: "{{count}} Atsakymai" + many: "{{count}} Atsakymai" + other: "{{count}} Atsakymai" + has_likes: + one: "{{count}} žmogui tai patinka" + few: "{{count}} žmonėms tai patinka" + many: "{{count}} žmonėms tai patinka" + other: "{{count}} žmonėms tai patinka" + has_likes_title: + one: "1 žmogui patiko šis įrašas" + few: "{{count}} žmonėms patinka šis įrašas" + many: "{{count}} žmonėms patinka šis įrašas" + other: "{{count}} žmonėms patinka šis įrašas" + has_likes_title_only_you: "tau patiko šis įrašas" + has_likes_title_you: + one: "tau ir 1 žmogui patiko šis įrašas" + few: "tau ir {{count}} žmonėms patiko šis įrašas" + many: "tau ir {{count}} žmonėms patiko šis įrašas" + other: "tau ir {{count}} žmonėms patiko šis įrašas" + errors: + create: "Atsiprašome, įvyko klaida kuriant įrašą. Prašome pamėginti dar kartą." + edit: "Atsiprašome, įvyko klaida redaguojant įrašą. Prašome pamėginti dar kartą." + upload: "Atsiprašome, įvyko klaida įkeliant šį dokumentą. Prašome pamėginti dar kartą." + too_many_uploads: "Atsiprašome, bet jūs galite įkelti tik vieną failą vienu metu." + image_upload_not_allowed_for_new_user: "Atsiprašome, bet nauji vartotojai negali įkelti nuotraukų." + attachment_upload_not_allowed_for_new_user: "Atsiprašome, bet nauji vartotojai negali įkelti priedų." + attachment_download_requires_login: "Atsiprašome, bet jūs turite būti prisijungęs, kad galėtumėt atsisiųsti priedus." + abandon: + confirm: "Ar tikrai norite atšaukti savo įrašą?" + no_value: "Ne, palikti" + yes_value: "Taip, atšaukti" + via_email: "Šis įrašas buvo gautas per el. paštą" + whisper: "Šis įrašas yra privatus šnabždesys moderatoriams" + wiki: + about: "šis įrašas yra wiki" + archetypes: + save: 'Išsaugoti nustatymus' + controls: + reply: "Pradėk rašyti atsakymą šiam įrašui" + like: "įrašas man patinka" + has_liked: "tau patinka šis įrašas" + undo_like: "nepatinka" + edit: "redaguoti įrašą" + edit_action: "Redaguoti" + edit_anonymous: "Apgailestaujame, bet jūs turite būti prisijungęs, kad redaguotumėte šį įrašą." + flag: "Uždėk įrašui privačią vėliavą arba išsiųsk privatų pranešimą" + delete: "ištrinti įrašą" + undelete: "anuliuoti įrašo ištrinimą" + share: "pasidalinti nuoroda į šį įrašą" + more: "Daugiau" + delete_replies: + direct_replies: + one: "Taip, ir 1 tiesioginį atsakymą" + few: "Taip, ir {{count}}tiesioginius atsakymus" + many: "Taip, ir {{count}}tiesioginių atsakymų" + other: "Taip, ir {{count}} tiesioginius atsakymus" + all_replies: + one: "Taip, ir 1 atsakymą" + few: "Taip, ir visus {{count}} atsakymus" + many: "Taip, ir visus {{count}}atsakymų" + other: "Taip, ir visus {{count}} atsakymus" + just_the_post: "Ne, tik šį įrašą" + admin: "įrašo administravimas" + wiki: "Sukurti Wiki" + unwiki: "Ištrinti Wiki" + convert_to_moderator: "Pridėk Komandos spalvą" + revert_to_regular: "Pašalink Komandos spalvą" + rebake: "Perkurti HTML" + unhide: "Panaikinti slėpimo būsena" + change_owner: "Pakeisti Valdytoją" + lock_post: "Užrakinti įrašą" + unlock_post: "Atrakinti įrašą" + actions: + flag: 'Uždėk vėliavą' + undo: + off_topic: "Nuimti vėliavą" + spam: "Nuimti vėliavą" + inappropriate: "Nuimti vėliavą" + bookmark: "Anuliuoti žymę" + like: "Anuliuoti Patinka" + people: + like: "mėgsta tai" + like_capped: + one: "ir {{count}}kitas mėgsta tai" + few: "ir {{count}}kitų mėgsta tai" + many: "ir {{count}}kitų mėgsta tai " + other: "ir {{count}} kitų mėgsta tai" + by_you: + off_topic: "Tu pažymėjai tai kaip \"ne į temą\"." + spam: "Tu pažymėjai tai, kaip šiukšlę" + inappropriate: "Tu pažymėjai tai, kaip nepriimtiną" + notify_moderators: "Tu pasiūlei moderavimą." + notify_user: "Jūs išsiuntėt žinutę šiam vartotojui" + bookmark: "Jūs uždėjot žymą ant šio įrašo" + like: "Jūs tai mėgstate" + by_you_and_others: + off_topic: + one: "Tu ir dar 1 žmogus pažymėjo tai, kaip \"ne į temą\"." + few: "Tu ir {{count}} žmonės pažymėjo tai kaip \"ne į temą\"." + many: "Tu ir {{count}} žmonės pažymėjo tai kaip \"ne į temą\"." + other: "Tu ir {{count}} žmonės pažymėjo tai kaip \"ne į temą\"." + spam: + one: "Tu ir dar 1 žmogus pažymėjo tai, kaip šiukšlę." + few: "Tu ir {{count}} žmonės pažymėjo tai kaip šiukšlę" + many: "Tu ir {{count}} žmonės pažymėjo tai kaip šiukšlę" + other: "Tu ir {{count}} žmonės pažymėjo tai kaip šiukšlę" + inappropriate: + one: "Tu ir dar 1 žmogus pažymėjo tai kaip nepriimtiną." + few: "Tu ir {{count}} žmonės pažymėjo tai kaip nepriimtiną." + many: "Tu ir {{count}} žmonės pažymėjo tai kaip nepriimtiną." + other: "Tu ir {{count}} žmonės pažymėjo tai kaip nepriimtiną." + notify_moderators: + one: "Tu ir dar vienas žmogus siūlo moderavimą" + few: "Tu ir {{count}} žmonės siūlo moderavimą" + many: "Tu ir {{count}} žmonės siūlo moderavimą" + other: "Tu ir {{count}} žmonės siūlo moderavimą" + notify_user: + one: "Tu ir dar 1 žmogus išsiuntė žinutę šiam vartotojui" + few: "Tu ir {{count}} žmonės išsiuntė žinutę šiam vartotojui" + many: "Tu ir {{count}} žmonės išsiuntė žinutę šiam vartotojui" + other: "Tu ir {{count}} žmonės išsiuntė žinutę šiam vartotojui" + bookmark: + one: "Tu ir dar vienas žmogus pridėjo žymą šiam įrašui" + few: "Jūs ir {{count}} kitų žmonių pridėjo šį įrašą prie žymių" + many: "Jūs ir {{count}} kitų žmonių pridėjo šį įrašą prie žymių" + other: "Jūs ir {{count}} kitų žmonių pridėjo šį įrašą prie žymių" + like: + one: "Jūs ir {{count}} kitas žmogus mėgsta šį pranešimą" + few: "Jūs ir {{count}} kiti žmonės mėgsta šį pranešimą" + many: "Jūs ir {{count}} kitų žmonių mėgsta šį pranešimą" + other: "Jūs ir {{count}} kitų žmonių mėgsta šį pranešimą" + by_others: + off_topic: + one: "1 žmogus pažymėjo tai kaip \"ne į temą\"." + few: "{{count}} žmonės pažymėjo tai kaip \"ne į temą\"." + many: "{{count}} žmonės pažymėjo tai kaip \"ne į temą\"." + other: "{{count}} žmonės pažymėjo tai kaip \"ne į temą\"." + spam: + one: "1 žmogus pažymėjo tai kaip šiukšlę" + few: "{{count}} žmonės pažymėjo tai kaip šiukšlę" + many: "{{count}} žmonės pažymėjo tai kaip šiukšlę" + other: "{{count}} žmonės pažymėjo tai kaip šiukšlę" + inappropriate: + one: "1 žmogus pažymėjo tai kaip nepriimtiną" + few: "{{count}} žmonės pažymėjo tai kaip nepriimtiną" + many: "{{count}} žmonės pažymėjo tai kaip nepriimtiną" + other: "{{count}} žmonės pažymėjo tai kaip nepriimtiną" + notify_moderators: + one: "1 žmogus siūlo moderavimą" + few: "{{count}} žmonės siūlo moderavimą" + many: "{{count}} žmonės siūlo moderavimą" + other: "{{count}} žmonės siūlo moderavimą" + notify_user: + one: "1 žmogus išsiuntė žinutę šiam vartotojui" + few: "{{count}} žmonės išsiuntė žinutę šiam vartotojui" + many: "{{count}} žmonės išsiuntė žinutę šiam vartotojui" + other: "{{count}} žmonės išsiuntė žinutę šiam vartotojui" + bookmark: + one: "{{count}} žmogus pridėjo šį pranešimą prie žymių" + few: "{{count}} žmonės pridėjo šį pranešimą prie žymių" + many: "{{count}} žmonių pridėjo žymą šiam įrašui" + other: "{{count}} žmonių pridėjo žymą šiam įrašui" + like: + one: "{{count}} žmogus tai mėgsta" + few: "{{count}} žmonės tai mėgsta" + many: "{{count}} žmonių tai mėgsta" + other: "{{count}} žmonių tai mėgsta" + revisions: + controls: + first: "Pirmoji peržiūra" + previous: "Prieš tai buvusi peržiūra" + next: "Sekanti peržiūra" + last: "Paskutinė peržiūra" + hide: "Slėpti peržiūras" + show: "Rodyti peržiūras" + edit_wiki: "Redaguoti Wiki" + edit_post: "Redaguoti Įrašą" + comparing_previous_to_current_out_of_total: "{{previous}} {{current}} / {{total}}" + displays: + inline: + title: "Rodyti suteiktas paslaugas su priedais ir panaikinimais" + button: 'HTML' + side_by_side: + title: "Rodyti suteiktas paslaugas su tarpusavio skirtumais" + button: 'HTML' + side_by_side_markdown: + title: "Rodyti pirminį šaltinį su tarpusavio skirtumais" + raw_email: + displays: + text_part: + button: 'Tekstas' + html_part: + button: 'HTML' + category: + can: 'galimas…' + none: '(jokia kategorija)' + all: 'Visos kategorijos' + choose: 'category…' + edit: 'redaguoti' + edit_long: "Redaguoti" + view: 'Peržiūrėti temas kategorijoje' + general: 'Bendriniai' + settings: 'Nustatymai' + topic_template: "Temos šablonas" + tags: "Žymos" + delete: 'Ištrinti kategoriją' + create: 'Nauja Kategorija' + create_long: 'Sukurti naują kategoriją' + save: 'Išsaugoti kategoriją' + slug: 'Kategorijos Stabdis' + slug_placeholder: '(Pasirinktinai) brūkšniniai žodžiai skirti URL' + creation_error: Įvyko klaida kuriant kategoriją. + save_error: Įvyko klaida išsaugant kategoriją. + name: "Kategorijos pavadinimas" + description: "Aprašymas" + topic: "kategorijos tema" + logo: "Kategorijos logotipo paveiksliukas" + background_image: "Kategorijos fono paveiksliukas" + badge_colors: "Ženkliukų spalvos" + background_color: "Fono spalva" + foreground_color: "Priekinio plano spalva" + name_placeholder: "Daugiausiai vienas arba du žodžiai" + color_placeholder: "Bet kokia internetinė spalva" + delete_confirm: "Ar tikrai norite ištrinti šią kategoriją?" + delete_error: "Įvyko klaida ištrinant kategoriją." + list: "Visos kategorijos" + no_description: "Prašome pridėti aprašymą šiai kategorijai." + change_in_category_topic: "Redaguoti aprašyma" + already_used: 'Ši spalva jau priskirta prie kitos kategorijos' + security: "Saugumo" + special_warning: "Įspėjimas: Ši kategorija yra iš anksto numatyta kategorija ir saugumo nustatymai negali būti keičiami. Jeigu nenorite naudoti šios kategorijos, ištrinkie ją vietoj pakartotino naudojimo." + images: "Paveiksliukai" + email_in: " papildomas naujas el. pašto adresas:" + email_in_allow_strangers: "Gauti el. laiškus iš anoniminių paskyrų neturinčių vartotojų " + email_in_disabled: "Naujų temų kūrimas per el. paštą yra negalimas Puslapio Nustatymuose. Jei nori skelbti naujas temas per el. paštą," + email_in_disabled_click: 'nustatykite "email in" nustatymus.' + sort_order: "Temų sąrasą rūšiuoti oagal\"" + allow_badges_label: "Leisti trofėjų apdovanojimus šioje kategorijoje" + edit_permissions: "Redaguoti leidimus" + add_permission: "Pridėti leidimus" + this_year: "šiais metais" + position: "Vieta:" + default_position: "Numatyta pozicija" + position_disabled: "Kategorijos bus rodomos pagal aktyvumą. Tam, kad nustatytum kategorijų rodymo tvarką," + position_disabled_click: 'nueik į "fixed category positions" nustatymus.' + parent: "Tėvinė kategoriją" + notifications: + watching: + title: "Stebimos" + tracking: + title: "Sekamos" + regular: + title: "Įprastas" + description: "Būsi perspėtas kai kažkas paminės tavo @vardą ar tau atsakys." + muted: + title: "Nutildytos" + description: "Tau nebus siunčiami pranešimai susiję su šia kategorijos tema." + sort_options: + default: "numatytasis" + likes: "Mėgsta" + views: "Peržiūros" + posts: "įrašai" + activity: "Veikla" + posters: "Komentatoriai" + category: "Kategorija" + created: "Sukurta" + subcategory_list_styles: + boxes: "Dėžutės" + boxes_with_featured_topics: "Dėžutės su išskirtinėm temom" + flagging: + title: 'Ačiū, kad padedi padedi išlaikyti forumą civilizuotu!' + action: 'Uždėti Įrašui Vėliavą' + take_action: "Imtis Veiksmų" + notify_action: 'Žinutės' + official_warning: 'Oficialus įspėjimas' + delete_spammer: "Ištrinti Vartotoją" + yes_delete_spammer: "Taip, ištrinti šį kenkėją" + ip_address_missing: "(N/A)" + hidden_email_address: "(paslėptas)" + submit_tooltip: "Patvirtinti privačią vėliavą" + take_action_tooltip: "Prieiti prie vėliavų ribos tuoj pat, o ne laukti daugiau vartotojų vėliavų" + cant: "Apgailestaujame, tačiau šiuo metu negalite uždėti šiam įrašui vėliavos. " + notify_staff: 'Įspėti moderatorius privačiai' + formatted_name: + off_topic: "Tai yra ne į temą" + inappropriate: "Tai yra nepriimtina" + spam: "Tai yra šiukšlė" + custom_placeholder_notify_user: "Buk konkretesnis, buk konstruktyvus ir visada būk malonus." + custom_placeholder_notify_moderators: "Leiskite mums sužinoti kuo būtent esate susirūpinęs. Pateikite nuorodas ir pavyzdžius jei tik įmanoma." + custom_message: + at_least: + one: "įveskite bent jau 1 simbolį" + few: "įveskite bent jau {{count}} simbolius" + many: "įveskite bent jau {{count}}simbolių" + other: "įveskite bent jau {{count}}simbolius" + more: + one: "liko 1..." + few: "liko {{count}}..." + many: "liko {{count}}..." + other: "liko {{count}}..." + flagging_topic: + title: "Ačiū, kad padedi padedi išlaikyti forumą civilizuotu!" + action: "Temos su vėliavomis" + notify_action: "Žinutės" + topic_map: + title: "Temos Aprašymas" + participants_title: "Dažni Poster'iai" + links_title: "Populiarios nuorodos" + links_shown: "rodyti daugiau nuorodų..." + clicks: + one: "%{count} paspaudimas" + few: "%{count} paspaudimai" + many: "%{count} paspaudimų" + other: "%{count} paspaudimų" + post_links: + title: + one: "1 daugiau" + few: "%{count}daugiau" + many: "%{count}daugiau" + other: "%{count}daugiau" + topic_statuses: + warning: + help: "Tai Oficialus Ispėjimas" + bookmarked: + help: "Jūs uždėjot žymą ant šios temos" + locked: + help: "Ši tema yra uždaryta, todėl joje nebegalima rašyti" + archived: + help: "Ši tema yra archyvuota, todėl jos negalima keisti" + locked_and_archived: + help: "Ši tema yra uždaryta, todėl joje nebegalima rašyti" + unpinned: + title: "Atsegta" + help: "Ši tema yra Atžymėta tik tau. Ji bus rodoma normalia tvarka." + pinned_globally: + title: "Prisegta globaliai" + help: "Ši tema yra globaliai Prisegta. Ji bus rodoma kategorijų sąrašo viršuje." + pinned: + title: "Prisegta" + help: "Ši tema yra Pažymėta tik tau. Ji bus rodoma sąrašo kategorijos sąrašo viršuje." + invisible: + help: "Ši tema yra išimta iš sąrašo. Ji daugiau nebebus rodoma temų sąraše ir ją galima pasiekti tik su tiesiogine nuoroda." + posts: "Įrašai" + posts_long: "Šiuo metu yra {{number}} įrašų šioje temoje" + posts_likes_MF: | + Ši tema turi {count, plural, one {1 reply} other {# replies}} {ratio, select, + low {with a high like to post ratio} + med {with a very high like to post ratio} + high {with an extremely high like to post ratio} + other {}} + original_post: "Originalus įrašas" + views: "Peržiūros" + views_lowercase: + one: "peržiūra" + few: "peržiūros" + many: "peržiūros" + other: "peržiūros" + replies: "Atsakymai" + views_long: + one: "ši tema buvo peržiūrėta 1 kartą" + few: "ši tema buvo peržiūrėta {{number}} kartus" + many: "ši tema buvo peržiūrėta {{number}}kartų" + other: "ši tema buvo peržiūrėta {{number}} kartus" + activity: "Aktyvumas" + likes: "Patikimai" + likes_lowercase: + one: "patikimas" + few: "patikimai" + many: "patikimai" + other: "patikimai" + likes_long: "Šiuo metu temoje yra {{number}} Patikimų" + users: "Vartotojai" + users_lowercase: + one: "vartotojas" + few: "vartotojai" + many: "vartotojai" + other: "vartotojai" + category_title: "Kategorija" + history: "Istorija" + changed_by: "pagal {{author}}" + raw_email: + title: "Įeinantis paštas" + not_available: "Nėra galimybių!" + categories_list: "Kategorijų sąrašas" + filters: + with_topics: "%{filter} temos" + with_category: "%{filter} %{category} temos" + latest: + title: "Paskutinės" + title_with_count: + one: "Paskutinis (1)" + few: "Paskutinės ({{count}})" + many: "Paskutinės ({{count}})" + other: "Paskutinės ({{count}})" + help: "temos su paskutiniais įrašais" + hot: + title: "Karštos" + help: "sąrašas karščiausių temų" + read: + title: "Perskaityti" + help: "Temos, kurias perskaitei, pagal paskutinių perskaitytų temų tvarką" + search: + title: "Paieška" + help: "Ieškoti visose temose" + categories: + title: "Kategorijos" + title_in: "Kategorija - {{categoryName}}" + help: "Visos temos sugrupuotos pagal kategoriją" + unread: + title: "Neperskaitytos" + title_with_count: + one: "Neperskaitytas (1)" + few: "Neperskaitytos ({{count}})" + many: "Neperskaitytos ({{count}})" + other: "Neperskaitytos ({{count}})" + help: "temos, kurias stebide ar sekate su neperskaitytais įrašais" + lower_title_with_count: + one: "1 neperskaitytas" + few: "{{count}} neperskaitytų" + many: "{{count}} neperskaitytų" + other: "{{count}} neperskaitytų" + new: + lower_title_with_count: + one: "1 nauja" + few: "{{count}} nauji" + many: "{{count}} nauji" + other: "{{count}} nauji" + lower_title: "Nauja" + title: "Naujos" + title_with_count: + one: "Naujas (1)" + few: "Naujos ({{count}})" + many: "Naujos ({{count}})" + other: "Naujos ({{count}})" + help: "Per paskutines dienas sukurtos temos" + posted: + title: "Mano Įrašai" + help: "temos, kuriose yra tavo įrašas" + bookmarks: + title: "Žymės" + help: "Temos, kurias pažymėjai" + category: + title: "{{categoryName}}" + title_with_count: + one: "{{categoryName}} (1)" + few: "{{categoryName}} ({{count}})" + many: "{{categoryName}} ({{count}})" + other: "{{categoryName}} ({{count}})" + help: "paskutinės temos kategorijoje {{categoryName}} " + top: + title: "Populiarios" + help: "pačios aktyviausios temos paskutiniaisiais metais, mėnesį, savaitę ar dieną" + all: + title: "Per visą laiką" + yearly: + title: "Kasmet" + quarterly: + title: "Kas ketvirtį" + monthly: + title: "Kas mėnesį" + weekly: + title: "Kas savaitę" + daily: + title: "Kasdien" + all_time: "Per visą laiką" + this_year: "Metai" + this_quarter: "Per ketvirtį" + this_month: "Per mėnesį" + this_week: "Per savaitę" + today: "Šandien" + other_periods: "skaityk TOP" + permission_types: + full: "Kurti / Atsakyti / Peržiūrėti" + create_post: "Atsakyti / Peržiūrėti" + readonly: "Peržiūrėti" + lightbox: + download: "atsisiųsti" + keyboard_shortcuts_help: + title: 'Klaviatūros trumpiniai' + jump_to: + title: 'Peršokti į' + home: 'g, h Pradinį' + latest: 'g, l Naujasi' + new: 'g, n Nauji' + unread: 'g, u Neperskaityti' + categories: 'g, c Kategorijos' + top: 'g, t Top' + bookmarks: 'g, b Išsaugoti' + profile: 'g, p Profilis' + messages: 'g, m Žinutės' + drafts: 'g, d Juodraščiai' + navigation: + title: 'Navigacija' + jump: '#Eiti į įršą#' + back: 'u Atgal' + actions: + title: 'Veiksmai' + badges: + title: Ženkleliai + badge_count: + one: "1 _enklelis" + few: "%{count}Ženkleliai" + many: "%{count} Ženklelių" + other: "%{count}Ženkleliai" + more_badges: + one: "+1 Daugiau" + few: "+%{count}Daugiau" + many: "+%{count}Daugiau" + other: "+%{count}Daugiau" + none: "(nieko)" + badge_grouping: + community: + name: Bendruomenė + trust_level: + name: Patikimumo lygis + other: + name: Kita + posting: + name: Publikuojama + tagging: + all_tags: "Visos žymos" + other_tags: "Kitos žymos" + selector_all_tags: "visos žymos" + selector_no_tags: "nėra žymų" + tags: "Žymos" + delete_tag: "Ištrinti žymą" + rename_tag: "Pervadinti žymą" + sort_by: "Rūšiuoti pagal:" + sort_by_count: "skaičių" + sort_by_name: "vardą" + filters: + without_category: "%{filter}%{tag} temos" + with_category: "%{filter}%{tag}temos, %{category}kategorijoje" + notifications: + watching: + title: "Stebiu" + watching_first_post: + title: "Stebiu pirmą įrašą" + tracking: + title: "Seku" + muted: + title: "Nutildyta" + groups: + title: "Žymos grupės" + new: "Nauja grupė" + tags_label: "Žymos šioje grupėje" + parent_tag_label: "Panašios žymos:" + parent_tag_placeholder: "Pasirinktinai" + new_name: "Nauja žymos grupė" + save: "Saugoti" + delete: "Pašalinti" + topics: + bottom: + latest: "Daugiau nėra jokių naujausių temų." + invite: + custom_message_placeholder: "Įveskite savo pasirinktinę žinutę" + custom_message_template_forum: "Labas, užsiregistruok ir tu!\nČia bus vienas geriausių forumų..." + admin_js: + type_to_filter: "įrašyk kažką dėl filtro..." + admin: + title: 'Forumo administratorius' + moderator: 'Moderatorius' + dashboard: + title: "Apžvalga" + last_updated: "Apžvalga paskutinį karta atnaujinta:" + version: "Versija" + up_to_date: "Jūs turite naujausią versiją!" + critical_available: "Yra kritinių atnaujinimų." + updates_available: "Yra atnaujinimų." + please_upgrade: "Prašome atnaujinti!" + no_check_performed: "Atnaujinimų patikrinimas neįvykdytas. Patikrinkite ar veikia sidekiq." + stale_data: "Artimiausiu metu atnaujinimų patikrinimas nebuvo įvykdytas. Patikrinkite ar veikia sidekiq." + version_check_pending: "Matomai jūs nesenai atsinaujinote. Nuostabu!" + installed_version: "Įrašyta" + latest_version: "Naujausia" + problems_found: "Rastos kelios problemos susijusios su Discourse instaliavimu: " + last_checked: "Paskutinį kartą tikrinta" + refresh_problems: "Atnaujinti" + no_problems: "Nerasta jokių problemų" + moderators: 'Moderatoriai:' + admins: 'Administratoriai:' + suspended: 'Sustabdyti:' + private_messages_short: "Msgs" + private_messages_title: "Žinutės" + mobile_title: "Mobili " + space_free: "{{size}} laisva" + uploads: "Įkėlimai" + backups: "Atsarginės kopijos" + lastest_backup: "Naujausi: %{date}" + traffic_short: "Srautas" + traffic: "Application web requests" + page_views: "Puslapio peržiūros" + page_views_short: "Puslapio peržiūros" + show_traffic_report: "Show Detailed Traffic Report" + community_health: Bendruomenės sveikata + moderators_activity: Moderatorių veikla + whats_new_in_discourse: "Kas aujo Discourse?" + activity_metrics: Aktyvumas + all_reports: "Visi pranešimai" + general_tab: "Bendrieji" + moderation_tab: "Moderavimas" + disabled: Uždrausta + reports: + today: "Šiandien" + yesterday: "Vakar" + all_time: "Per visą laiką" + 7_days_ago: "Prieš 7 dienas" + 30_days_ago: "Prieš 30 dienų" + all: "Visi" + view_table: "table" + refresh_report: "Refresh Report" + start_date: "Pražios data" + end_date: "End Date" + groups: "Visos grupės" + trending_search: + more: 'Paieškos įrašai' + commits: + latest_changes: "Paskutiniai pakeitimai:" + by: "nuo" + flags: + title: "Uždėti vėliavą" + active_posts: "Pažymėti įrašai" + old_posts: "Seni Pažymėti įrašai" + topics: "Pažymėtos temos" + moderation_history: "Moderavimo istorija" + agree: "Sutinka" + agree_title: "Patvirtink, kad vėliava yra teisinga ir tinkama" + agree_flag_hide_post: "Paslėpti įrašą" + agree_flag_restore_post: "Sutikti ir atkurti įrašą" + agree_flag_suspend: "Suspenduoti narį" + agree_flag_silence: "Nutildyti narį" + agree_flag_silence_title: "Sutikti su pranešimu ir nutildyti narį." + agree_flag: "Palikti įrašą" + ignore_flag: "Ignoruoti" + delete: "Ištrinti" + delete_title: "Ištrinti šį įrašą ant kurio uždėta vėliava." + delete_post_defer_flag_title: "Ištrinti įrašą. Jei tema turi tik vieną įrašą - išsitrins visa tema." + delete_post_agree_flag_title: "Delete post; if the first post, delete the topic" + delete_flag_modal_title: "Ištrinti ir..." + delete_spammer: "Ištrinti Vartotoją" + delete_spammer_title: "Pašalinti vartotoją ir visus įrašus bei temas susijusius su juo" + disagree_flag_unhide_post: "Nesutiku (atnaujinti įrašą)" + disagree_flag_unhide_post_title: "Pašalinti visas vėliavas iš įrašo ir padaryk jį matomą" + disagree_flag: "Nesutinka" + disagree_flag_title: "Pažymėk šią vėliavą, kaip neteisingą" + clear_topic_flags: "Baigti" + clear_topic_flags_title: "Tema yra ištirta, o problema išspresta. Paspasuk \"Viskas\", kad nuimtum vėliavą" + more: "(daugiau atsakymų...)" + suspend_user: "Suspenduoti narį" + suspend_user_title: "Suspenduoti narį už šį įrašą" + replies: + one: "[1 atsakymas]" + few: "[%{count}atsakymai]" + many: "[%{count}atsakymų]" + other: "[%{count}atsakymai]" + dispositions: + agreed: "sutiko" + disagreed: "nesutiko" + deferred: "ignoruojama" + flagged_by: "Žmonės, kurie uždėjo vėliavas" + resolved_by: "Išspręsta" + took_action: "Imtis Veiksmų" + system: "Sistema" + error: "Įvyko klaida" + reply_message: "Atsakyti" + topic_flagged: "Šiai temai buvo uždėta vėliava" + show_full: "rodyti pilną įrašą" + visit_topic: "Užeiti į tema prieš imantis veiksmų" + was_edited: "Įrašas buvo pakeistas po pirmos uždėtos vėliavos" + previous_flags_count: "Šiai temai buvo uždėta vėliava jau {{count}} kartus." + show_details: "Rodyti pranešimo detales" + details: "detalės" + flagged_topics: + topic: "Tema" + type: "Tipas" + users: "Nariai" + short_names: + spam: "šlamštas" + groups: + new: + title: "Nauja Grupė" + create: "Sukurti" + name: + too_short: "Grupės pavadinimas per trumpas" + too_long: "Grupės pavadinimas per ilgas" + checking: "Tikrinama grupės pavadinimo galimumas..." + available: "Grupės pavadinimas galimas" + not_available: "Grupės pavadinimas negalimas" + blank: "Grupės pavadinimas negali buti tuščias" + manage: + interaction: + email: Epaštas + incoming_email_placeholder: "įveskite elektoninio pašto adresą" + visibility: Matomumas + visibility_levels: + title: "Kas gali matyti šia grupę?" + public: "Visi" + members: "Grupės valdytojai, nariai ir administratoriai" + staff: "Grupės valdytojai ir moderatoriai" + owners: "Grupės valdytojai ir administratoriai" + membership: + automatic: Automatini + trust_level: Patikimumo lygis + trust_levels_none: "Nieko" + primary: "Pagrindinė Grupė" + no_primary: "(jokios pagrindinės grupės)" + title: "Grupės" + edit: "Redaguoti grupes" + refresh: "Atnaujinti" + about: "Čia galite redaguoti savo grupių narystę ir pavadinimus" + group_members: "Grupės nariai" + delete: "Ištrinti" + delete_confirm: "Ištrinti šią grupę?" + delete_failed: "Negalima ištrinti grupės. Jei tai yra automatinė grupė, jos negalima ištrinti." + delete_owner_confirm: "Ar nori pašalinti valdytojo privilegijas '%{username}'?" + add: "Pridėti" + custom: "Išskirtinės" + automatic: "Automatinės" + default_title: "Numatytoji antraštė" + group_owners: Valdytojai + add_owners: Pridėti valdytojus + api: + generate_master: "Generuoti pagrindinį API raktą" + none: "Šiuo metu nėra jokių aktyvių API raktų." + user: "Vartotojas" + title: "API" + key: "API raktas" + generate: "Generuoti" + regenerate: "Pergeneruoti" + revoke: "Pašalinti" + confirm_regen: "Ar tikrai norite pakeisti šį API raktą nauju?" + confirm_revoke: "Ar tikrai norite pašalinti šį raktą?" + info_html: "Jūsų API raktas leis jums kurti ir atnaujinti temas naudojant JSON užklausas." + all_users: "Visi vartotojai" + note_html: "Tai slapta funkcija, su ja gali kurti įrašus bet kokiu vardu." + web_hooks: + create: "Sukurti" + save: "Saugoti" + destroy: "Pašalinti" + description: "Aprašymas" + controls: "Valdymai" + go_back: "Atgal į sąrašą" + content_type: "Turinio tipas" + secret: "Slaptas" + active: "Aktyvus" + events: + event_id: "ID" + timestamp: "Sukurta" + completion: "Sukurimo laikas" + actions: "Veiksmai" + plugins: + title: "Plugins" + installed: "Installed Plugins" + name: "Vardas" + none_installed: "Neturi instaliavęs jokių plugins'ų" + version: "Versija" + enabled: "Galimas?" + is_enabled: "Taip" + not_enabled: "Ne" + change_settings: "Pakeisti nustatymus" + change_settings_short: "Nustatymai" + howto: "Kaip galiu instaliuoti plungin'us?" + backups: + title: "Atsarginės kopijos" + menu: + backups: "Atsarginės kopijos" + logs: "Įrašai" + none: "Nėra galimų atsarginių kopijų." + logs: + none: "Šiuo metu nėra jokių įrašų..." + columns: + filename: "Dokumento pavadinimas" + size: "Dydis" + upload: + label: "Įkelti" + title: "Įkelti atsarginę kopiją šiam atskiram atvejui" + uploading: "Įkeliama" + error: "Įvyko klaida įkeliant '{{filename}}': {{message}}" + operations: + is_running: "Šiuo metu jau yra vykdoma operacija..." + failed: "Įvyko klaida su {{operation}}. Prašome patikrinti logaritmus." + cancel: + label: "Atšaukti" + title: "Atšaukti dabartinę operaciją" + confirm: "Ar tikrai norite atšaukti dabartinę operaciją?" + backup: + label: "Kurti atsarginę kopiją" + title: "Sukurti atsarginę kopiją" + confirm: "Ar tikrai norite pradėti naują atsarginės kopijos darymą?" + download: + label: "Atsisiųsti" + destroy: + title: "Ištrinti atsarginę kopiją" + confirm: "Ar tikrai norite ištrinti šią atsarginę kopiją?" + restore: + is_disabled: "Atkurimas yra išjungtas svetainės nustatymuose." + label: "Atkurti" + title: "Atkurti atsarginę kopiją" + rollback: + label: "Atkurti senesnius nustatymus" + title: "Atkurti duomenų bazę iki ankstesnės busenos." + export_csv: + success: "Failų eksportavimas pradėtas. Kai procesas bus baigtas, gausite pranešimą per el. paštą." + failed: "Eksportas nepavyko. Įvyko klaida. Prašome patikrinti logaritmus." + button_text: "Eksportuoti" + button_title: + user: "Eksportuoti pilną vartotojų sąrašą CSV formatu" + staff_action: "Eksportuoti pilną komandos veiksmų sąrašą CSV formatu." + screened_email: "Eksportuoti pilną el. pašto adresų sąrašą CSV formatu." + screened_ip: "Eksportuoti pilną IP sąrašą CSV formatu." + screened_url: "Eksportuoti pilną URL sąrašą CSV formatu." + export_json: + button_text: "Eksportuoti" + invite: + button_text: "Siųsti pakvietimą" + button_title: "Siųsti pakvietimą" + customize: + title: "Pakeisti" + long_title: "Puslapio Keitimas" + preview: "peržiūra" + save: "Išsaugoti" + new: "Naujas" + new_style: "Naujas stilius" + import: "Importuoti" + delete: "Ištrinti" + color: "Spalva" + opacity: "Permatomumas" + copy: "Kopijuoti" + email_templates: + title: "El. laiškų Pavyzdžiai" + subject: "Tema" + multiple_subjects: "El. laiško pavyzdys priskirtas keletui subjektų" + body: "Tekstas" + none_selected: "Pasirink el. laiško pavyzdį, kad pradėtum redaguoti" + revert: "Atstatyti Pakeitimus" + revert_confirm: "Ar tikrai nori atstatyti pakeitimus?" + theme: + import_theme: "Importuoti temą" + title: "Temos" + create: "Sukurti" + create_type: "Tipas:" + create_name: "Pavadinimas:" + edit: "Redaguoti" + desktop: "Darbalaukis" + mobile: "Mobilus" + settings: "Nustatymai" + preview: "Peržiūrėti" + is_default: "Tema įgalinta pagal nutylėjimą" + color_scheme: "Spalvų schema" + theme_components: "Temos komponentai" + uploads: "Įkėlimai" + upload: "Įkelti" + edit_css_html: "Redaguoti CSS/HTML" + about_theme: "Apie temą" + license: "Licensija" + component_of: "Komponentas:" + update_to_latest: "Atnaujinti iki paskutinės" + check_for_updates: "Tikrinti atnaujinimus " + updating: "Atnaujinama..." + up_to_date: "Tema yra naujausia, psakutinis tikrinimas: " + add: "Pridėti" + theme_settings: "Temos nustatymai" + scss: + text: "CSS" + header: + text: "Viršus" + after_header: + text: "Po viršaus" + footer: + text: "Apačia" + title: "Įveskite HTML, kad rodyti puslapio apačioje" + embedded_scss: + text: "Įterptas CSS" + head_tag: + text: "" + body_tag: + text: "