From: Andy Allan Date: Wed, 7 Aug 2024 15:22:21 +0000 (+0100) Subject: Merge pull request #5019 from tomhughes/oauth2-cleanup X-Git-Tag: live~1127 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/70cb93a101638596ecae5782575ada2d4d08c8dd?hp=77ab4ef292e5261499efe6b8fee1a25c5719270d Merge pull request #5019 from tomhughes/oauth2-cleanup Add expiry for OAuth 2 grants and tokens --- diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 6fe5b2e57..3b18f7246 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -71,7 +71,7 @@ Metrics/ClassLength: # Offense count: 59 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/CyclomaticComplexity: - Max: 29 + Max: 31 # Offense count: 753 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. @@ -86,7 +86,7 @@ Metrics/ParameterLists: # Offense count: 56 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/PerceivedComplexity: - Max: 30 + Max: 32 # Offense count: 2394 # This cop supports safe autocorrection (--autocorrect). @@ -95,7 +95,7 @@ Minitest/EmptyLineBeforeAssertionMethods: # Offense count: 565 Minitest/MultipleAssertions: - Max: 54 + Max: 60 # Offense count: 1 # This cop supports unsafe autocorrection (--autocorrect-all). diff --git a/Gemfile.lock b/Gemfile.lock index 05ccd47d1..00984911c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -92,11 +92,11 @@ GEM ffi (~> 1.15) ffi-compiler (~> 1.0) ast (2.4.2) - autoprefixer-rails (10.4.16.0) + autoprefixer-rails (10.4.19.0) execjs (~> 2) aws-eventstream (1.3.0) - aws-partitions (1.957.0) - aws-sdk-core (3.201.2) + aws-partitions (1.962.0) + aws-sdk-core (3.201.3) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) @@ -104,11 +104,11 @@ GEM aws-sdk-kms (1.88.0) aws-sdk-core (~> 3, >= 3.201.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.156.0) + aws-sdk-s3 (1.157.0) aws-sdk-core (~> 3, >= 3.201.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) - aws-sigv4 (1.8.0) + aws-sigv4 (1.9.1) aws-eventstream (~> 1, >= 1.0.2) base64 (0.2.0) better_errors (2.10.1) @@ -125,7 +125,7 @@ GEM bigdecimal (3.1.8) binding_of_caller (1.0.1) debug_inspector (>= 1.2.0) - bootsnap (1.18.3) + bootsnap (1.18.4) msgpack (~> 1.2) bootstrap (5.3.3) autoprefixer-rails (>= 9.1.0) @@ -177,7 +177,7 @@ GEM delayed_job_active_record (4.1.8) activerecord (>= 3.0, < 8.0) delayed_job (>= 3.0, < 5) - docile (1.4.0) + docile (1.4.1) doorkeeper (5.7.1) railties (>= 5) doorkeeper-i18n (5.2.7) @@ -219,12 +219,12 @@ GEM dry-initializer (~> 3.0) dry-schema (>= 1.12, < 2) zeitwerk (~> 2.6) - erb_lint (0.5.0) + erb_lint (0.6.0) activesupport better_html (>= 2.0.1) parser (>= 2.7.1.4) rainbow - rubocop + rubocop (>= 1) smart_properties erubi (1.13.0) execjs (2.9.1) @@ -234,10 +234,10 @@ GEM factory_bot_rails (6.4.3) factory_bot (~> 6.4) railties (>= 5.0.0) - faraday (2.10.0) + faraday (2.10.1) faraday-net_http (>= 2.0, < 3.2) logger - faraday-net_http (3.1.0) + faraday-net_http (3.1.1) net-http ffi (1.17.0) ffi-compiler (1.3.2) @@ -253,8 +253,8 @@ GEM ffi (>= 1.0.0) globalid (1.2.1) activesupport (>= 6.1) - google-protobuf (3.25.3) - hashdiff (1.1.0) + google-protobuf (3.25.4) + hashdiff (1.1.1) hashie (5.0.0) highline (3.1.0) reline @@ -284,7 +284,7 @@ GEM image_optim (~> 0.24) railties sprockets - image_processing (1.12.2) + image_processing (1.13.0) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) image_size (3.4.0) @@ -352,7 +352,7 @@ GEM net-smtp (0.5.0) net-protocol nio4r (2.7.3) - nokogiri (1.16.6) + nokogiri (1.16.7) mini_portile2 (~> 2.8.2) racc (~> 1.4) oauth (0.4.7) @@ -407,7 +407,7 @@ GEM parser (3.3.4.0) ast (~> 2.4.1) racc - pg (1.5.6) + pg (1.5.7) popper_js (2.11.8) progress (3.6.0) psych (5.1.2) @@ -416,7 +416,7 @@ GEM puma (5.6.8) nio4r (~> 2.0) quad_tile (1.0.1) - racc (1.8.0) + racc (1.8.1) rack (2.2.9) rack-cors (2.0.2) rack (>= 2.0.0) @@ -485,14 +485,14 @@ GEM io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) - rexml (3.3.2) + rexml (3.3.4) strscan rinku (2.0.6) rotp (6.3.0) rouge (4.3.0) rtlcss (0.2.1) mini_racer (>= 0.6.3) - rubocop (1.65.0) + rubocop (1.65.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -503,7 +503,7 @@ GEM rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.31.3) + rubocop-ast (1.32.0) parser (>= 3.3.1.0) rubocop-capybara (2.21.0) rubocop (~> 1.41) @@ -528,7 +528,7 @@ GEM ffi (~> 1.12) logger rubyzip (2.3.2) - sanitize (6.1.1) + sanitize (6.1.2) crass (~> 1.0.2) nokogiri (>= 1.12.0) sass-embedded (1.64.2) @@ -558,7 +558,7 @@ GEM sprockets-exporters_pack (0.1.2) brotli (>= 0.2.0) sprockets (>= 4.0.0.beta3) - sprockets-rails (3.5.1) + sprockets-rails (3.5.2) actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) @@ -597,7 +597,7 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.16) + zeitwerk (2.6.17) PLATFORMS ruby diff --git a/app/abilities/api_capability.rb b/app/abilities/api_capability.rb index f27dd2e63..44e676345 100644 --- a/app/abilities/api_capability.rb +++ b/app/abilities/api_capability.rb @@ -19,6 +19,8 @@ class ApiCapability can [:gpx_files], User if scope?(token, :read_gpx) can [:index, :show], UserPreference if scope?(token, :read_prefs) can [:update, :update_all, :destroy], UserPreference if scope?(token, :write_prefs) + can [:inbox, :outbox, :show, :update, :destroy], Message if scope?(token, :consume_messages) + can [:create], Message if scope?(token, :send_messages) if user.terms_agreed? can [:create, :update, :upload, :close, :subscribe, :unsubscribe], Changeset if scope?(token, :write_api) diff --git a/app/assets/javascripts/richtext.js b/app/assets/javascripts/richtext.js index 3036f169b..259b914de 100644 --- a/app/assets/javascripts/richtext.js +++ b/app/assets/javascripts/richtext.js @@ -1,7 +1,4 @@ $(document).ready(function () { - /* Hide the preview panes */ - $(".richtext_preview").hide(); - /* * When the text in an edit pane is changed, clear the contents of * the associated preview pne so that it will be regenerated when @@ -11,34 +8,10 @@ $(document).ready(function () { $(this).parents(".richtext_container").find(".richtext_preview").empty(); }); - /* Disable all the edit buttons */ - $(".richtext_doedit").prop("disabled", true); - - /* Enable the preview buttons */ - $(".richtext_dopreview").prop("disabled", false); - - /* - * Install a click handler to switch to edit mode when the - * edit button is pressed. - */ - $(".richtext_doedit").click(function (event) { - var editor = $(this).parents(".richtext_container").find("textarea"); - var preview = $(this).parents(".richtext_container").find(".richtext_preview"); - - preview.hide(); - editor.show(); - - $(this).siblings(".richtext_dopreview").prop("disabled", false); - $(this).prop("disabled", true); - - event.preventDefault(); - }); - /* - * Install a click handler to switch to preview mode when the - * preview button is pressed. + * Install a handler to switch to preview mode */ - $(".richtext_dopreview").click(function (event) { + $(".richtext_dopreview").on("show.bs.tab", function () { var editor = $(this).parents(".richtext_container").find("textarea"); var preview = $(this).parents(".richtext_container").find(".richtext_preview"); var minHeight = editor.outerHeight() - preview.outerHeight() + preview.height(); @@ -54,13 +27,6 @@ $(document).ready(function () { }); } - editor.hide(); preview.css("min-height", minHeight + "px"); - preview.show(); - - $(this).siblings(".richtext_doedit").prop("disabled", false); - $(this).prop("disabled", true); - - event.preventDefault(); }); }); diff --git a/app/controllers/api/messages_controller.rb b/app/controllers/api/messages_controller.rb new file mode 100644 index 000000000..074f87398 --- /dev/null +++ b/app/controllers/api/messages_controller.rb @@ -0,0 +1,149 @@ +# The MessagesController is the RESTful interface to Message objects + +module Api + class MessagesController < ApiController + before_action :authorize + + before_action :check_api_writable, :only => [:create, :update, :destroy] + before_action :check_api_readable, :except => [:create, :update, :destroy] + + authorize_resource + + around_action :api_call_handle_error, :api_call_timeout + + before_action :set_request_formats + + def inbox + @skip_body = true + @messages = Message.includes(:sender, :recipient).where(:to_user_id => current_user.id) + + show_messages + end + + def outbox + @skip_body = true + @messages = Message.includes(:sender, :recipient).where(:from_user_id => current_user.id) + + show_messages + end + + # Dump the details on a message given in params[:id] + def show + @message = Message.includes(:sender, :recipient).find(params[:id]) + + raise OSM::APIAccessDenied if current_user.id != @message.from_user_id && current_user.id != @message.to_user_id + + # Render the result + respond_to do |format| + format.xml + format.json + end + end + + # Create a new message from current user + def create + # Check the arguments are sane + raise OSM::APIBadUserInput, "No title was given" if params[:title].blank? + raise OSM::APIBadUserInput, "No body was given" if params[:body].blank? + + # Extract the arguments + if params[:recipient_id] + recipient_id = params[:recipient_id].to_i + recipient = User.find(recipient_id) + elsif params[:recipient] + recipient_display_name = params[:recipient] + recipient = User.find_by(:display_name => recipient_display_name) + else + raise OSM::APIBadUserInput, "No recipient was given" + end + + raise OSM::APIRateLimitExceeded if current_user.sent_messages.where(:sent_on => Time.now.utc - 1.hour..).count >= current_user.max_messages_per_hour + + @message = Message.new(:sender => current_user, + :recipient => recipient, + :sent_on => Time.now.utc, + :title => params[:title], + :body => params[:body], + :body_format => "markdown") + @message.save! + + UserMailer.message_notification(@message).deliver_later if @message.notify_recipient? + + # Return a copy of the new message + respond_to do |format| + format.xml { render :action => :show } + format.json { render :action => :show } + end + end + + # Update read status of a message + def update + @message = Message.find(params[:id]) + read_status_idx = %w[true false].index params[:read_status] + + raise OSM::APIBadUserInput, "Invalid value of `read_status` was given" if read_status_idx.nil? + raise OSM::APIAccessDenied unless current_user.id == @message.to_user_id + + @message.message_read = read_status_idx.zero? + @message.save! + + # Return a copy of the message + respond_to do |format| + format.xml { render :action => :show } + format.json { render :action => :show } + end + end + + # Delete message by marking it as not visible for the current user + def destroy + @message = Message.find(params[:id]) + if current_user.id == @message.from_user_id + @message.from_user_visible = false + elsif current_user.id == @message.to_user_id + @message.to_user_visible = false + else + raise OSM::APIAccessDenied + end + + @message.save! + + # Return a copy of the message + respond_to do |format| + format.xml { render :action => :show } + format.json { render :action => :show } + end + end + + private + + def show_messages + @messages = @messages.where(:muted => false) + if params[:order].nil? || params[:order] == "newest" + @messages = @messages.where(:id => ..params[:from_id]) unless params[:from_id].nil? + @messages = @messages.order(:id => :desc) + elsif params[:order] == "oldest" + @messages = @messages.where(:id => params[:from_id]..) unless params[:from_id].nil? + @messages = @messages.order(:id => :asc) + else + raise OSM::APIBadUserInput, "Invalid order specified" + end + + limit = params[:limit] + if !limit + limit = Settings.default_message_query_limit + elsif !limit.to_i.positive? || limit.to_i > Settings.max_message_query_limit + raise OSM::APIBadUserInput, "Messages limit must be between 1 and #{Settings.max_message_query_limit}" + else + limit = limit.to_i + end + + @messages = @messages.limit(limit) + + # Render the result + respond_to do |format| + format.xml + format.json + end + end + end +end diff --git a/app/controllers/diary_entries_controller.rb b/app/controllers/diary_entries_controller.rb index eaf6ddf9c..9962c7efd 100644 --- a/app/controllers/diary_entries_controller.rb +++ b/app/controllers/diary_entries_controller.rb @@ -69,6 +69,7 @@ class DiaryEntriesController < ApplicationController if @entry @title = t ".title", :user => params[:display_name], :title => @entry.title @og_image = @entry.body.image + @og_image_alt = @entry.body.image_alt @comments = can?(:unhide, DiaryComment) ? @entry.comments : @entry.visible_comments else @title = t "diary_entries.no_such_entry.title", :id => params[:id] diff --git a/app/controllers/site_controller.rb b/app/controllers/site_controller.rb index 5d63e79fd..58f0a11c9 100644 --- a/app/controllers/site_controller.rb +++ b/app/controllers/site_controller.rb @@ -138,7 +138,12 @@ class SiteController < ApplicationController end def preview - render :html => RichText.new(params[:type], params[:text]).to_html + if params[:text].blank? + flash.now[:warning] = t("layouts.nothing_to_preview") + render :partial => "layouts/flash" + else + render :html => RichText.new(params[:type], params[:text]).to_html + end end def id diff --git a/app/controllers/user_blocks_controller.rb b/app/controllers/user_blocks_controller.rb index 3ab217a60..664ac5681 100644 --- a/app/controllers/user_blocks_controller.rb +++ b/app/controllers/user_blocks_controller.rb @@ -63,8 +63,9 @@ class UserBlocksController < ApplicationController def update if @valid_params - if @user_block.creator != current_user - flash[:error] = t(".only_creator_can_edit") + if current_user != @user_block.creator && + current_user != @user_block.revoker + flash[:error] = t(@user_block.revoker ? ".only_creator_or_revoker_can_edit" : ".only_creator_can_edit") redirect_to :action => "edit" elsif @user_block.update( :ends_at => Time.now.utc + @block_period.hours, diff --git a/app/helpers/open_graph_helper.rb b/app/helpers/open_graph_helper.rb index a41831ca6..ad24c73b2 100644 --- a/app/helpers/open_graph_helper.rb +++ b/app/helpers/open_graph_helper.rb @@ -1,15 +1,16 @@ module OpenGraphHelper require "addressable/uri" - def opengraph_tags(title = nil, og_image = nil) + def opengraph_tags(title = nil, og_image = nil, og_image_alt = nil) tags = { "og:site_name" => t("layouts.project_name.title"), "og:title" => title || t("layouts.project_name.title"), "og:type" => "website", - "og:image" => og_image_url(og_image), "og:url" => url_for(:only_path => false), "og:description" => t("layouts.intro_text") - } + }.merge( + opengraph_image_properties(og_image, og_image_alt) + ) safe_join(tags.map do |property, content| tag.meta(:property => property, :content => content) @@ -18,12 +19,20 @@ module OpenGraphHelper private - def og_image_url(og_image) + def opengraph_image_properties(og_image, og_image_alt) begin - return Addressable::URI.join(root_url, og_image).normalize if og_image + if og_image + properties = {} + properties["og:image"] = Addressable::URI.join(root_url, og_image).normalize + properties["og:image:alt"] = og_image_alt if og_image_alt + return properties + end rescue Addressable::URI::InvalidURIError # return default image end - image_url("osm_logo_256.png") + { + "og:image" => image_url("osm_logo_256.png"), + "og:image:alt" => t("layouts.logo.alt_text") + } end end diff --git a/app/helpers/trace_helper.rb b/app/helpers/trace_helper.rb index aec1146cb..fbbeb3dff 100644 --- a/app/helpers/trace_helper.rb +++ b/app/helpers/trace_helper.rb @@ -2,4 +2,20 @@ module TraceHelper def link_to_tag(tag) link_to(tag, :tag => tag, :page => nil) end + + def trace_icon(trace, options = {}) + options[:class] ||= "trace_image" + options[:alt] ||= "" + + image_tag trace_icon_path(trace.user, trace), + options.merge(:size => 50) + end + + def trace_picture(trace, options = {}) + options[:class] ||= "trace_image" + options[:alt] ||= "" + + image_tag trace_picture_path(trace.user, trace), + options.merge(:size => 250) + end end diff --git a/app/views/api/changesets/index.json.jbuilder b/app/views/api/changesets/index.json.jbuilder index f52d69865..ce094fa34 100644 --- a/app/views/api/changesets/index.json.jbuilder +++ b/app/views/api/changesets/index.json.jbuilder @@ -1,5 +1,5 @@ json.partial! "api/root_attributes" -json.changesets(@changesets) do |changeset| - json.partial! changeset +json.changesets do + json.array! @changesets, :partial => "changeset", :as => :changeset end diff --git a/app/views/api/changesets/index.xml.builder b/app/views/api/changesets/index.xml.builder index 5ff7e2620..286f50c35 100644 --- a/app/views/api/changesets/index.xml.builder +++ b/app/views/api/changesets/index.xml.builder @@ -1,7 +1,4 @@ xml.instruct! :xml, :version => "1.0" - xml.osm(OSM::API.new.xml_root_attributes) do |osm| - @changesets.each do |changeset| - osm << render(changeset) - end + osm << (render(@changesets) || "") end diff --git a/app/views/api/messages/_message.json.jbuilder b/app/views/api/messages/_message.json.jbuilder new file mode 100644 index 000000000..a04295d31 --- /dev/null +++ b/app/views/api/messages/_message.json.jbuilder @@ -0,0 +1,17 @@ +json.id message.id +json.from_user_id message.from_user_id +json.from_display_name message.sender.display_name +json.to_user_id message.to_user_id +json.to_display_name message.recipient.display_name +json.title message.title +json.sent_on message.sent_on.xmlschema + +if current_user.id == message.from_user_id + json.deleted !message.from_user_visible +elsif current_user.id == message.to_user_id + json.message_read message.message_read + json.deleted !message.to_user_visible +end + +json.body_format message.body_format +json.body message.body unless @skip_body diff --git a/app/views/api/messages/_message.xml.builder b/app/views/api/messages/_message.xml.builder new file mode 100644 index 000000000..64ac9e3bc --- /dev/null +++ b/app/views/api/messages/_message.xml.builder @@ -0,0 +1,21 @@ +attrs = { + "id" => message.id, + "from_user_id" => message.from_user_id, + "from_display_name" => message.sender.display_name, + "to_user_id" => message.to_user_id, + "to_display_name" => message.recipient.display_name, + "sent_on" => message.sent_on.xmlschema, + "body_format" => message.body_format +} + +if current_user.id == message.from_user_id + attrs["deleted"] = !message.from_user_visible +elsif current_user.id == message.to_user_id + attrs["message_read"] = message.message_read + attrs["deleted"] = !message.to_user_visible +end + +xml.message(attrs) do |nd| + nd.title(message.title) + nd.body(message.body) unless @skip_body +end diff --git a/app/views/api/messages/inbox.json.jbuilder b/app/views/api/messages/inbox.json.jbuilder new file mode 100644 index 000000000..122a82495 --- /dev/null +++ b/app/views/api/messages/inbox.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.messages do + json.array! @messages, :partial => "message", :as => :message +end diff --git a/app/views/api/messages/inbox.xml.builder b/app/views/api/messages/inbox.xml.builder new file mode 100644 index 000000000..0ef9003a9 --- /dev/null +++ b/app/views/api/messages/inbox.xml.builder @@ -0,0 +1,7 @@ +xml.instruct! + +xml.osm(OSM::API.new.xml_root_attributes) do |osm| + xml.tag! "messages" do + osm << (render(@messages) || "") + end +end diff --git a/app/views/api/messages/outbox.json.jbuilder b/app/views/api/messages/outbox.json.jbuilder new file mode 100644 index 000000000..122a82495 --- /dev/null +++ b/app/views/api/messages/outbox.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.messages do + json.array! @messages, :partial => "message", :as => :message +end diff --git a/app/views/api/messages/outbox.xml.builder b/app/views/api/messages/outbox.xml.builder new file mode 100644 index 000000000..440e3429b --- /dev/null +++ b/app/views/api/messages/outbox.xml.builder @@ -0,0 +1,5 @@ +xml.instruct! + +xml.osm(OSM::API.new.xml_root_attributes) do |osm| + osm << (render(@messages) || "") +end diff --git a/app/views/api/messages/show.json.jbuilder b/app/views/api/messages/show.json.jbuilder new file mode 100644 index 000000000..d8f24e958 --- /dev/null +++ b/app/views/api/messages/show.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.message do + json.partial! @message +end diff --git a/app/views/api/messages/show.xml.builder b/app/views/api/messages/show.xml.builder new file mode 100644 index 000000000..008d59249 --- /dev/null +++ b/app/views/api/messages/show.xml.builder @@ -0,0 +1,5 @@ +xml.instruct! :xml, :version => "1.0" + +xml.osm(OSM::API.new.xml_root_attributes) do |osm| + osm << render(@message) +end diff --git a/app/views/api/notes/index.json.jbuilder b/app/views/api/notes/index.json.jbuilder index 7909391f5..5660a8ad5 100644 --- a/app/views/api/notes/index.json.jbuilder +++ b/app/views/api/notes/index.json.jbuilder @@ -1,5 +1,5 @@ json.type "FeatureCollection" -json.features(@notes) do |note| - json.partial! note +json.features do + json.array! @notes, :partial => "note", :as => :note end diff --git a/app/views/api/users/index.json.jbuilder b/app/views/api/users/index.json.jbuilder index 1ad07d47c..d2dbd4d4f 100644 --- a/app/views/api/users/index.json.jbuilder +++ b/app/views/api/users/index.json.jbuilder @@ -1,5 +1,5 @@ json.partial! "api/root_attributes" -json.users(@users) do |user| - json.partial! user +json.users do + json.array! @users, :partial => "user", :as => :user end diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb index cb48d834e..e96564b82 100644 --- a/app/views/layouts/_header.html.erb +++ b/app/views/layouts/_header.html.erb @@ -82,7 +82,7 @@ <% if current_user && current_user.id %>
<%= render :partial => "shared/#{type}_help" %> - <%= submit_tag t(".edit"), :id => "#{id}_doedit", :class => "richtext_doedit btn btn-primary", :disabled => true %> - <%= submit_tag t(".preview"), :id => "#{id}_dopreview", :class => "richtext_dopreview btn btn-primary" %>
diff --git a/app/views/traces/_trace.html.erb b/app/views/traces/_trace.html.erb index ba503f730..f60eea7f1 100644 --- a/app/views/traces/_trace.html.erb +++ b/app/views/traces/_trace.html.erb @@ -2,7 +2,7 @@ <% if Settings.status != "gpx_offline" %> <% if trace.inserted %> - <%= link_to image_tag(trace_icon_path(trace.user, trace), :alt => "", :class => "trace_image"), + <%= link_to trace_icon(trace), show_trace_path(trace.user, trace), :class => "d-inline-block" %> <% else %> diff --git a/app/views/traces/edit.html.erb b/app/views/traces/edit.html.erb index 2059178cf..1c440adf2 100644 --- a/app/views/traces/edit.html.erb +++ b/app/views/traces/edit.html.erb @@ -2,7 +2,7 @@

<%= t ".heading", :name => @trace.name %>

<% end %> -<%= image_tag trace_picture_path(@trace.user, @trace), :class => "trace_image" %> +<%= trace_picture(@trace) %> <%= bootstrap_form_for @trace do |f| %> <%= f.text_field :name, :disabled => true %> diff --git a/app/views/traces/show.html.erb b/app/views/traces/show.html.erb index 51b21f982..63adf1572 100644 --- a/app/views/traces/show.html.erb +++ b/app/views/traces/show.html.erb @@ -4,7 +4,7 @@ <% if Settings.status != "gpx_offline" %> <% if @trace.inserted %> - <%= image_tag trace_picture_path(@trace.user, @trace), :class => "trace_image" %> + <%= trace_picture(@trace) %> <% else %> <%= t ".pending" %> <% end %> diff --git a/app/views/user_blocks/_block.html.erb b/app/views/user_blocks/_block.html.erb index 461dc7a8d..a18d1dbdb 100644 --- a/app/views/user_blocks/_block.html.erb +++ b/app/views/user_blocks/_block.html.erb @@ -15,7 +15,8 @@ <% end %> <%= link_to t(".show"), block %> - <% if current_user and current_user.id == block.creator_id %><%= link_to t(".edit"), edit_user_block_path(block) %><% end %> + <% if current_user && (current_user.id == block.creator_id || + current_user.id == block.revoker_id) %><%= link_to t(".edit"), edit_user_block_path(block) %><% end %> <% if show_revoke_link %> <% if block.active? %><%= link_to t(".revoke"), revoke_user_block_path(block) %><% end %> <% end %> diff --git a/app/views/user_blocks/show.html.erb b/app/views/user_blocks/show.html.erb index 619cd6c3f..c36c043cf 100644 --- a/app/views/user_blocks/show.html.erb +++ b/app/views/user_blocks/show.html.erb @@ -26,9 +26,12 @@
<%= @user_block.reason.to_html %>
-<% if current_user&.id == @user_block.creator_id || can?(:revoke, UserBlock) && @user_block.active? %> +<% if current_user && (current_user.id == @user_block.creator_id || + current_user.id == @user_block.revoker_id) || + can?(:revoke, UserBlock) && @user_block.active? %>
- <% if current_user&.id == @user_block.creator_id %> + <% if current_user && (current_user.id == @user_block.creator_id || + current_user.id == @user_block.revoker_id) %> <%= link_to t(".edit"), edit_user_block_path(@user_block), :class => "btn btn-outline-primary" %> <% end %> <% if can?(:revoke, UserBlock) && @user_block.active? %> diff --git a/app/views/user_mailer/_gpx_description.text.erb b/app/views/user_mailer/_gpx_description.text.erb new file mode 100644 index 000000000..6f7a97844 --- /dev/null +++ b/app/views/user_mailer/_gpx_description.text.erb @@ -0,0 +1,8 @@ +<% trace_name = @trace_name %> +<% trace_description = @trace_description %> +<% if @trace_tags.length > 0 %> + <% tags = @trace_tags.map { |trace_tag| trace_tag.tag }.join(", ") %> + <%= t ".description_with_tags", :trace_name => trace_name, :trace_description => trace_description, :tags => tags %> +<% else %> + <%= t ".description_with_no_tags", :trace_name => trace_name, :trace_description => trace_description %> +<% end %> diff --git a/app/views/user_mailer/gpx_failure.text.erb b/app/views/user_mailer/gpx_failure.text.erb new file mode 100644 index 000000000..9544c74a9 --- /dev/null +++ b/app/views/user_mailer/gpx_failure.text.erb @@ -0,0 +1,10 @@ +<%= t ".hi", :to_user => @to_user %> + +<%= render :partial => "gpx_description" %> +<%= t ".failed_to_import" %> + +== +<%= @error %> +== + +<%= t ".more_info", :url => t(".import_failures_url") %> diff --git a/app/views/user_mailer/gpx_success.text.erb b/app/views/user_mailer/gpx_success.text.erb new file mode 100644 index 000000000..aee3a0f11 --- /dev/null +++ b/app/views/user_mailer/gpx_success.text.erb @@ -0,0 +1,8 @@ +<%= t ".hi", :to_user => @to_user %> + +<%= render :partial => "gpx_description" %> +<%= t(".loaded", :trace_points => @trace_points, :count => @possible_points) %> + +<%= t ".trace_location", :trace_url => @trace_url %> + +<%= t ".all_your_traces", :url => @my_traces_url %> diff --git a/config/locales/aln.yml b/config/locales/aln.yml index a924af237..d92818493 100644 --- a/config/locales/aln.yml +++ b/config/locales/aln.yml @@ -1173,7 +1173,6 @@ aln: show: Shiko këtë bllok back: Shiko të gjitha blloqet e filter: - block_expired: Blloku ka skaduar dhe nuk mund të redaktohen. block_period: Periudha e bllokuar duhet të jetë një nga vlerat selectable në drop-down list. create: diff --git a/config/locales/ar.yml b/config/locales/ar.yml index d8cc0a6f5..3fc7c8e6b 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -44,6 +44,7 @@ # Author: Zpizza # Author: أَحمد # Author: بدارين +# Author: بهتين شوكت # Author: ترجمان05 # Author: حبيشان # Author: ديفيد @@ -1663,18 +1664,28 @@ ar: befriend_them: "\uFEFFيمكنك أيضًا إضافتهم كصديق على %{befriendurl}." befriend_them_html: يمكنك أيضًا إضافتهم كصديق على %{befriendurl}. gpx_description: + description_with_tags: 'ويبدو ذالك ملف GPX الخاص بك هو %{trace_name} مع الوصف + %{trace_description} والعلامات التالية: %{tags}' description_with_tags_html: 'يبدو أن ملف GPX الخاص بك %{trace_name} مع الوصف %{trace_description} والعلامات التالية: %{tags}' + description_with_no_tags: يبدو أن ملف GPX الخاص بك %{trace_name} ومع ذالك الوصف + %{trace_description} وبدون وسوم description_with_no_tags_html: يبدو أن ملف GPX الخاص بك %{trace_name} مع الوصف %{trace_description} وبدون وسوم gpx_failure: hi: مرحبًا %{to_user}، failed_to_import: 'فشل الاستيراد، الخطأ هو:' + more_info: أكثر معلومة عن جي بي اكس يستورد الفشل و كيف ل يتجنب هم يستطيع يكون + وجد في%{url}. more_info_html: يمكن العثور على مزيد من المعلومات حول إخفاقات استيراد GPX وكيفية تجنبها على %{url}. subject: '[خريطة الشارع المفتوحة] فشل استيراد جي بي إكس' gpx_success: hi: مرحبًا %{to_user}، + trace_location: لك يتعقب يكون ذالك متاح في %{trace_url} + all_your_traces: |- + ان الجميع لك بنجاح اترفع جي بي اكس آثار وهو موجود في + %{url} subject: '[خريطة الشارع المفتوحة] نجاح استيراد جي بي إكس' signup_confirm: subject: '[خريطة الشارع المفتوحة] مرحبا بك في خريطة الشارع المفتوحة' @@ -2618,13 +2629,14 @@ ar: show: اعرض هذه العرقلة back: اعرض كل العرقلات filter: - block_expired: العرقلة قد انتهت ولا يمكن تعديلها. block_period: فترة العرقلة يجب أن تكون واحدة من القيم الاختيارية في القائمة المنسدلة. create: flash: أُنشىء عرقلة على المستخدم %{name}. update: only_creator_can_edit: فقط الوسيط الذي قام بإنشاء هذه العرقلة يمكنه تعديلها. + only_creator_or_revoker_can_edit: لاينفع تعديل هذا الحظر إلا من المشرفين الذين + العملوا هذا الحظر أو إلغائه. success: تم تحديث العرقلة. index: title: عرقلات المستخدم diff --git a/config/locales/arz.yml b/config/locales/arz.yml index 762f819c5..30cd03118 100644 --- a/config/locales/arz.yml +++ b/config/locales/arz.yml @@ -989,7 +989,6 @@ arz: show: اعرض هذه العرقلة back: اعرض كل العرقلات filter: - block_expired: العرقله قد انتهت ولا يمكن تعديلها. block_period: فتره العرقله يجب أن تكون واحده من القيم الاختياريه فى القائمه المنسدله. create: diff --git a/config/locales/ast.yml b/config/locales/ast.yml index 1a8715510..b5b930b7d 100644 --- a/config/locales/ast.yml +++ b/config/locales/ast.yml @@ -2070,7 +2070,6 @@ ast: show: Ver esti bloquéu back: Ver tolos bloqueos filter: - block_expired: El bloquéu yá caducó y nun puede editase. block_period: El periodu de bloquéu tien de ser un de los valores presentes na llista estenderexable. create: diff --git a/config/locales/be-Tarask.yml b/config/locales/be-Tarask.yml index 87af26366..d2b1c812c 100644 --- a/config/locales/be-Tarask.yml +++ b/config/locales/be-Tarask.yml @@ -1458,7 +1458,6 @@ be-Tarask: show: Паказаць гэтае блякаваньне back: Паказаць усе блякаваньні filter: - block_expired: Блякаваньне ўжо скончылася і ня можа рэдагавацца. block_period: Час блякаваньня павінен быць выбраны са значэньняў з разгортваемага сьпісу. create: diff --git a/config/locales/be.yml b/config/locales/be.yml index 5bf21b9c7..8ed552833 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -699,6 +699,8 @@ be: comment: Каментар newer_comments: Навейшыя каментары older_comments: Старэйшыя каментары + new: + heading: Дадаць каментар да абмеркавання наступнага запісу ў дзённіку? doorkeeper: errors: messages: @@ -940,6 +942,7 @@ be: college: Будынак каледжа commercial: Камерцыйны будынак construction: Будынак будуецца + cowshed: Кароўнік detached: Хата dormitory: Інтэрнат duplex: Падзеленая хата @@ -969,6 +972,7 @@ be: shed: Адрына stable: Стайня static_caravan: Мабільны дом + sty: Свінарнік temple: Храм terrace: Тэраса train_station: Чыгуначны вакзал @@ -2027,7 +2031,7 @@ be: lost password link: Згубілі пароль? login_button: Увайсці register now: Зарэгістравацца зараз - with external: або ўвайдзіце ў сістэму з дапамогай трэцяй асобы + with external: або ўвайдзіце ў сістэму з дапамогай пабочнага сэрвісу or: або auth failure: Прабачце, немагчыма увайсці з такім адрасам і паролем. destroy: @@ -2089,6 +2093,15 @@ be: open_data_open_data: адкрытыя даныя open_data_copyright_license: Аўтарскія правы і ліцэнзія legal_title: Прававыя пытанні + legal_1_1_openstreetmap_foundation: Фонд OpenStreetMap + legal_1_1_terms_of_use: Умовы карыстання + legal_1_1_privacy_policy: Палітыка прыватнасці + legal_2_1_html: Калі ласка, %{contact_the_osmf_link}, калі ў вас ёсць пытанні + адносна ліцэнзавання, аўтарскіх правоў або іншых юрыдычных пытаннях. + legal_2_1_contact_the_osmf: звяжыцеся з Фондам OSM + legal_2_2_html: OpenStreetMap, лагатып у відзе павелічальнага шкла і State of + the Map з'яўляюцца %{registered_trademarks_link}. + legal_2_2_registered_trademarks: зарэгістраванымі таварнымі знакамі Фонду OSM partners_title: Партнёры copyright: title: Аўтарскія правы і ліцэнзія @@ -2105,6 +2118,16 @@ be: native_link: беларуская версія mapping_link: пачаць маляваць карту legal_babble: + introduction_1_osm_foundation: Фонд OpenStreetMap + introduction_2_html: Вы можаце капіраваць, распаўсюджваць, перадаваць і змяняць + нашыя даныя да той пары пакуль вы спасылаецеся на OpenStreetMap і яе ўдзельнікаў. + Калі вы змяняеце ці выкарыстоўваеце нашыя даныя, то можаце распаўсюджваць + вынікі толькі на ўмовах такой жа ліцэнзіі. Поўны %{legal_code_link} растлумачыць + вашыя правы і абавязкі. + introduction_2_legal_code: тэкст ліцэнзіі + introduction_3_html: Наша дакументацыя прадастаўляецца на ўмовах ліцэнзіі + %{creative_commons_link} (CC BY-SA 2.0). + introduction_3_creative_commons: Creative Commons Attribution-ShareAlike 2.0 credit_title_html: Як спасылацца на OpenStreetMap credit_1_html: 'Там, дзе вы выкарыстоўваеце даныя OpenStreetMap, вы павінны выканаць наступныя дзве рэчы:' @@ -2116,6 +2139,25 @@ be: contributors_intro_html: 'Нашымі ўдзельнікамі з''яўляюцца тысячы людзей. Мы таксама ўключаем дадзеныя ад нацыянальных картаграфічных агенцтваў, якія распаўсюджваюцца на ўмовах адкрытых ліцэнзій, сярод іх:' + contributors_at_austria: |2- + Пераключыць змест + + Аўстрыя + contributors_au_australia: |2- + Пераключыць змест + + Аўстралія + contributors_ca_canada: Канада + contributors_cz_czechia: Чэхія + contributors_fi_finland: Фінляндыя + contributors_fr_france: Францыя + contributors_hr_croatia: Харватыя + contributors_nl_netherlands: Нідэрланды + contributors_nz_new_zealand: Новая Зеландыя + contributors_rs_serbia: Сербія + contributors_si_slovenia: Славенія + contributors_es_spain: Іспанія + contributors_za_south_africa: Паўднёвая Афрыка contributors_footer_2_html: |- Уключэнне дадзеных у OpenStreetMap не азначае, што пастаўшчыкі пачатковых дадзеных якім-небудзь чынам падтрымліваюць OpenStreetMap, прадстаўляюць гарантыі, ці @@ -2243,6 +2285,8 @@ be: rail: Чыгунка train: Цягнік subway: Метро + ferry: Паром + tram: Трамвай trolleybus: Тралейбус bus: Аўтобус cable_car: Канатная дарога @@ -2251,8 +2295,11 @@ be: taxiway: рулёжная дарожка apron: Перон аэрапорта admin: Адміністрацыйная мяжа + capital: Сталіца + city: Горад forest: Лес wood: пушча + sand: Пясок golf: Поле для гольфа park: Парк common: Агульныя @@ -2274,15 +2321,17 @@ be: military: Ваенная зона school: Школа university: Універсітэт + hospital: Бальніца building: Значны будынак station: Чыгуначны вакзал summit: Вяршыня - peak: пік + peak: Пік tunnel: Тунэль (пункцірам) bridge: Мост (суцэльная лінія) private: Прыватны доступ destination: Мэтавы доступ construction: Дарогі ў стадыі будаўніцтва + bus_stop: Аўтобусны прыпынак bicycle_shop: Крама ровараў bicycle_parking: Паркоўка для ровараў toilets: Прыбіральні @@ -2524,18 +2573,49 @@ be: flash: Кліенцкая інфармацыя была абноўленая паспяхова destroy: flash: Знішчаная рэгістрацыя кліенцкага дастасавання + oauth2_applications: + index: + new: Зарэгістраваць новую праграму + name: Назва + permissions: Дазволы + application: + edit: Рэдагаваць + delete: Выдаліць + new: + title: Зарэгістраваць новую праграму + show: + edit: Правіць + delete: Выдаліць users: new: title: Зарэгістравацца + tab_title: Зарэгістравацца no_auto_account_create: На жаль, мы не можам стварыць для вас уліковы запіс аўтаматычна. about: header: Свабодная і даступная для рэдагавання + paragraph_1: У адрозненне ад іншых карт, OpenStreetMap цалкам створана такімі + ж людзьмі як вы і кожны можа яе свабодна рэдагаваць і выкарыстоўваць. + paragraph_2: Зарэгіструйцеся, каб зрабіць свой унёсак. + welcome: Вітаем у OpenStreetMap display name description: Ваша імя, якое будзе бачнае ўсім. Вы можаце змяніць яго потым ў вашых параметрах. + by_signing_up: + html: Рэгіструючыся, вы пагаджаецеся з нашымі %{tou_link}, %{privacy_policy_link} + і %{contributor_terms_link}. + privacy_policy: палітыкай прыватнасці + contributor_terms: умовамі ўдзелу + tou: умовамі карыстання external auth: 'Аўтэнтыфікацыя праз:' continue: Зарэгістравацца terms accepted: Дзякуй за прыняцце новых умоў ўдзелу! + email_help: + privacy_policy: палітыкі прыватнасці + html: Адрас вашай электроннай пошты не будзе паказвацца іншым карыстальнікам, + звярніцеся да %{privacy_policy_link} за больш дэтальнай інфармацыяй. + consider_pd_html: Я пагаджаюся з тым, што мой унёсак будзе часткай %{consider_pd_link}. + consider_pd: грамадскага набытку + or: або use external auth: У якасці альтэрнатывы выкарыстайце для ўваходу старонні сервіс terms: title: Умовы @@ -2588,6 +2668,9 @@ be: remove as friend: Выдаліць з сяброў add as friend: Пасябраваць mapper since: 'Малюе карту з:' + last map edit: 'Апошняе рэдагаванне карты:' + no activity yet: Актыўнасці пакуль няма + uid: 'ID карыстальніка:' ct status: 'Умовы ўдзелу:' ct undecided: Нявырашана ct declined: Адхіленыя @@ -2598,18 +2681,24 @@ be: role: administrator: Гэты карыстальнік з’яўляецца адміністратарам moderator: Гэты карыстальнік з’яўляецца мадэратарам + importer: Гэты карыстальнік займаецца імпартам даных grant: administrator: Надаць правы адміністратара moderator: Надаць правы мадэратара + importer: Дазволіць карыстальніку імпарт даных revoke: administrator: Адклікаць доступ з правамі адміністратара moderator: Скасаваць доступ мадэратара + importer: Забараніць карыстальніку імпарт даных block_history: Дзейныя блакіроўкі moderator_history: Створаныя блакіроўкі + revoke_all_blocks: Скасаваць усе блакіроўкі comments: Каментары create_block: Заблакаваць гэтага карыстальніка activate_user: Актываваць гэтага карыстальніка confirm_user: Пацвердзіць гэтага карыстальніка + unconfirm_user: Адмяніць пацвярджэнне гэтага карыстальніка + unsuspend_user: Адмяніць прыпыненне ўліковага запісу гэтага карыстальніка hide_user: Схаваць гэтага карыстальніка unhide_user: Паказаць гэтага карыстальніка delete_user: Выдаліць гэтага карыстальніка @@ -2620,6 +2709,8 @@ be: index: title: Удзельнікі heading: Удзельнікі + older: Даўнейшыя карыстальнікі + newer: Навейшыя карыстальнікі summary_html: '%{name} створана з %{ip_address} %{date}' summary_no_ip_html: '%{name} створаны %{date}' confirm: Пацвердзіць выбраных карыстальнікаў @@ -2628,6 +2719,11 @@ be: suspended: title: Уліковы запіс прыпынены heading: Уліковы запіс прыпынены + support: службы падтрымкі + automatically_suspended: На жаль, ваш уліковы запіс быў прыпынены з-за падазронай + актыўнасці. + contact_support_html: Гэтае рашэнне будзе разгледжана адміністратарам у хуткім + часе або вы можаце напісаць да %{support_link}, калі вы жадаеце яго абмеркаваць. auth_failure: connection_failed: Злучэнне з крыніцай аўтэнтыфікацыі не атрымалася invalid_credentials: Памылковыя ўліковыя даныя для праверкі сапраўднасці @@ -2683,7 +2779,6 @@ be: show: Паказаць гэтую блакіроўку back: Паказаць усе блакіроўкі filter: - block_expired: Блакіроўка ўжо скончылася і не можа рэдагавацца. block_period: Час блакіроўкі павінен быць выбраны са значэнняў з разгортваемага спісу. create: @@ -2740,7 +2835,8 @@ be: show: title: '%{block_on} заблакіраваны %{block_by}' heading_html: '%{block_on} заблакіраваны %{block_by}' - created: Створаны + created: 'Створана:' + duration: 'Працягласць:' status: 'Статус:' show: Паказаць edit: Рэдагаваць @@ -2761,11 +2857,17 @@ be: reason: Прычына блакіроўкі status: Статус revoker_name: Адкліканы + user_mutes: + index: + table: + tbody: + send_message: Даслаць паведамленне notes: index: title: Заўвагі, створаныя ці пракаментаваныя %{user} heading: Заўвагі %{user}'а subheading_html: Заўвагі, створаныя ці пракаментаваныя %{user} + no_notes: Няма запісаў id: Id creator: Стваральнік description: Апісанне @@ -2777,6 +2879,10 @@ be: open_title: 'Нявырашаная заўвага #%{note_name}' closed_title: 'Вырашаная заўвага #%{note_name}' hidden_title: 'Схаваная заўвага #%{note_name}' + event_opened_by_html: Створана карыстальнікам %{user} %{time_ago} + event_opened_by_anonymous_html: Створана ананімным карыстальнікам %{time_ago} + event_commented_by_html: Пракаментавана карыстальнікам %{user} %{time_ago} таму + event_commented_by_anonymous_html: Пракаментавана ананімным карыстальнікам %{time_ago} report: паскардзіцца на гэтую заўвагу anonymous_warning: Гэтая нататка змяшчае каментары ад ананімных карыстальнікаў, што павінны быць незалежна правераны. @@ -2790,6 +2896,7 @@ be: intro: Заўважылі памылку або чагосьці не стае? Дайце іншым удзельнікам магчымасць даведацца пра памылку і такім чынам мы выправім яе. Перамясціце маркер у патрэбную пазіцыю і напішыце заўвагу з тлумачэннем праблемы. + anonymous_warning_sign_up: Зарэгістравацца advice: Ваша заўвага агульнадаступная і можа выкарыстоўвацца для абнаўлення карты, таму не ўводзьце асабістую інфармацыю або інфармацыю з абароненых аўтарскім правам карт або рэестраў. @@ -2850,6 +2957,9 @@ be: gps: Агульныя GPS-сляды overlays: Уключыць накладкі для ліквідацыі памылак карты title: Слаі + make_a_donation: Зрабіць ахвяраванне + website_and_api_terms: Умовы вэб-сайта і API + osm_france: OpenStreetMap Францыя site: edit_tooltip: Рэдагаваць карту edit_disabled_tooltip: Наблізце, каб рэдагаваць карту @@ -2873,6 +2983,8 @@ be: descend: Уніз directions: Маршрут distance: Адлегласць + distance_m: '%{distance}м' + distance_km: '%{distance}км' errors: no_route: Не атрымалася знайсці маршрут паміж двума гэтымі месцамі. no_place: 'Прабачце - не магу знайсці гэта месца: %{place}.' diff --git a/config/locales/bg.yml b/config/locales/bg.yml index ba58716d9..67ecb6745 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -1134,10 +1134,10 @@ bg: "yes": Воден път admin_levels: level2: Държавна граница - level4: Държавна граница - level5: Граница на региона - level6: Областна граница - level7: Общинска граница + level4: Граница на област + level5: Граница на община + level6: Граница на район + level7: Граница на кметство level8: Граница на землище level9: Граница на селото level10: Граница на предградията @@ -1495,7 +1495,9 @@ bg: shared: markdown_help: headings: Заглавия + heading: Заглавие subheading: Подзаглавие + unordered: Неподреден списък ordered: Подреден списък first: Първи елемент second: Втори елемент @@ -1566,8 +1568,23 @@ bg: mapping_link: картографирате legal_babble: credit_title_html: Как да кредитирате OpenStreetMap + credit_1_html: 'Когато използвате данни от OpenStreetMap, от вас се изисква + да направите следните две неща:' + credit_2_1: Предоставете кредит към OpenStreetMap, като покажете нашето уведомление + за авторски права. + credit_2_2: Ясно да посочите, че данните са достъпни съгласно Лиценза за отворени + бази данни (Open Database License). + credit_3_html: По отношение на известието за авторските права имаме различни + изисквания за начина, по който то трябва да се показва, в зависимост от + това как използвате нашите данни. В зависимост от това дали сте създали + карта с възможност за преглед, печатна карта или статично изображение, се + прилагат различни правила за начина на показване на съобщението за авторски + права. Пълна информация за изискванията може да бъде намерена в %{attribution_guidelines_link}. more_title_html: Открийте повече contributors_title_html: Нашите сътрудници + contributors_intro_html: 'Нашите сътрудници са хиляди хора. Ние включваме + и данни, които са отворено лицензирани от национални картографски агенции + и други източници, сред които:' infringement_title_html: Нарушаване на авторските права infringement_1_html: Напомняме на сътрудниците на OSM никога да не добавят данни от източници, защитени с авторски права (например Google Maps или @@ -1788,6 +1805,7 @@ bg: степен като местните клонове. Всъщност много групи съществуват много успешно като неформално събиране на хора или като общностна група. Всеки може да ги създаде или да се присъедини към тях. Прочетете повече на %{communities_wiki_link}. + communities_wiki: уики страница Общности traces: new: upload_trace: Качване на следи от GPS @@ -1848,8 +1866,10 @@ bg: index: public_traces: Публични следи от GPS public_traces_from: Публични следи от GPS от потребител %{user} + description: Преглед на скорошни качвания на GPS следи tagged_with: с етикет %{tags} upload_trace: Качване на следи от GPS + all_traces: Всички следи my_traces: Моите следи georss: title: OpenStreetMap GPS трасета @@ -2019,8 +2039,6 @@ bg: edit: title: Промяна на блокирането на %{name} heading_html: Промяна на блокирането на %{name} - filter: - block_expired: Блокирането вече е изтекло и не може да се редактира. revoke: revoke: Анулиране! helper: diff --git a/config/locales/br.yml b/config/locales/br.yml index 96bf2e421..548529766 100644 --- a/config/locales/br.yml +++ b/config/locales/br.yml @@ -2484,22 +2484,22 @@ br: openid_login_button: Kenderc'hel openid: title: Kevreañ gant OpenID - alt: Kevreañ gant un URL OpenID + alt: Logo OpenID google: title: Kevreañ gant Google - alt: Kevreañ gant OpenID Google + alt: Logo Google facebook: title: Kevreañ gant Facebook - alt: Kevreañ gant ur gont Facebook + alt: Logo Facebook microsoft: title: Kevreañ gant Microsoft - alt: Kevreañ gant ur gont Microsoft + alt: Logo Microsoft github: title: Kevreañ gant GitHub - alt: Kevreañ gant ur gont GitHub + alt: Logo GitHub wikipedia: title: Kevreañ gant Wikipedia - alt: Kevreañ gant ur gont Wikipedia + alt: Logo Wikipedia oauth: authorize: title: Aotren mont d'ho kont @@ -2650,6 +2650,7 @@ br: terms accepted: Trugarez deoc'h evit bezañ asantet da ziferadennoù nevez ar c'henlabourer ! email_help: + privacy_policy: Politikerezh prevezded html: Ho chomlec'h ne vo ket hewel d'an holl, sellit ouzh %{privacy_policy_link} evit gouzout hiroc'h. consider_pd: domani foran @@ -2823,7 +2824,6 @@ br: show: Gwelet ar stankadur-mañ back: Gwelet an holl stankadurioù filter: - block_expired: Aet eo ar stankadur d'e dermen dija ha ne c'hall ket bezañ aozet. block_period: Ar prantad stankañ a rank bezañ unan eus an talvoudoù a c'haller dibab ar roll disac'hañ. create: diff --git a/config/locales/bs.yml b/config/locales/bs.yml index 9eda7a4e8..fbb3aa7c7 100644 --- a/config/locales/bs.yml +++ b/config/locales/bs.yml @@ -1471,7 +1471,6 @@ bs: show: Pogledati ovu blokadu back: Pogledati sve blokade filter: - block_expired: Blokada je već istekla i ne može se uređivati. block_period: Period blokade mora biti jedna od vrijednosti iz drop-down liste. create: flash: Napraviti blokadu na korisnika %{name}. diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 6cd0f05c2..eb1e7f6e9 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -2870,7 +2870,6 @@ ca: show: Mostra el bloc back: Mostra tots els blocs filter: - block_expired: El bloc ja ha expirat i no es pot editar. block_period: El període de blocatge ha de ser un dels valors seleccionables de la llista desplegable. create: diff --git a/config/locales/ce.yml b/config/locales/ce.yml index 8d2d39ebf..1fcecbf07 100644 --- a/config/locales/ce.yml +++ b/config/locales/ce.yml @@ -124,7 +124,7 @@ ce: longitude: Дохалла public: Массарна description: Цуьнах лаьцна - gpx_file: GPX файл чуяккха + gpx_file: GPX файл чуйаккха visibility: Гуш хилар tagstring: Тегаш message: @@ -1618,6 +1618,7 @@ ce: коьрта белхаш дӀахьош долу дера. osm_read_only: OpenStreetMap база карарчу хенахь ешаран режимехь йу,база Ӏалашъяран белхаш дӀахьош долу дер. + nothing_to_preview: Хьалххе хьажа хӀумма а дац. donate: Дехар ду, гӀо де OpenStreetMap %{link} аппаратан фонда карлайоккхуш. help: ГӀо about: Проектах лаьцна @@ -1663,13 +1664,19 @@ ce: befriend_them: Иштта %{befriendurl} чохь доттагӀ санна тӀетоха йиш йу хьан. befriend_them_html: Иштта %{befriendurl} чохь доттагӀ санна тӀетоха йиш йу хьан. gpx_description: + description_with_tags: 'Иза хьан GPX файлах тера йу %{trace_name} %{trace_description} + описаниеца а, хӀара тегашца а: %{tags}' description_with_tags_html: 'Иза хьан GPX файлах тера йу %{trace_name} %{trace_description} описаниеца а, хӀара тегашца а: %{tags}' + description_with_no_tags: Иза хьан GPX файлах тера йу %{trace_name} %%{trace_description} + дицарца, цхьа а тег йоцуш description_with_no_tags_html: Иза хьан GPX файлах тера йу %{trace_name} %%{trace_description} дицарца, цхьа а тег йоцуш gpx_failure: hi: Маршалла ду %{to_user}, failed_to_import: 'импорт ян аьтто ца баьлла. Кхузахь гӀалат ду:' + more_info: GPX импортан кхачамбацарех лаьцна кхин а хаамаш каро йиш йу %{url} + тӀехь. more_info_html: GPX импортан кхачамбацарех лаьцна кхин а хаамаш каро йиш йу %{url} тӀехь. subject: '[OpenStreetMap] GPX Импорт ца хилира' @@ -1679,6 +1686,8 @@ ce: one: кхиамца дӀатоьхна %{trace_points}хила тарлучу %{count} point. точках. other: loaded successfully with %{trace_points}хила тарлучу %{count} points. точках. + trace_location: Хьан лар лело йиш йу %{trace_url} + all_your_traces: Хьан йерриге а кхиамца чуйиллина GPX лараш каро йиш йу %{url} all_your_traces_html: Хьан ерриге а кхиамца чуйиллина GPX лараш каро йиш йу %{url} тӀехь. subject: '[OpenStreetMap] GPX Импортан дика хилира' @@ -1979,7 +1988,7 @@ ce: url: URL codeblock: Кодан блок richtext_field: - edit: Нисйе + edit: Нисйан preview: Хьажа site: about: @@ -2263,11 +2272,11 @@ ce: description: Йукъаралло латтош йу болалуш болчарна хьехам. community: title: ГӀо а, йукъараллин форум а - description: OpenStreetMap-ах лаьцна гӀо лаха а, къамелаш дан а юкъара меттиг. + description: OpenStreetMap-ах лаьцна гӀо лаха а, къамелаш дан а йукъара меттиг. mailing_lists: title: Почтан тептарш - description: Хаттар ло йа дийцаре де оьшуш долу хаттарш, шуьйрачу актуальни - йа регионан рассылкашкахь. + description: Хаттар ло йа дийцаре де оьшуш долу хаттарш, шуьйрачу актуалан + йа регионан дIасатасаршкахь. irc: title: IRC description: Интерактивни чат тайп-тайпанчу меттанашкахь а, дуккха а теманашца @@ -2517,7 +2526,7 @@ ce: start_coordinates: 'Координатийн йуьхь:' coordinates_html: '%{latitude}; %{longitude}' map: карта - edit: нисйе + edit: нисйан owner: 'Йерг:' description: 'Цуьнах лаьцна:' tags: 'Тегаш:' @@ -2659,6 +2668,8 @@ ce: write_notes: заметкаш хийца write_redactions: Картан хаамаш хийца read_email: Декъашхочун электронан почтан адрес деша + consume_messages: Деша, статус карлайаккха, лелончан хаамаш дӀабаха + send_messages: Кхечу лелочаьрга леррина хаамаш дӀакхачо skip_authorization: Автоматически дӀахьедар тӀечӀагӀдар for_roles: moderator: ХӀара бакъо лерина йу модераторшна бен лело йиш йоцучу гӀуллакхашна @@ -2714,15 +2725,15 @@ ce: name: ЦӀе permissions: Магор application: - edit: Нисйе + edit: Нисйан delete: ДӀайаккха confirm_delete: Ð¥Iар приложени дӀайаккха? new: title: Регистаци е керла приложенина edit: - title: Нисйе хьан приложени + title: Хьан приложени нисйан show: - edit: Нисйе + edit: Нисйан delete: ДӀайаккха confirm_delete: Ð¥Iар приложени дӀайаккха? client_id: Клиентан ID @@ -2804,7 +2815,7 @@ ce: а, тӀаккха ши байракха а гIоттайай, «ДӀадахьа» нуьйда тӀе тӀаIайе contributor_terms_explain: ХӀокху барто леладо хьан хӀинцалера а, хиндолчу а дакъалацаран хьелаш. - read_ct: Ас ешна а, реза а ву лакхахь хьахийначу хьолана. + read_ct: Ас йешна а, реза а ву лакхахь хьахийначу хьолана. tou_explain_html: '%{tou_link} урхалла до веб-сайтан а, OSMF-о луш йолчу кхечу инфраструктуран а. Дехар ду, ссылка тӀе а таӀийна, хьажа текстана тIех долчунна.' read_tou: Со реза ву Лелоран хьолашна @@ -2975,12 +2986,13 @@ ce: show: ХӀокху блоке хьажа back: Гайта дерриге блоктохарш filter: - block_expired: Блок хӀинцале чекхъяьлла,йа и хийца йиш яц. block_period: Блокировкан мур хила беза цхьаъ маьIан долуш тептарчура хаьржина. create: flash: Декъашхочунна %{name} тӀехь блок кхоьллина . update: only_creator_can_edit: И блок кхоьллинчу модераторан бен хийца йиш яц. + only_creator_or_revoker_can_edit: ХӀара блок кхоьллинчу йа йухайаьккхинчу модераторийн + бен хийца йиш йац. success: Блок карлайаккхина. index: title: Декъашхочун блоктохар @@ -3291,6 +3303,8 @@ ce: агӀора onramp_left_without_directions: Аьрру агӀор дӀаверза onramp_left: Аьрру агӀор дӀаверза + endofroad_left_without_exit: Некъ чаккхаболучех аьрру агӀор дӀаверза %{name} + тӀе. merge_left_without_exit: Аьрру агӀор вала %{name} тIе fork_left_without_exit: ГӀонжагӀехь аьрру агӀор дӀаверза %{name} тӀе. slight_left_without_exit: '%{name} тӀе аьрру агӀор меллаш дӀаверза' @@ -3338,7 +3352,7 @@ ce: redactions: edit: heading: Нисйе редакци - title: Нисйе редакци + title: Редакци нисйан index: empty: Гайта цхьа а редакци яц. heading: Редакцин тептар diff --git a/config/locales/cs.yml b/config/locales/cs.yml index bacaa1ede..f284caefc 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -707,6 +707,8 @@ cs: comment: Komentář newer_comments: Novější komentáře older_comments: Starší komentáře + new: + heading: Přidat komentář do následující diskuse k deníkovému záznamu? doorkeeper: errors: messages: @@ -745,6 +747,10 @@ cs: contact_the_community_html: Neváhejte %{contact_link} komunitu OpenStreetMap, pokud jste naÅ¡li nefunkční odkaz / chybu. Poznamenejte si přesnou adresu URL vaÅ¡eho požadavku. + bad_request: + title: Chybný požadavek + description: Operace, kterou jste žádali po serveru OpenStreetMap, není platná + (HTTP 400) forbidden: title: Zakázáno description: Operace, kterou jste požadovali na serveru OpenStreetMap, je dostupná @@ -941,6 +947,7 @@ cs: college: Budova Å¡koly commercial: Komerční budova construction: Budova ve výstavbě + cowshed: Kravín detached: Rodinný dům dormitory: Kolej duplex: Dvojdomek @@ -970,6 +977,7 @@ cs: shed: Kůlna stable: Stáj static_caravan: Karavan + sty: Vepřín temple: Budova chrámu terrace: Terasovitá budova train_station: Železniční stanice @@ -1820,8 +1828,8 @@ cs: Poznámka je umístěna poblíž %{place}.' commented_note_html: '%{commenter} reaktivoval poznámku k mapě, kterou jste komentovali. Poznámka je umístěna poblíž %{place}.' - details: Podrobnosti k poznámce můžete najít na %{url}. - details_html: Podrobnosti k poznámce můžete najít na %{url}. + details: Odpovědět nebo se dozvědět více o této poznámce můžete na %{url}. + details_html: Odpovědět nebo se dozvědět více o této poznámce můžete na %{url}. changeset_comment_notification: description: 'Sada změn OpenStreetMap #%{id}' hi: Dobrý den, uživateli %{to_user}, @@ -1842,8 +1850,8 @@ cs: partial_changeset_with_comment: s komentářem „%{changeset_comment}“ partial_changeset_with_comment_html: s komentářem „%{changeset_comment}“ partial_changeset_without_comment: bez komentáře - details: Více informací o této sadě změn lze nalézt na %{url}. - details_html: Odpovězte nebo se zjistěte více o změnách na %{url}. + details: Odpovědět nebo se dozvědět více o této sadě změn můžete na %{url}. + details_html: Odpovědět nebo se dozvědět více o této sadě změn můžete na %{url}. unsubscribe: Od aktualizací této sady změn se můžete odhlásit na %{url}. unsubscribe_html: Od aktualizací této sady změn se můžete odhlásit na %{url}. confirmations: @@ -2670,7 +2678,7 @@ cs: other: GPX soubor s %{count} body od uživatele %{user} description_without_count: GPX soubor od uživatele %{user} application: - basic_auth_disabled: 'HTTP základní autentifikace je zakázaná: %{link}' + basic_auth_disabled: 'HTTP Basic autentizace je zakázaná: %{link}' oauth_10a_disabled: 'OAuth 1.0 a 1.0a jsou zakázané: %{link}' permission_denied: Pro přístup k této akci nemáte oprávnění require_cookies: @@ -2697,22 +2705,22 @@ cs: openid_login_button: Pokračovat openid: title: Přihlásit se pomocí OpenID - alt: OpenID Logo + alt: Logo OpenID google: title: Přihlásit se prostřednictvím Google - alt: Google Logo + alt: Logo Googlu facebook: title: Přihlásit se přes Facebook - alt: Facebook logo + alt: Logo Facebooku microsoft: title: Přihlásit se přes Microsoft - alt: Microsoft Logo + alt: Logo Microsoftu github: title: Přihlásit se přes GitHub - alt: GitHub Logo + alt: Logo GitHubu wikipedia: title: Přihlásit se účtem na Wikipedii - alt: Wikipedia Logo + alt: Logo Wikipedie oauth: authorize: title: Autorizovat přístup k vaÅ¡emu účtu @@ -2881,7 +2889,7 @@ cs: continue: Zaregistrovat se terms accepted: Děkujeme za odsouhlasení nových podmínek pro přispěvatele! email_help: - privacy_policy: Zásady ochrany osobních údajů + privacy_policy: pravidly ochrany osobních údajů privacy_policy_title: Pravidla ochrany osobních údajů OSMF, včetně části o e-mailových adresách html: VaÅ¡e adresa se nezobrazuje veřejně, více informací získáte na stránce @@ -3069,7 +3077,6 @@ cs: show: Zobrazit tento blok back: Zobrazit vÅ¡echny bloky filter: - block_expired: Tento blok již vyprÅ¡el, a proto ho nelze upravovat. block_period: Doba bloku musí být jedna z těch, které obsahuje rozevírací seznam. create: flash: Uživatel %{name} zablokován. @@ -3246,8 +3253,10 @@ cs: intro: Zahlédli jste chybu nebo prázdné místo? Dejte vědět ostatním uživatelům, aby to mohli napravit. Posuňte značku na správné místo a napiÅ¡te poznámku vysvětlující problém. - anonymous_warning_log_in: Přihlásit se - anonymous_warning_sign_up: Zaregistrovat se + anonymous_warning_html: Nejste přihlášeni. Pokud chcete získávat aktualizace + k vaší poznámce, %{log_in} nebo %{sign_up}. + anonymous_warning_log_in: přihlaste se + anonymous_warning_sign_up: se zaregistrujte advice: VaÅ¡e poznámka je veřejná a může sloužit k úpravám mapy, proto nevkládejte žádné osobní údaje ani informace z autorskoprávně chráněných map či adresářů. add: Přidat poznámku @@ -3265,14 +3274,15 @@ cs: custom_dimensions: Nastavit vlastní rozměry format: 'Formát:' scale: 'Měřítko:' - image_dimensions: Obrázek bude ukazovat standardní vrstvu v %{width} × %{height} + image_dimensions: Obrázek bude ukazovat vrstvu %{layer} v %{width} × %{height} download: Stáhnout short_url: Krátké URL include_marker: Vložit značku center_marker: Vycentrovat mapu na značku paste_html: HTML ke vložení na webovou stránku view_larger_map: Zobrazit větší mapu - only_standard_layer: Jako obrázek lze exportovat jen standardní vrstvu + only_standard_layer: Jako obrázek lze exportovat jen vrstvy Standardní, Cyklomapa + a Dopravní embed: report_problem: Nahlásit problém key: diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 08de0e767..4f1cd9229 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -438,8 +438,8 @@ cy: way: llwybr relation: perthynas start_rjs: - feature_warning: Wrthi'n llwytho %{num_features} nodwedd, a all arafu eich porwr. - Ydych chi wir eisiau gweld y data? + feature_warning: Wrthi'n llwytho %{num_features} nodwedd, a all arafu neu chwalu + eich porwr. Ydych chi wir eisiau gweld y data? load_data: Llwytho data loading: Wrthi'n llwytho... tag_details: @@ -458,9 +458,15 @@ cy: introduction: Cliciwch ar y map i ddarganfod nodweddion gerllaw. nearby: Nodweddion gerllaw enclosing: Nodweddion amgáu + old_nodes: + not_found: + sorry: 'Sori, ni ellir canfod fersiwn %{version} o''r nod #%{id}.' old_ways: not_found: sorry: 'Sori, ni ellir canfod fersiwn %{version} o lwybr #%{id}.' + old_relations: + not_found: + sorry: 'Sori, ni ellir canfod fersiwn %{version} o''r perthynas #%{id}.' changesets: changeset_paging_nav: showing_page: Tudalen %{page} diff --git a/config/locales/da.yml b/config/locales/da.yml index 8f9f1adaa..fe20af61a 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -1646,6 +1646,7 @@ da: databasevedligeholdelse. osm_read_only: OpenStreetMap databasen er for øjeblikket ikke redigerbar pÃ¥ grund af database vedligeholdelse. + nothing_to_preview: Intet at forhÃ¥ndsvise donate: Støt OpenStreetMap med en %{link} til Hardware-upgradefonden. help: Hjælp about: Om @@ -2698,6 +2699,8 @@ da: write_notes: Ændre bemærkninger write_redactions: Rediger kortdata read_email: Læse brugerens e-mailadresse + consume_messages: Læs, opdater status og slet brugerbeskeder + send_messages: Send private beskeder til andre brugere skip_authorization: Godkend applikation automatisk for_roles: moderator: Denne tilladelse er til handlinger, der kun er tilgængelige for moderatorer @@ -3015,7 +3018,6 @@ da: show: Vis denne blokering back: Vis alle blokeringer filter: - block_expired: Blokeringen er allerede udløbet og kan ikke redigeres. block_period: Blokeringsperioden skal være en af de værdier der er valgbar i listen over værdier. create: @@ -3023,6 +3025,8 @@ da: update: only_creator_can_edit: Kun moderatoren som oprettede denne blokering kan ændre den. + only_creator_or_revoker_can_edit: Kun de moderatorer, der har oprettet eller + ophævet denne blokering, kan redigere den. success: Blokering opdateret. index: title: Brugerblokeringer @@ -3203,14 +3207,15 @@ da: custom_dimensions: Angiv brugerdefinerede dimensioner format: 'Format:' scale: 'Skala:' - image_dimensions: Billedet vil vise standardlaget i %{width} x %{height} + image_dimensions: Billedet vil vise laget %{layer} i %{width} x %{height} download: Hent short_url: Kort URL include_marker: Tilføj markør center_marker: Centrér kortet pÃ¥ markøren paste_html: Indsæt HTML som skal indlejres i websiden view_larger_map: Vis større kort - only_standard_layer: Kun standardlaget kan eksporteres som et billede + only_standard_layer: Kun lagene standard, cykelkort og transport kan eksporteres + som et billede embed: report_problem: Rapporter et problem key: diff --git a/config/locales/de.yml b/config/locales/de.yml index 681c0dec3..171efd3f8 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1737,6 +1737,7 @@ de: nicht verfügbar. osm_read_only: Die OpenStreetMap-Datenbank ist im Moment wegen wichtiger Wartungsarbeiten im „Nur-Lesen-Modus“. + nothing_to_preview: Es gibt keine Vorschau. donate: Unterstütze die OpenStreetMap-Hardwarespendenaktion durch eine eigene %{link}. help: Hilfe @@ -1788,13 +1789,19 @@ de: befriend_them: Du kannst sie/ihn unter %{befriendurl} ebenfalls als Freund hinzufügen. befriend_them_html: Du kannst sie/ihn unter %{befriendurl} auch als Freund hinzufügen. gpx_description: + description_with_tags: 'Es sieht so aus, als ob deine GPX-Datei %{trace_name} + mit der Beschreibung %{trace_description} und den folgenden Tags: %{tags}' description_with_tags_html: 'Es scheint, dass deine GPX-Datei %{trace_name} mit der Beschreibung %{trace_description} und den folgenden Tags: %{tags}' + description_with_no_tags: Es sieht so aus, als ob deine GPX-Datei %{trace_name} + mit der Beschreibung %{trace_description} und ohne Tags description_with_no_tags_html: Es scheint, dass deine GPX-Datei %{trace_name} mit der Beschreibung %{trace_description} und ohne Tags gpx_failure: hi: Hallo %{to_user}, failed_to_import: 'konnte nicht importiert werden, die Fehlermeldung:' + more_info: Weitere Informationen über Fehler bei GPX-Importen und wie sie vermieden + werden können finden sich in %{url} more_info_html: Weitere Informationen über Fehler bei GPX-Importen und wie sie vermieden werden können finden sich in %{url} import_failures_url: https://wiki.openstreetmap.org/wiki/DE:GPX#Warum_wurde_meine_GPX-Datei_nicht_richtig_hochgeladen.3F @@ -1804,6 +1811,9 @@ de: loaded: one: mit %{trace_points} von einem möglichen Punkt erfolgreich geladen. other: mit %{trace_points} von %{count} möglichen Punkten erfolgreich geladen. + trace_location: Dein Track ist verfügbar unter %{trace_url} + all_your_traces: Alle deine erfolgreich hochgeladenen GPX-Tracks findest du + unter %{url}. all_your_traces_html: Alle deine erfolgreich hochgeladenen GPX-Traces findest du unter %{url}. subject: '[OpenStreetMap] GPX-Import erfolgreich' @@ -2840,6 +2850,8 @@ de: write_notes: Notizen bearbeiten write_redactions: Kartendaten redigieren read_email: Lesen der Benutzer-E-Mail-Adresse + consume_messages: Lesen, Aktualisieren des Status und Löschen von Benutzernachrichten + send_messages: Private Nachrichten an andere Benutzer senden skip_authorization: Antrag automatisch genehmigen for_roles: moderator: Diese Berechtigung gilt nur für Aktionen, die nur Moderatoren zur @@ -3173,14 +3185,14 @@ de: show: Diese Sperre anzeigen back: Alle Sperren anzeigen filter: - block_expired: Die Sperre kann nicht bearbeitet werden, da die Sperrdauer bereits - abgelaufen ist. block_period: Die Sperrdauer muss einem der Werte aus der Drop-Down-Liste entsprechen. create: flash: Benutzer %{name} wurde gesperrt. update: only_creator_can_edit: Nur der Moderator, der die Sperre eingerichtet hat, kann sie ändern. + only_creator_or_revoker_can_edit: Nur die Moderatoren, die die Sperre eingerichtet + haben, können sie ändern. success: Sperre aktualisiert. index: title: Benutzersperren diff --git a/config/locales/dsb.yml b/config/locales/dsb.yml index e7a1d3508..b08248f3c 100644 --- a/config/locales/dsb.yml +++ b/config/locales/dsb.yml @@ -1623,7 +1623,6 @@ dsb: show: Toś to blokěrowanje pokazaś back: WÅ¡ykne blokěrowanja pokazaś filter: - block_expired: Blokěrowanje jo južo pśepadnuło a njedajo se wobźěłaś. block_period: Cas blokěrowanja musy jadna z gódnotow byś, kótarež daju se z padajuceje lisćiny wubraś. create: diff --git a/config/locales/el.yml b/config/locales/el.yml index ef3f2c0b2..38d191b11 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -677,6 +677,9 @@ el: comment: Σχόλιο newer_comments: Νεότερα σχόλια older_comments: Παλαιότερα σχόλια + new: + heading: Να προσθέσετε ένα σχόλιο στην ακόλοουθη συζήτηση για την καταχώριση + ημερολογίου; doorkeeper: errors: messages: @@ -922,6 +925,7 @@ el: college: Πανεπιστημιακό κτήριο commercial: Εμπορικό κτήριο construction: Κτήριο υπό κατασκευή + cowshed: Αγελαδοστάσιο detached: Μεζονέτα dormitory: Κοιτώνας duplex: Μεζονέτα @@ -951,6 +955,7 @@ el: shed: Υπόστεγο stable: Στάβλος static_caravan: Τροχόσπιτο + sty: Χοιροστάσιο temple: Κτήριο ναού terrace: Σειρά όμοιων σπιτιών train_station: Κτήριο Σιδηροδρομικού Σταθμού @@ -1670,6 +1675,7 @@ el: λόγω εργασιών συντήρησης. osm_read_only: Η βάση δεδομένων του OpenStreetMap έχει τεθεί προσωρινά σε λειτουργία «μόνο για ανάγνωση» λόγω εργασιών συντήρησης. + nothing_to_preview: Τίποτα για προεπισκόπηση. donate: Υποστηρίξτε το OpenStreetMap %{link} στον έρανο αναβάθμισης υλικού. help: Βοήθεια about: Σχετικά @@ -1718,13 +1724,19 @@ el: befriend_them: Μπορείτε επίσης να τους προσθέσετε ως φίλους στο %{befriendurl}. befriend_them_html: Μπορείτε επίσης να τους προσθέσετε ως φίλους στο %{befriendurl}. gpx_description: + description_with_tags: 'Φαίνεται πως το αρχείο σας GPX %{trace_name} με την + περιγραφή %{trace_description} και με τις παρακάτω ετικέτες: %{tags}' description_with_tags_html: 'Φαίνεται πως το αρχείο σου GPX %{trace_name} με την περιγραφή %{trace_description} και με τις παρακάτω ετικέτες: %{tags}' + description_with_no_tags: Φαίνεται πως το αρχείο σας GPX %{trace_name} με την + περιγραφή %{trace_description} και χωρίς ετικέτες description_with_no_tags_html: Φαίνεται πως το αρχείο σου GPX %{trace_name} με την περιγραφή %{trace_description} και χωρίς ετικέτες gpx_failure: hi: Γεια σας %{to_user}, failed_to_import: 'Απέτυχε η εισαγωγή. Το σφάλμα είναι:' + more_info: Περισσότερες πληροφορίες σχετικά με τα σφάλματα εισαγωγής GPX και + πως να τα αποφύγετε, μπορείτε να βρείτε στο %{url}. more_info_html: Περισσότερες πληροφορίες σχετικά με τις αποτυχίες εισαγωγής GPX και τον τρόπο αποφυγής τους μπορείτε να βρείτε στη διεύθυνση %{url}. subject: '[OpenStreetMap] Η εισαγωγή GPX απέτυχε' @@ -1733,6 +1745,9 @@ el: loaded: one: φορτώθηκε επιτυχώς με %{trace_points} από πιθανό %{count} σημείο. other: φορτώθηκε επιτυχώς με %{trace_points} από πιθανά %{count} σημεία. + trace_location: Το ίχνος σας είναι διαθέσιμο στο %{trace_url} + all_your_traces: Όλα τα επιτυχώς ανεβασμένα ίχνη GPX σας μπορούν να βρεθούν + στο %{url} all_your_traces_html: Όλα τα ίχνη GPX που ανεβάσατε με επιτυχία μπορούν να βρεθούν στη διεύθυνση %{url}. subject: '[OpenStreetMap] Η εισαγωγή GPX πέτυχε' @@ -2654,25 +2669,26 @@ el: oauth2_authorizations: Εξουσιοδοτήσεις OAuth 2 muted_users: Χρήστες σε Σίγαση auth_providers: + openid_url: OpenID URL openid_login_button: Συνέχεια openid: title: Σύνδεση με OpenID - alt: Σύνδεση με ένα OpenID URL + alt: Λογότυπο OpenID google: title: Σύνδεση με Google - alt: Σύνδεση με ένα Google OpenID + alt: Λογότυπο Google facebook: title: Σύνδεση με Facebook - alt: Σύνδεση με λογαριασμό Facebook + alt: Λογότυπο Facebook microsoft: title: Σύνδεση με Microsoft - alt: Σύνδεση με λογαριασμό Microsoft + alt: Λογότυπο Microsoft github: title: Σύνδεση με GitHub - alt: Σύνδεση με λογαριασμό GitHub + alt: Λογότυπο GitHub wikipedia: title: Σύνδεση με Wikipedia - alt: Συνδεθείτε με λογαριασμό Wikipedia + alt: Λογότυπο Wikipedia oauth: authorize: title: Επιτρέψτε την πρόσβαση στο λογαριασμό σας @@ -2714,7 +2730,12 @@ el: write_notes: Τροποποίηση σημειώσεων write_redactions: Αφαίρεση και απόκρυψη δεδομένων χάρτη read_email: Διαβάζει τη διεύθυνση email χρήστη + consume_messages: Ανάγνωση, ενημέρωση της κατάστασης και διαγραφή των μηνυμάτων + χρήστη + send_messages: Αποστολή προσωπικών μηνυμάτων σε άλλους χρήστες. skip_authorization: Αυτόματη έγκριση εφαρμογής + for_roles: + moderator: Αυτή η άδεια είναι για ενέργειες διαθέσιμες μόνο στους διαχειριστές oauth_clients: new: title: Καταχώρηση νέας εφαρμογής @@ -2825,18 +2846,27 @@ el: το διορθώσει, να ενημερώσει, να το κατεβάσει και να το χρησιμοποιήσει. paragraph_2: Εγγραφείτε για να ξεκινήσετε να συνεισφέρετε. welcome: Καλώς ήλθατε στο OpenStreetMap + duplicate_social_email: Εάν έχετε ήδη λογαριασμό OpenStreetMap και επιθυμείτε + να χρησιμοποιείτε έναν πάροχο ταυτότητας τρίτου μέρους, παρακαλούμε να συνδεθείτε + χρησιμοποιώντας τον κωδικό πρόσβασής σας και να τροποποιήσετε τις ρυθμίσεις + του λογαριασμού σας. display name description: Το δημόσια εμφανιζόμενο όνομα χρήστη. Μπορείτε να το αλλάξετε αργότερα από τις προτιμήσεις. by_signing_up: + html: Με την εγγραφή σας, συμφωνείτε στους %{tou_link}, στην %{privacy_policy_link} + και στους %{contributor_terms_link}. privacy_policy: πολιτική απορρήτου privacy_policy_title: Πολιτική απορρήτου OSMF, συμπεριλαμβανομένης της ενότητας για τις διευθύνσεις ηλεκτρονικού ταχυδρομείου contributor_terms: όρους συνεισφοράς - tou: όροι χρήσης + tou: όρους χρήσης external auth: 'Έλεγχος ταυτότητας από τρίτο μέρος:' continue: Εγγραφή terms accepted: Ευχαριστούμε για την αποδοχή των νέων όρων συνεισφοράς! email_help: + privacy_policy: πολιτική απορρήτου + privacy_policy_title: Πολιτική απορρήτου OSMF, συμπεριλαμβανομένης της ενότητας + για τις διευθύνσεις ηλεκτρονικού ταχυδρομείου html: Η διεύθυνσή σας δεν εμφανίζεται δημόσια, ανατρέξτε στην %{privacy_policy_link} για περισσότερες πληροφορίες. consider_pd_html: Θεωρώ τις συνεισφορές μου να είναι στο %{consider_pd_link}. @@ -3027,7 +3057,6 @@ el: show: Προβολή αυτής της φραγής back: Προβολή όλων των φραγών filter: - block_expired: Η φραγή έχει ήδη λήξει και δεν μπορεί να αλλάξει. block_period: Η περίοδος φραγής πρέπει να είναι μία από τις τιμές στην πτυσσόμενη λίστα. create: @@ -3035,6 +3064,8 @@ el: update: only_creator_can_edit: Μόνο ο συντονιστής που δημιούργησε αυτήν τη φραγή μπορεί να την επεξεργαστεί. + only_creator_or_revoker_can_edit: Μόνο οι διαχειριστές που δημιούργησαν ή ανακαλέσαν + αυτή τη φραγή μπορούν να την επεξεργαστούν. success: Η φραγή ενημερώθηκε. index: title: Φραγές χρήστη @@ -3217,7 +3248,7 @@ el: custom_dimensions: Ορισμός προσαρμοσμένων διαστάσεων format: 'Μορφή:' scale: 'Κλίμακα:' - image_dimensions: Η εικόνα θα εμφανίζει το τυπικό στρώμα στο %{width} x %{height} + image_dimensions: Η εικόνα θα εμφανίζει το %{layer} στο %{width} x %{height} download: Λήψη short_url: Σύντομος Σύνδεμος include_marker: Συμπερίληψη δείκτη diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index 9850467f2..73e8191bd 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -1936,7 +1936,6 @@ en-GB: show: View this block back: View all blocks filter: - block_expired: The block has already expired and cannot be edited. block_period: The blocking period must be one of the values selectable in the drop-down list. create: diff --git a/config/locales/en.yml b/config/locales/en.yml index 2b83fec1f..a69416337 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1586,6 +1586,7 @@ en: tou: "Terms of Use" osm_offline: "The OpenStreetMap database is currently offline while essential database maintenance work is carried out." osm_read_only: "The OpenStreetMap database is currently in read-only mode while essential database maintenance work is carried out." + nothing_to_preview: "Nothing to preview." donate: "Support OpenStreetMap by %{link} to the Hardware Upgrade Fund." help: Help about: About @@ -1626,11 +1627,14 @@ en: befriend_them: "You can also add them as a friend at %{befriendurl}." befriend_them_html: "You can also add them as a friend at %{befriendurl}." gpx_description: + description_with_tags: "It looks like your GPX file %{trace_name} with the description %{trace_description} and the following tags: %{tags}" description_with_tags_html: "It looks like your GPX file %{trace_name} with the description %{trace_description} and the following tags: %{tags}" + description_with_no_tags: "It looks like your GPX file %{trace_name} with the description %{trace_description} and no tags" description_with_no_tags_html: "It looks like your GPX file %{trace_name} with the description %{trace_description} and no tags" gpx_failure: hi: "Hi %{to_user}," failed_to_import: "failed to import. Here is the error:" + more_info: "More information about GPX import failures and how to avoid them can be found at %{url}." more_info_html: "More information about GPX import failures and how to avoid them can be found at %{url}." import_failures_url: "https://wiki.openstreetmap.org/wiki/GPX_Import_Failures" subject: "[OpenStreetMap] GPX Import failure" @@ -1639,6 +1643,8 @@ en: loaded: one: "loaded successfully with %{trace_points} out of a possible %{count} point." other: "loaded successfully with %{trace_points} out of a possible %{count} points." + trace_location: "Your trace is available at %{trace_url}" + all_your_traces: "All your successfully uploaded GPX traces can be found at %{url}" all_your_traces_html: "All your successfully uploaded GPX traces can be found at %{url}." subject: "[OpenStreetMap] GPX Import success" signup_confirm: @@ -2641,6 +2647,8 @@ en: write_notes: Modify notes write_redactions: Redact map data read_email: Read user email address + consume_messages: Read, update status and delete user messages + send_messages: Send private messages to other users skip_authorization: Auto approve application for_roles: moderator: This permission is for actions available only to moderators @@ -2940,6 +2948,7 @@ en: flash: "Created a block on user %{name}." update: only_creator_can_edit: "Only the moderator who created this block can edit it." + only_creator_or_revoker_can_edit: "Only the moderators who created or revoked this block can edit it." success: "Block updated." index: title: "User blocks" diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 8c509274a..66296e847 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -1631,6 +1631,7 @@ eo: laboroj de prizorgado. osm_read_only: La OpenStreetMap-datumbazo estas nuntempe nurlega pro necesaj laboroj de prizorgado. + nothing_to_preview: Nenio por antaÅ­vidi. donate: Subteni OpenStreetMap %{link} al fonduso por modernigi aparataron. help: Helpo about: Pri @@ -1678,13 +1679,18 @@ eo: befriend_them: Vi ankaÅ­ povas aldoni vin kiel amikon ĉe %{befriendurl}. befriend_them_html: Vi ankaÅ­ povas aldoni ilin kiel amiko ĉe %{befriendurl} gpx_description: + description_with_tags: 'Ŝajnas, ke tio ĉi estas via GPX‑dosiero %{trace_name} + kun la priskribo %{trace_description} kaj kun la jenaj etikedoj: %{tags}' description_with_tags_html: 'Ŝajnas, ke tio ĉi estas via GPX‑dosiero %{trace_name} kun la priskribo %{trace_description} kaj kun la jenaj etikedoj: %{tags}' + description_with_no_tags: Ŝajnas, ke tio ĉi estas via GPX‑dosiero %{trace_name} + kun la priskribo %{trace_description} kaj sen etikedoj description_with_no_tags_html: Ŝajnas, ke tio ĉi estas via GPX‑dosiero %{trace_name} kun la priskribo %{trace_description} kaj sen etikedoj gpx_failure: hi: Saluton %{to_user}, failed_to_import: 'ne estas enportita sukcese. Eraro:' + more_info: Pliaj informoj pri eraroj dum enporti GPX‑dosierojn troviĝas ĉe %{url}. more_info_html: Pliaj informoj pri eraroj dum enporti GPX‑dosierojn troviĝas ĉe %{url}. subject: '[OpenStreetMap] Eraro dum enportado de GPX-dosiero' @@ -1693,6 +1699,8 @@ eo: loaded: one: estas sukcese enlegita kun %{trace_points} el ebla %{count} punkto. other: estas sukcese enlegita kun %{trace_points} el eblaj %{count} punktoj. + trace_location: Via spuro estas disponebla ĉe %{trace_url} + all_your_traces: Ĉiuj viaj sukcese alŝutitaj GPX-spuroj troveblas ĉe %{url} all_your_traces_html: Ĉiuj viaj sukcese alŝutitaj GPX-spuroj troveblas ĉe %{url}. subject: '[OpenStreetMap] GPX-dosiero enportita sukcese' signup_confirm: @@ -2660,6 +2668,8 @@ eo: write_notes: modifi rimarkojn write_redactions: Redakti map-datumojn read_email: legi retpoŝtan adreson de uzanto + consume_messages: legi, ŝanĝi staton kaj forigi mesaĝojn de uzanto + send_messages: sendi privatajn mesaĝojn al aliaj uzantoj skip_authorization: AÅ­tomate akcepti aplikaĵojn for_roles: moderator: Tiu ĉi permeso estas por agoj disponeblaj nur por kontrolantoj @@ -2973,13 +2983,14 @@ eo: show: Montri ĉi tiun blokadon back: Montri ĉiujn blokadojn filter: - block_expired: Ĉi tiu blokado malvalidiĝis kaj neredakteblas. block_period: La periodo de blokado estu unu el la valoroj elektitaj el la fallisto. create: flash: Kreis blokon por uzanto %{name}. update: only_creator_can_edit: Nur la kontrolanto kiu kreis ĉi tiun blokadon, povas redakti ĝin. + only_creator_or_revoker_can_edit: Nur la kontrolantoj, kiuj kreis aÅ­ nuligis + tiun ĉi blokadon povas redakti ĝin. success: Blokado ĝisdatigita. index: title: Blokadoj de uzanto @@ -3158,14 +3169,15 @@ eo: custom_dimensions: Agordi proprajn dimensiojn format: 'Dosiertipo:' scale: 'Skalo:' - image_dimensions: Bildo montros la norman tavolon je distingivo %{width}×%{height} + image_dimensions: Bildo montros la tavolon “%{layer}” je distingivo %{width}×%{height} download: Elŝuti short_url: Mallonga retadreso include_marker: Inkludi markon center_marker: Centrigi mapon al marko paste_html: Engluu HTML-kodon al via retpaĝo view_larger_map: Vidi pli grandan mapon - only_standard_layer: Nur la norma tavolo de mapo elporteblas kiel bildon + only_standard_layer: Nur la tavoloj Norma, Biciklada kaj Transporta estas elporteblaj + kiel bildoj embed: report_problem: Raporti problemon key: diff --git a/config/locales/es.yml b/config/locales/es.yml index 5d29738cf..1d096a5d4 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -28,6 +28,7 @@ # Author: Dgstranz # Author: Egofer # Author: Ejegg +# Author: EmicraftNoob # Author: Eulalio # Author: Fitoschido # Author: Fortega @@ -104,7 +105,7 @@ es: time: formats: - friendly: '%e de %B de %Y a las %H:%M' + friendly: '%e %B %Y a las %H:%M' helpers: file: prompt: Seleccionar archivo @@ -2809,6 +2810,7 @@ es: write_notes: Modifica notas write_redactions: Censurar datos del mapa read_email: Leer dirección de correo electrónico del usuario + send_messages: Enviar mensajes privados a otros usuarios skip_authorization: Auto aprobar aplicación for_roles: moderator: Este permiso es para acciones disponibles solo para moderadores. @@ -3134,13 +3136,14 @@ es: show: Ver este bloqueo back: Ver todos los bloqueos filter: - block_expired: Este bloqueo ya ha expirado y no puede ser editado. block_period: El periodo de bloqueo debe de ser uno de los valores seleccionables de la lista desplegable. create: flash: Has creado un bloqueo en el usuario %{name}. update: only_creator_can_edit: Sólo el moderador que ha creado este bloqueo puede editarlo. + only_creator_or_revoker_can_edit: Solo los moderadores que han creado o revocado + este bloqueo pueden editarlo. success: Bloqueo actualizado. index: title: Bloqueos de usuario @@ -3322,14 +3325,15 @@ es: custom_dimensions: Establecer dimensiones personalizadas format: 'Formato:' scale: 'Escala:' - image_dimensions: La imagen mostrará la capa estándar en %{width} x %{height} + image_dimensions: La imagen mostrará la capa %{layer} en %{width} x %{height} download: Descargar short_url: URL corta include_marker: Incluir marcador center_marker: Centrar mapa en el marcador paste_html: Pegar código HTML para incrustar en el sitio web view_larger_map: Ver el mapa más grande - only_standard_layer: Sólo la capa estándar se puede exportar como una imagen + only_standard_layer: Sólo las capas Estándar, Mapa Ciclista y Transporte pueden + exportarse como una imagen embed: report_problem: Reportar un problema key: diff --git a/config/locales/et.yml b/config/locales/et.yml index 36bfb88ec..46660b444 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -2853,7 +2853,6 @@ et: show: Vaata seda blokeeringut back: Vaata kõiki blokeeringuid filter: - block_expired: Blokeering on juba aegunud ja seda ei saa muuta. block_period: Blokeeringu ajavahemik peab olema üks valitav rippmenüü loendi väärtus. create: diff --git a/config/locales/eu.yml b/config/locales/eu.yml index cbf41d0e0..d8ca1f5b1 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -2800,7 +2800,6 @@ eu: show: Ikusi bloke hau back: Ikusi bloke guztiak filter: - block_expired: Blokea dagoeneko iraungi da eta ezin da editatu. block_period: Blokeoaren iraupena goitibeherako zerrendan hautatutako balioetariko bat izan behar da. create: diff --git a/config/locales/fa.yml b/config/locales/fa.yml index cf92d804e..bf6b5ec3f 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -2544,7 +2544,6 @@ fa: show: دیدن این مسدودی back: دیدن تمام مسدودی‌ها filter: - block_expired: مسدودی قبلاً منقضی شده و قابل ویرایش نیست. block_period: دورهٔ مسدودی باید یکی از مقدارهای قابل انتخاب در لیست بازشو باشد. create: flash: یک مسدودی روی کاربری %{name} ایجاد شد. diff --git a/config/locales/fi.yml b/config/locales/fi.yml index ee10ca3b7..5e49f8ab8 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -2731,7 +2731,6 @@ fi: show: Näytä tämä esto back: Näytä kaikki estot filter: - block_expired: Esto on jo vanhentunut, eikä sitä voi muokata. block_period: Eston ajanjakson täytyy olla yksi pudotusvalikossa olevista arvoista. create: flash: Estettiin käyttäjä %{name} diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 454b685ea..ab1c14f2b 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -69,6 +69,7 @@ # Author: Metroitendo # Author: Momo50WM # Author: Mulcyber +# Author: Méthodes Bulebe Hangi # Author: Nemo bis # Author: Nicolapps # Author: Niridya @@ -116,7 +117,7 @@ fr: dir: ltr time: formats: - friendly: '%e %B %Y à %H%M' + friendly: '%e %B %Y à %-H h %M' blog: '%e %B %Y' helpers: file: @@ -138,8 +139,8 @@ fr: create: S’inscrire update: Mettre à jour redaction: - create: Créer la censure - update: Enregistrer la censure + create: Créer le masquage + update: Enregistrer le masquage trace: create: Téléverser update: Enregistrer les modifications @@ -162,7 +163,7 @@ fr: changeset_tag: Attribut du groupe de modifications country: Pays diary_comment: Commentaire du journal - diary_entry: Entrée d’agenda + diary_entry: Entrée du journal friend: Ami(e) issue: Problème language: Langue @@ -199,7 +200,7 @@ fr: support_url: URL de l’assistance allow_read_prefs: lire les préférences de l’utilisateur allow_write_prefs: modifier les préférences de l’utilisateur - allow_write_diary: créer des entrées de carnet, des commentaires et des liens + allow_write_diary: créer des entrées du journal, des commentaires et des liens d’amitié allow_write_api: modifier la carte allow_read_gpx: lire ses traces GPS privées @@ -251,7 +252,7 @@ fr: email: Courriel new_email: Nouvelle adresse de courriel active: Actif - display_name: Afficher le nom + display_name: Pseudonyme description: Description du profil home_lat: Latitude home_lon: Longitude @@ -347,7 +348,7 @@ fr: reopened_at_by_html: Réactivé à %{when} par %{user} rss: title: Notes OpenStreetMap - description_all: Une liste de notes rapportées, commentées ou fermées + description_all: Une liste de notes signalées, commentées ou fermées description_area: Une liste de notes, signalées, commentées ou fermées dans votre zone [(%{min_lat} ; %{min_lon}) – (%{max_lat} ; %{max_lon})] description_item: Un flux RSS pour la note %{id} @@ -369,7 +370,7 @@ fr: utilisant le bouton ci-dessous. Veuillez prendre note des détails suivants :' delete_profile: Les informations de votre profil, y compris votre avatar, votre description et votre lieu de résidence seront supprimées. - delete_display_name: Votre nom affiché sera supprimé et pourra être réutilisé + delete_display_name: Votre pseudonyme sera supprimé et pourra être réutilisé pour d’autres comptes. retain_caveats: 'Cependant, quelques informations vous concernant seront conservées sur OpenStreetMap, même après la suppression de votre compte :' @@ -396,12 +397,12 @@ fr: external auth: Authentification externe openid: link: https://wiki.openstreetmap.org/wiki/FR:OpenID - link text: qu’est-ce que cela ? + link text: qu’est-ce ? public editing: heading: Modification publique enabled: Activée. Non anonyme et peut modifier les données. enabled link: https://wiki.openstreetmap.org/wiki/FR:Modifications_anonymes - enabled link text: qu’est-ce que ceci ? + enabled link text: qu’est-ce ? disabled: Désactivée et ne peut pas modifier les données ; toutes les précédentes modifications sont anonymes. disabled link text: pourquoi ne puis-je pas modifier ? @@ -415,9 +416,9 @@ fr: agreed_with_pd: Vous avez également déclaré que vous considérez vos modifications comme relevant du domaine public. link: https://wiki.osmfoundation.org/wiki/Licence/Contributor_Terms/FR - link text: qu’est-ce que ceci ? + link text: qu’est-ce ? save changes button: Enregistrer les modifications - delete_account: Supprimer le compte... + delete_account: Supprimer le compte… go_public: heading: Modification publique currently_not_public: Actuellement, vos modifications sont anonymes et les utilisateurs @@ -458,10 +459,10 @@ fr: other: '%{count} chemins' download_xml: Télécharger en XML view_history: Voir l’historique - view_unredacted_history: Voir l'historique non censuré + view_unredacted_history: Voir l'historique non masqué view_details: Afficher les détails - view_redacted_data: Afficher les données censurées - view_redaction_message: Afficher le message de rédaction + view_redacted_data: Afficher les données masquées + view_redaction_message: Afficher le message de masquage location: 'Emplacement :' common_details: coordinates_html: '%{latitude} ; %{longitude}' @@ -506,8 +507,8 @@ fr: note: note timeout: title: Erreur de dépassement du délai d’attente - sorry: Désolé, les données pour l’objet %{type} d’identifiant %{id} ont mis - trop de temps à être récupérées. + sorry: Désolé, obtenir les données pour l’objet %{type} d’identifiant %{id} + a pris trop de temps. type: node: nœud way: chemin @@ -527,7 +528,7 @@ fr: navigateur lent ou le bloquer. Êtes-vous sûr de vouloir afficher ces données ? load_data: Charger les données - loading: Chargement en cours... + loading: Chargement en cours… tag_details: tags: Attributs wiki_link: @@ -546,18 +547,18 @@ fr: enclosing: Objets englobants old_nodes: not_found: - sorry: 'Désolé, le nœud #%{id} version %{version} est introuvable.' + sorry: Désolé, la version %{version} du nœud %{id} est introuvable. old_ways: not_found: - sorry: 'Désolé, la façon #%{id} version %{version} est introuvable.' + sorry: Désolé, la version %{version} du chemin %{id} est introuvable. old_relations: not_found: - sorry: 'Désolé, la relation #%{id} version %{version} est introuvable.' + sorry: Désolé, la version %{version} de la relation %{id} est introuvable. changesets: changeset_paging_nav: showing_page: Page %{page} - next: Suivant ▸ - previous: ◂ Précédent + next: Suivant › + previous: ‹ Précédent changeset: anonymous: Anonyme no_edits: (aucune modification) @@ -588,10 +589,10 @@ fr: closed: Fermé belongs_to: Auteur subscribe: - heading: S'abonner à la discussion sur l'ensemble de modifications suivante ? - button: S'abonner à la discussion + heading: S’abonner à la discussion sur l’ensemble de modifications suivant ? + button: S’abonner à la discussion unsubscribe: - heading: Se désabonner de la discussion du groupe de modifications suivant ? + heading: Se désabonner de la discussion du groupe de modifications suivant ? button: Se désinscrire de la discussion heading: title: Groupe de modifications %{id} @@ -599,9 +600,8 @@ fr: no_such_entry: title: Aucun ensemble de modifications de ce type heading: 'Aucune entrée avec l’identifiant : %{id}' - body: Désolé, il n’y a aucun groupe de modifications avec l'identifiant %{id}. - Veuillez vérifier l'orthographe ou la validité du lien sur lequel vous avez - cliqué. + body: Désolé, il n’y a aucun groupe de modifications avec l’identifiant %{id}. + Peut-être avez-vous fait une erreur en le recopiant ou suivi un lien erroné ? show: title: 'Groupe de modifications : %{id}' created: 'Créé : %{when}' @@ -617,7 +617,7 @@ fr: subscribe: S’abonner unsubscribe: Se désabonner comment_by_html: Commentaire de %{user} %{time_ago} - hidden_comment_by_html: Commentaire caché de %{user} %{time_ago} + hidden_comment_by_html: Commentaire masqué de %{user} %{time_ago} hide_comment: masquer unhide_comment: démasquer comment: Commenter @@ -631,22 +631,22 @@ fr: relations: Relations (%{count}) relations_paginated: Relations (%{x} à %{y} sur %{count}) timeout: - sorry: Désolé, la liste des groupes de modifications que vous avez demandée - a mis trop de temps à récupérer. + sorry: Désolé, récupérer la liste des groupes de modifications que vous avez + demandée a pris trop de temps. changeset_comments: comment: comment: Nouveau commentaire sur le groupe de modifications nº %{changeset_id} par %{author} commented_at_by_html: Mis à jour le %{when} par %{user} comments: - comment: Nouveau commentaire sur le groupe de modifications nº %{changeset_id} + comment: Nouveau commentaire sur le groupe de modifications %{changeset_id} par %{author} index: title_all: Discussion sur le groupe de modifications OpenStreetMap - title_particular: Discussion sur le groupe de modifications OpenStreetMap nº %{changeset_id} + title_particular: Discussion sur le groupe de modifications OpenStreetMap %{changeset_id} timeout: - sorry: Désolé, la liste des commentaires d’ensembles de modifications que vous - avez demandée est trop longue à récupérer. + sorry: Désolé, récupérer les commentaires du groupe de modifications que vous + avez demandés a pris trop de temps. dashboards: contact: km away: à %{count} km @@ -660,7 +660,7 @@ fr: title: Mon tableau de bord no_home_location_html: '%{edit_profile_link} et définissez l’emplacement de votre domicile pour voir les utilisateurs à proximité.' - edit_your_profile: Modifier votre profil + edit_your_profile: Modifiez votre profil my friends: Mes amis no friends: Vous n’avez encore ajouté aucun ami. nearby users: Autres utilisateurs à proximité @@ -680,12 +680,12 @@ fr: title: Journaux des utilisateurs title_friends: Journaux des amis title_nearby: Journaux des utilisateurs à proximité - user_title: Carnet de %{user} - in_language_title: Entrées du carnet en %{language} + user_title: Journal de %{user} + in_language_title: Entrées du journal en %{language} new: Nouvelle entrée du journal new_title: Écrire une nouvelle entrée dans mon journal utilisateur my_diary: Mon journal - no_entries: Aucune entrée de carnet + no_entries: Aucune entrée de journal recent_entries: Entrées récentes du journal older_entries: Entrées plus anciennes newer_entries: Entrées plus récentes @@ -693,8 +693,8 @@ fr: title: Modifier l’entrée du journal marker_text: Emplacement de l’entrée du journal show: - title: Carnet de %{user} | %{title} - user_title: Carnet de %{user} + title: Journal de %{user} | %{title} + user_title: Journal de %{user} discussion: Discussion subscribe: S’abonner unsubscribe: Se désabonner @@ -702,11 +702,11 @@ fr: login_to_leave_a_comment_html: '%{login_link} pour laisser un commentaire' login: Se connecter no_such_entry: - title: Aucune entrée de carnet correspondante + title: Aucune entrée de journal correspondante heading: 'Aucune entrée avec l’identifiant : %{id}' - body: Désolé, il n’y a aucune entrée ni commentaire de carnet avec l’identifiant - %{id}. Veuillez vérifier votre orthographe ou la validité du lien que vous - avez cliqué. + body: Désolé, il n’y a aucune entrée ni commentaire de journal avec l’identifiant + %{id}. Peut-être avez-vous fait une erreur en le recopiant ou suivi un lien + erroné ? diary_entry: posted_by_html: Publié par %{link_user} le %{created} en %{language_link}. updated_at_html: Dernière mise à jour le %{updated}. @@ -738,8 +738,8 @@ fr: description: Entrées récentes du journal OpenStreetMap de %{user} language: title: Entrées du journal OpenStreetMap en %{language_name} - description: Entrées récentes des carnets d’utilisateurs d’OpenStreetMap en - %{language_name} + description: Entrées récentes des journaux d’utilisateurs d’OpenStreetMap + en %{language_name} all: title: Entrées des journaux OpenStreetMap description: Entrées récentes des journaux d’utilisateurs de OpenStreetMap @@ -760,6 +760,8 @@ fr: comment: Commentaire newer_comments: Commentaires plus récents older_comments: Commentaires plus anciens + new: + heading: Ajouter un commentaire à cette discussion ? doorkeeper: errors: messages: @@ -945,7 +947,7 @@ fr: prison: Prison pub: Pub public_bath: Bains publics - public_bookcase: Bibliothèque publique + public_bookcase: Microbibliothèque public_building: Bâtiment public ranger_station: Poste de garde forestière recycling: Point de recyclage @@ -1755,6 +1757,7 @@ fr: maintenance essentielle à son bon fonctionnement est en cours. osm_read_only: La base de données OpenStreetMap est actuellement en mode lecture seule ; une maintenance essentielle à son bon fonctionnement est en cours. + nothing_to_preview: Rien à voir en avant. donate: Soutenez OpenStreetMap, %{link} au fonds de mise à niveau du matériel. help: Aide about: À propos @@ -1805,13 +1808,19 @@ fr: befriend_them: 'Vous pouvez également l’ajouter comme ami(e) ici : %{befriendurl}.' befriend_them_html: Vous pouvez aussi l’ajouter comme ami à l’adresse %{befriendurl}. gpx_description: + description_with_tags: Il semble que votre fichier GPX « %{trace_name} » avec + la description « %{trace_description} » et les balises « %{tags} » description_with_tags_html: Il semble que votre fichier GPX « %{trace_name} » avec la description « %{trace_description} » et les balises « %{tags} » + description_with_no_tags: Il semble que votre fichier GPX « %{trace_name} » + avec la description « %{trace_description} » et sans balise description_with_no_tags_html: Il semble que votre fichier GPX « %{trace_name} » avec la description « %{trace_description} » et sans balise gpx_failure: hi: Bonjour %{to_user}, failed_to_import: 'n’a pas pu être importé. Voici l’erreur :' + more_info: Vous trouverez plus d’informations sur les échecs d’import GPX et + comment les éviter à l’adresse %{url}. more_info_html: Vous trouverez plus d’informations sur les échecs d’import GPX et comment les éviter à l’adresse %{url}. import_failures_url: https://wiki.openstreetmap.org/wiki/GPX#Troubleshooting @@ -1822,6 +1831,8 @@ fr: one: s’est chargé correctement avec %{trace_points} dd %{count} point possible. other: s’est chargé correctement avec %{trace_points} des %{count} points possibles. + all_your_traces: Toutes vos traces de GPX téléversées avec succès peuvent être + trouvées à %{url}. all_your_traces_html: Toutes vos traces de GPX téléversées avec succès peuvent être trouvées à %{url}. subject: '[OpenStreetMap] Import GPX réussi' @@ -2671,6 +2682,7 @@ fr: Il n’est pas nécessaire d’établir formellement un groupe dans la même mesure que les chapitres locaux. En effet, de nombreux groupes existent avec beaucoup de succès en tant que rassemblement informel de personnes ou en tant que groupe communautaire. Chacun peut en créer ou en rejoindre un. En savoir plus sur la %{communities_wiki_link}. communities_wiki: page wiki des communautés + communities_wiki_url: https://wiki.openstreetmap.org/wiki/FR:User_group traces: visibility: private: Privé (partagé anonymement, points non ordonnés) @@ -2806,6 +2818,7 @@ fr: oauth2_authorizations: Droits OAuth 2 muted_users: Utilisateurs silencieux auth_providers: + openid_url: URL OpenID openid_login_button: Continuer openid: title: Connexion avec OpenID @@ -2835,7 +2848,7 @@ fr: allow_to: 'Autoriser l’application cliente à :' allow_read_prefs: lire vos préférences utilisateur ; allow_write_prefs: modifier vos préférences utilisateur ; - allow_write_diary: créer des entrées dans votre carnet, faire des commentaires + allow_write_diary: créer des entrées dans votre journal, faire des commentaires et ajouter des ami(e)s ; allow_write_api: modifier la carte. allow_read_gpx: lire vos traces GPS privées ; @@ -2867,6 +2880,8 @@ fr: write_notes: Modifier les notes write_redactions: Caviarder les données cartographiques read_email: Lire l’adresse courriel de l’utilisateur + consume_messages: Lire, modifier l’état et supprimer les messages de l’utilisateur + send_messages: Envoyer des messages privés à d’autres utilisateurs skip_authorization: Demande d’approbation automatique for_roles: moderator: Cette autorisation concerne les actions disponibles uniquement pour @@ -3069,7 +3084,7 @@ fr: destroy_mute: Réactiver le son de cet utilisateur edit_profile: Modifier le profil send message: Envoyer un message - diary: Carnet + diary: Journal edits: Modifications traces: Traces notes: Notes de carte @@ -3195,13 +3210,14 @@ fr: show: Afficher ce blocage back: Voir tous les blocages filter: - block_expired: Le blocage a déjà expiré et ne peut pas être modifié. block_period: La période de blocage doit être choisie dans la liste déroulante. create: flash: Blocage créé sur l’utilisateur « %{name} ». update: only_creator_can_edit: Seul le modérateur ou la modératrice qui a créé ce blocage peut le modifier. + only_creator_or_revoker_can_edit: Seuls les modérateurs ayant créé ou annulé + ce blocage peuvent le modifier. success: Blocage mis à jour. index: title: Blocages d’utilisateur @@ -3392,7 +3408,8 @@ fr: center_marker: Centrer la carte sur le marqueur paste_html: Coller le HTML à inclure dans le site web view_larger_map: Afficher une carte plus grande - only_standard_layer: Seule la couche standard peut être exportée comme une image + only_standard_layer: Seule les couche « Standard », « Carte cyclable » et « Carte + de transport » peuvent être exportées comme une image embed: report_problem: Signaler un problème key: diff --git a/config/locales/fy.yml b/config/locales/fy.yml index a8a7d2022..1618ea66b 100644 --- a/config/locales/fy.yml +++ b/config/locales/fy.yml @@ -2479,7 +2479,6 @@ fy: show: Dizze útsluting besjen back: Alle útslutings besjen filter: - block_expired: De útsluting is al ferrûn en kin net bewurke wurde. block_period: De útslutingsdoer moat ien fan 'e wearden yn 'e útklapbere karlist wêze. create: diff --git a/config/locales/gd.yml b/config/locales/gd.yml index a60901e37..521eeb0a8 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -1735,8 +1735,6 @@ gd: show: Seall am bacadh seo back: Seall a h-uile bacadh filter: - block_expired: Dh'fhalbh an ùine air a' bhacadh seo mar-thà is cha ghabh a dheasachadh - tuilleadh. block_period: Feumaidh eadaramh a' bhacaidh a bhith 'na aon dhe na luachan a ghabhas taghadh air an liosta-theàrnaidh. create: diff --git a/config/locales/gl.yml b/config/locales/gl.yml index c68587eab..49a80694e 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -418,10 +418,9 @@ gl: relation: relación start_rjs: feature_warning: Cargando %{num_features} funcións, que poden facer que o teu - navegador sexa lento ou non responda. Estás seguro de que queres mostrar estes - datos? + navegador sexa lento ou non responda. Queres mostrar estes datos? load_data: Cargar os datos - loading: Estase a carregar... + loading: Cargando... tag_details: tags: Etiquetas wiki_link: @@ -655,7 +654,7 @@ gl: newer_comments: Comentarios máis recentes older_comments: Comentarios máis vellos new: - heading: Queres engadir un comentario á seguinte discusión sobre a entrada do + heading: Queres engadir un comentario á seguinte conversa sobre a entrada no diario? doorkeeper: errors: @@ -865,7 +864,7 @@ gl: veterinary: Clínica veterinaria village_hall: Concello waste_basket: Cesto do lixo - waste_disposal: Contedor de lixo + waste_disposal: Colector do lixo waste_dump_site: Lugar de vertedoiro de lixo watering_place: Bebedoiro para animais water_point: Punto de auga @@ -1645,6 +1644,7 @@ gl: traballos de mantemento nela. osm_read_only: A base de datos do OpenStreetMap atópase en modo de só lectura mentres realizamos traballos de mantemento nela. + nothing_to_preview: Non hai nada que previsualizar. donate: Apoie o OpenStreetMap %{link} ao fondo de actualización de hardware. help: Axuda about: Acerca de @@ -1693,13 +1693,19 @@ gl: befriend_them: Tamén pode engadilo coma amizade no %{befriendurl}. befriend_them_html: Tamén podes engadilo como amizade no %{befriendurl}. gpx_description: + description_with_tags: 'Parece o teu ficheiro GPX %{trace_name} coa descrición + %{trace_description} e as seguintes etiquetas: %{tags}' description_with_tags_html: 'Parece o teu ficheiro GPX %{trace_name} coa descrición %{trace_description} e as seguintes etiquetas: %{tags}' + description_with_no_tags: Parece o teu ficheiro GPX %{trace_name} coa descrición + %{trace_description} e sen etiquetas description_with_no_tags_html: Parece o teu ficheiro GPX %{trace_name} coa descrición %{trace_description} e sen etiquetas gpx_failure: hi: 'Ola %{to_user}:' failed_to_import: 'erro ao importar. Velaquí atópase o erro:' + more_info: Máis información sobre os erros de importación de GPX e como evitalos + en %{url}. more_info_html: Máis información sobre os erros de importación de GPX e como evitalos en %{url}. subject: '[OpenStreetMap] Importación GPX errónea' @@ -1710,6 +1716,8 @@ gl: posible. other: cargouse correctamente con %{trace_points} de entre %{count} puntos posibles. + trace_location: A túa pista está dispoñible en %{trace_url} + all_your_traces: Podes atopar todas as pistas GPX que subiches en %{url} all_your_traces_html: Podes atopar todas as pistas GPX que subiches en %{url}. subject: '[OpenStreetMap] Importación GPX correcta' signup_confirm: @@ -2728,6 +2736,8 @@ gl: write_notes: Modificar notas write_redactions: Censurar datos do mapa read_email: Ver os enderezos de correo electrónico dos usuarios + consume_messages: Ver, actualizar o estado e borrar mensaxes dos usuarios + send_messages: Enviar mensaxes privadas aos usuarios skip_authorization: Aprobar automaticamente aplicacións for_roles: moderator: Estes permisos son para as accións dispoñibles unicamente para os @@ -3047,13 +3057,14 @@ gl: show: Ollar este bloqueo back: Ollar tódolos bloqueos filter: - block_expired: O bloqueo xa caducou. Non se pode editar. block_period: O período de bloqueo debe elixirse de entre os valores presentes na listaxe despregábel. create: flash: Bloqueo creado para o usuario %{name}. update: only_creator_can_edit: Só o moderador que creou o bloqueo pode editalo. + only_creator_or_revoker_can_edit: Só os moderadores que crearon ou revogaron + o bloqueo poden editalo. success: Bloqueo actualizado. index: title: Bloqueos de usuario @@ -3235,14 +3246,15 @@ gl: custom_dimensions: Estabelecer dimensións personalizadas format: 'Formato:' scale: 'Escala:' - image_dimensions: A imaxe amosará a capa estándar con %{width} x %{height} + image_dimensions: A imaxe amosará a capa %{layer} con %{width} x %{height} download: Baixar short_url: Enderezo URL curto include_marker: Incluí-lo marcador center_marker: Centrar o mapa no marcador paste_html: Pegue o código HTML para incluílo na páxina web view_larger_map: Ollar un mapa máis grande - only_standard_layer: Só a capa estándar pode exportarse coma unha imaxe + only_standard_layer: Só as capas estándar, ciclista e transporte poden exportarse + coma unha imaxe embed: report_problem: Denunciar un problema key: @@ -3263,7 +3275,7 @@ gl: other: Estás a menos de %{count} pés deste punto base: standard: Estándar - cyclosm: CyclOSM (Ciclista) + cyclosm: CyclOSM cycle_map: Ciclista transport_map: Transporte tracestracktop_topo: Tracestrack Topo diff --git a/config/locales/gu.yml b/config/locales/gu.yml index 66ae5f02c..f42174086 100644 --- a/config/locales/gu.yml +++ b/config/locales/gu.yml @@ -878,7 +878,7 @@ gu: third: ત્રીજું fourth: ચોથું fifth: પાંચમું - sixth: છઠ્ઠુ + sixth: છઠ્ઠું seventh: સાતમું eighth: આઠમું ninth: નવમું diff --git a/config/locales/he.yml b/config/locales/he.yml index c47aa81af..aeff25109 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -1671,6 +1671,7 @@ he: המבוצעות בו. osm_read_only: מסד הנתונים של אתר OpenStreetMap נתון כעת במצב קריאה בלבד בשל עבודות תחזוקה המבוצעות בו. + nothing_to_preview: אין מה להראות בתצוגה מקדימה. donate: תִמכו ב־OpenStreetMap על־ידי %{link} לקרן לשדרוג החומרה. help: עזרה about: אודות @@ -1714,14 +1715,20 @@ he: befriend_them: באפשרותך לסמנו כחבר בכתובת %{befriendurl}. befriend_them_html: באפשרותך לסמנו כחבר בכתובת %{befriendurl}. gpx_description: - description_with_tags_html: 'נראה כי קובץ ה־GPX שלך %{trace_name} העונה לתיאור - %{trace_description} והתגיות הבאות: %{tags}' - description_with_no_tags_html: נראה כי קובץ ה־GPX שלך %{trace_name} העונה לתיאור - %{trace_description} וללא תגיות + description_with_tags: 'זה נראה כמו קובץ ה־GPX שלך %{trace_name} עם התיאור %{trace_description} + ועם התגים הבאים: %{tags}' + description_with_tags_html: 'זה נראה כמו קובץ ה־GPX שלך %{trace_name} עם התיאור + %{trace_description} ועם התגים הבאים: %{tags}' + description_with_no_tags: זה נראה כמו קובץ ה־GPX שלך %{trace_name} עם התיאור + %{trace_description} וללא תגים + description_with_no_tags_html: זה נראה כמו קובץ ה־GPX שלך %{trace_name} עם התיאור + %{trace_description} וללא תגים gpx_failure: hi: שלום %{to_user}, failed_to_import: 'לא יובא כראוי. הינה השגיאה:' - more_info_html: מידע על תקלות בייבוא GPX וכיצד להימנע מהן נמצא תחת %{url}. + more_info: מידע נוסף על תקלות ביבוא GPX ועל איך להימנע מהן נמצא בכתובת %{url}. + more_info_html: מידע נוסף על תקלות ביבוא GPX ועל איך להימנע מהן נמצא בכתובת + %{url}. subject: '[אופן סטריט מאפ OpenStreetMap] שגיאה בייבוא GPX' gpx_success: hi: שלום %{to_user}, @@ -1730,6 +1737,8 @@ he: two: נטען בהצלחה עם %{trace_points} נקודות מתוך %{count} נקודות אפשריות. many: נטען בהצלחה עם %{trace_points} נקודות מתוך %{count} נקודות אפשריות. other: נטען בהצלחה עם %{trace_points} נקודות מתוך %{count} נקודות אפשריות. + trace_location: ההקלטה שלך זמינה בכתובת %{trace_url} + all_your_traces: אפשר למצוא את כל הקלטות ה־GPX שלך בכתובת %{url} all_your_traces_html: אפשר למצוא את כל עקבות ה־GPX שלך שהועלו בהצלחה דרך %{url}. subject: '[אופן סטריט מאפ OpenStreetMap] ייבוא GPX הצליח' signup_confirm: @@ -2699,6 +2708,8 @@ he: write_notes: לשנות הערות write_redactions: שינוי נתוני המפה read_email: לקרוא את כתובת הדוא"ל של המשתמש + consume_messages: קריאה, עדכון מצב ומחיקה של הודעות משתמשים + send_messages: שליחת הודעה פרטית למשתמשים אחרים skip_authorization: לאשר את היישום אוטומטית for_roles: moderator: ההרשאה הזאת מיועדת לפעולות שזמינות רק למפקחים @@ -3003,12 +3014,13 @@ he: show: הצגת החסימה הזאת back: הצגת כל החסימות filter: - block_expired: החסימה כבר פקעה ואי־אפשר לערוך אותה. block_period: תקופת החסימה צריכה להיות אחד הערכים שאפשר לבחור ברשימה הנפתחת. create: flash: נוצרה חסימה על חשבון %{name} update: only_creator_can_edit: רק המפקח שיצר את החסימה הזאת יכול לערוך אותה. + only_creator_or_revoker_can_edit: רק המפקחים שיצרו או ביטלו את החסימה הזאת יכולים + לערוך אותה. success: החסימה עודכנה. index: title: חסימות משתמש diff --git a/config/locales/hr.yml b/config/locales/hr.yml index ef76c43a8..e2f4ef99d 100644 --- a/config/locales/hr.yml +++ b/config/locales/hr.yml @@ -1737,7 +1737,6 @@ hr: show: Prikaži ovu blokadu back: Prikaži sve blokade filter: - block_expired: Blokada je već istekla i ne može se uređivati. block_period: Period blokade mora biti jedna od vrijednosti iz padajuće liste. create: flash: Napravi blokadu na korisnika %{name}. diff --git a/config/locales/hsb.yml b/config/locales/hsb.yml index 9977b0942..78b9281f0 100644 --- a/config/locales/hsb.yml +++ b/config/locales/hsb.yml @@ -2573,7 +2573,6 @@ hsb: show: Tute blokowanje pokazać back: Wšě blokowanja pokazać filter: - block_expired: Blokowanje je hižo spadnjene a njeda so wobdźěłać. block_period: Doba blokowanja dyrbi jedna z hódnotow być, kotrež hodźa so z padaceho menija wubrać. create: diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 487a061ae..16273c5f0 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -2916,7 +2916,6 @@ hu: show: blokkolás megjelenítése back: Összes blokkolás megjelenítése filter: - block_expired: A blokkolás már lejárt, és nem szerkeszthető. block_period: A blokkolási időszaknak egy, a legördülő listából kiválasztható értéknek kell lennie. create: diff --git a/config/locales/ia.yml b/config/locales/ia.yml index 2599f2a54..cb72dcccb 100644 --- a/config/locales/ia.yml +++ b/config/locales/ia.yml @@ -4,6 +4,7 @@ # Author: Carlosedepaula # Author: Fanjiayi # Author: Julian Mendez +# Author: Karmwiki # Author: Macofe # Author: McDutchie # Author: Nemo bis @@ -2689,6 +2690,7 @@ ia: write_notes: Modificar notas write_redactions: Censurar datos del carta read_email: Leger le adresse de e-mail del usator + send_messages: Inviar messages private a altere usatores skip_authorization: Approbar automaticamente le application for_roles: moderator: Iste permission es pro actiones que es disponibile solmente al moderatores @@ -3004,7 +3006,6 @@ ia: show: Examinar iste blocada back: Examinar tote le blocadas filter: - block_expired: Le blocada ha ja expirate e non pote esser modificate. block_period: Le periodo de blocada debe esser un del valores seligibile in le lista disrolante. create: diff --git a/config/locales/id.yml b/config/locales/id.yml index b69f47e04..5b2636b83 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -1640,13 +1640,19 @@ id: befriend_them: Anda juga dapat menambahkannua sebagai teman di %{befriendurl}. befriend_them_html: Anda juga bisa menambahkan mereka sebagai teman di %{befriendurl}. gpx_description: + description_with_tags: 'Kelihatannya berkas GPX Anda %{trace_name} dengan deskripsi + %{trace_description} dan tag-tag berikut: %{tags}' description_with_tags_html: 'Kelihatannya berkas GPX Anda %{trace_name} dengan deskripsi %{trace_description} dan tag-tag berikut: %{tags}' + description_with_no_tags: Kelihatannya berkas GPX Anda %{trace_name} dengan + deskripsi %{trace_description} dan tanpa tag description_with_no_tags_html: Kelihatannya berkas GPX Anda %{trace_name} dengan deskripsi %{trace_description} dan tanpa tag gpx_failure: hi: Halo %{to_user}, failed_to_import: 'gagal melakukan impor. Berikut ini adalah kesalahannya:' + more_info: Informasi lebih lanjut tentang kegagalan impor GPX dan cara menghindarinya + bisa ditemukan di %{url}. more_info_html: Informasi lebih lanjut tentang kegagalan impor GPX dan cara menghindarinya bisa ditemukan di %{url}. subject: '[OpenStreetMap] gagal impor GPX' @@ -1654,6 +1660,9 @@ id: hi: Halo %{to_user}, loaded: other: berhasil dimuat dengan %{trace_points} dari %{count} titik yang mungkin. + trace_location: Trace Anda tersedia di %{trace_url} + all_your_traces: Semua jejak GPX Anda yang berhasil diunggah dapat ditemukan + di %{url}. all_your_traces_html: Semua jejak GPX Anda yang berhasil diunggah dapat ditemukan di %{url}. subject: '[OpenStreetMap] impor GPX sukses' @@ -2634,6 +2643,8 @@ id: write_notes: Ubah catatan write_redactions: Sunting data peta read_email: Baca alamat surel pengguna + consume_messages: Baca, update status dan hapus pesan pengguna + send_messages: Kirim pesan pribadi ke pengguna ini skip_authorization: Setujui aplikasi secara otomatis oauth_clients: new: @@ -2925,7 +2936,6 @@ id: show: Lihat blokir ini back: Lihat semua blokir filter: - block_expired: Blokir sudah kadaluwarsa dan tidak bisa diedit. block_period: Periode blokir harus merupakan salah satu nilai yang dapat dipilih dari daftar drop-down atau pilihan. create: diff --git a/config/locales/is.yml b/config/locales/is.yml index 4a899c9e3..897f9237a 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -20,6 +20,8 @@ is: formats: friendly: '%e. %B %Y kl. %H:%M' blog: '%e. %B %Y' + count: + at_least_pattern: '%{count}+' helpers: file: prompt: Veldu skrá @@ -53,6 +55,11 @@ is: messages: invalid_email_address: lítur ekki út fyrir að vera gilt tölvupóstfang email_address_not_routable: er ekki nothæft + display_name_is_user_n: getur ekki verið user_n nema n sé notandaauðkennið + þitt + models: + user_mute: + is_already_muted: er nú þegar þaggað models: acl: Aðgangslisti changeset: Breytingasett @@ -84,7 +91,7 @@ is: tracetag: Merki ferils user: Notandi user_preference: Notandastillingar - user_token: Leynistrengur notanda + user_token: Aðgangsteikn notanda way: Leið way_node: Leiðarliður way_tag: Merki leiðar @@ -214,6 +221,7 @@ is: other: fyrir %{count} árum síðan printable_name: with_name_html: '%{name} (%{id})' + current_and_old_links_html: '%{current_link}, %{old_link}' editor: default: Sjálfgefið (núna %{name}) id: @@ -225,8 +233,10 @@ is: auth: providers: none: Ekkert + openid: OpenID google: Google facebook: Facebook + microsoft: Microsoft github: GitHub wikipedia: Wikipedia api: @@ -242,6 +252,8 @@ is: reopened_at_by_html: Endurvirkjað %{when} af %{user} rss: title: Minnispunktar OpenStreetMap + description_all: Listi yfir minnispunkta sem hafa verið tilkynntir, gerðar + athugasemdir við eða hefur verið lokað description_area: Listi yfir minnispunkta sem hafa verið tilkynntir, gerðar athugasemdir við eða hefur verið lokað á svæðinu þínu [(%{min_lat}|%{min_lon}) -- (%{max_lat}|%{max_lon})] @@ -277,6 +289,8 @@ is: retain_changeset_discussions: Umræður þínar um breytingar, ef einhverjar eru, verða geymdar. retain_email: Netfangið þitt verður geymt. + recent_editing_html: Þar sem þú hefur nýverið gert breytingar er ekki hægt + að eyða aðgangnum þínum. Eyðing verður möguleg eftir %{time}. confirm_delete: Ertu viss? cancel: Hætta við accounts: @@ -291,6 +305,7 @@ is: public editing: heading: Nafngreindar breytingar enabled: Virkt. Ekki nafnlaus og getur breytt gögnum. + enabled link: https://wiki.openstreetmap.org/wiki/Anonymous_edits enabled link text: Hvað er þetta? disabled: Óvirkur og getur ekki breytt gögnum, allar fyrri breytingar eru ónafngreindar. @@ -304,6 +319,7 @@ is: skilmálana vegna framlags þíns. agreed_with_pd: Þú hefur einnig lýst því yfir að breytingar þínar verði í almenningseigu (Public Domain). + link: https://wiki.osmfoundation.org/wiki/Licence/Contributor_Terms link text: Hvað er þetta? save changes button: Vista breytingar delete_account: Eyði aðgangi... @@ -332,6 +348,7 @@ is: deleted_ago_by_html: Eytt %{time_ago} af %{user} edited_ago_by_html: Breytt %{time_ago} af %{user} version: Útgáfa + redacted_version: Endurskoðuð útgáfa in_changeset: Breytingasett anonymous: nafnlaus no_comment: (engin athugasemd) @@ -344,7 +361,10 @@ is: other: '%{count} leiðir' download_xml: Sækja XML view_history: Skoða feril + view_unredacted_history: Sjá óendurskoðaða útgáfu view_details: Skoða nánar + view_redacted_data: Sjá endurskoðuð gögn + view_redaction_message: Sjá skilaboð með yfirferð location: 'Staðsetning:' common_details: coordinates_html: '%{latitude}, %{longitude}' @@ -427,6 +447,15 @@ is: introduction: Smelltu á kortið til að finna fitjur í nágrenninu. nearby: Nálægar fitjur enclosing: Umlykjandi fitjur + old_nodes: + not_found: + sorry: 'Því miður, liðurinn #%{id} útgáfa %{version} fannst ekki.' + old_ways: + not_found: + sorry: 'Því miður, leiðin #%{id} útgáfa %{version} fannst ekki.' + old_relations: + not_found: + sorry: 'Því miður, venslin #%{id} útgáfa %{version} fundust ekki.' changesets: changeset_paging_nav: showing_page: Síða %{page} @@ -461,8 +490,24 @@ is: created: Búið til closed: Lokað belongs_to: Höfundur + subscribe: + heading: Gerast áskrifandi að umræðu með breytingasetti? + button: Gerast áskrifandi að umræðu + unsubscribe: + heading: Hætta áskrift að umræðu með breytingasetti? + button: Hætta áskrift að umræðu + heading: + title: Breytingasett %{id} + created_by_html: Útbúið af %{link_user} þann %{created}. + no_such_entry: + title: Ekkert slíkt breytingasett + heading: 'Engin færsla er til með auðkennið: %{id}' + body: Breytingasett númerið %{id} er ekki til. Kannski settirðu inn rangt stafsetta + slóð eða fylgdir ógildum tengli. show: title: 'Breytingasett: %{id}' + created: 'Búið til: %{when}' + closed: 'Lokað: %{when}' created_ago_html: Búið til %{time_ago} closed_ago_html: Lokað %{time_ago} created_ago_by_html: Búið til %{time_ago} af %{user} @@ -550,6 +595,9 @@ is: show: title: Blogg %{user} | %{title} user_title: Blogg %{user} + discussion: Umræða + subscribe: Gerast áskrifandi + unsubscribe: Hætta í áskrift leave_a_comment: Bæta við athugasemd login_to_leave_a_comment_html: '%{login_link} til að bæta við athugasemd' login: Skrá inn @@ -593,6 +641,12 @@ is: all: title: OpenStreetMap bloggfærslur description: Nýjustu bloggfærslur frá notendum OpenStreetMap + subscribe: + heading: Gerast áskrifandi að umræðu með bloggfærslu? + button: Gerast áskrifandi að umræðu + unsubscribe: + heading: Hætta áskrift að umræðu með bloggfærslu? + button: Hætta áskrift að umræðu diary_comments: index: title: Dagbók Athugasemdir bætt við af %{user} @@ -604,11 +658,40 @@ is: comment: Athugasemd newer_comments: Nýrri athugasemdir older_comments: Eldri athugasemdir + new: + heading: Bæta athugasemd við umræðu með bloggfærslu? doorkeeper: + errors: + messages: + account_selection_required: Auðkenningarþjónninn krefst þess að reikningur + endanotanda sé valinn + consent_required: Auðkenningarþjónninn krefst samþykkis endanotanda + interaction_required: Auðkenningarþjónninn krefst aðgerðar af hálfu endanotanda + login_required: Auðkenningarþjónninn krefst auðkenningar endanotanda flash: applications: create: notice: Umsókn skráð. + openid_connect: + errors: + messages: + auth_time_from_resource_owner_not_configured: Brást vegna þess að uppsetningu + Doorkeeper::OpenidConnect.configure.auth_time_from_resource_owner vantar. + reauthenticate_resource_owner_not_configured: Brást vegna þess að uppsetningu + Doorkeeper::OpenidConnect.configure.reauthenticate_resource_owner vantar. + resource_owner_from_access_token_not_configured: Brást vegna þess að uppsetningu + Doorkeeper::OpenidConnect.configure.resource_owner_from_access_token vantar. + select_account_for_resource_owner_not_configured: Brást vegna þess að uppsetningu + Doorkeeper::OpenidConnect.configure.select_account_for_resource_owner + vantar. + subject_not_configured: Gerð auðkennisteikns brást vegna þess að uppsetningu + Doorkeeper::OpenidConnect.configure.subject vantar. + scopes: + address: Skoðaðu heimilisfangið þitt + email: Skoðaðu tölvupóstfangið þitt + openid: Auðkenndu notandaaðganginn þinn + phone: Skoðaðu símanúmerið þitt + profile: Skoðaðu persónuupplýsingar þínar errors: contact: contact_url: https://wiki.openstreetmap.org/wiki/Contact @@ -617,6 +700,10 @@ is: contact_the_community_html: Ekki hika við að %{contact_link} OpenStreetMap-samfélagið ef þú hefur fundið bilaðan tengil eða villu. Taktu niður nákvæma vefslóð beiðni þinnar. + bad_request: + title: Ógild beiðni + description: Aðgerðin sem þú baðst um á OpenStreetMap-þjóninum er ekki gild + (HTTP 400) forbidden: title: Bannað description: Aðgerðin sem þú baðst um á OpenStreetMap-þjóninum er aðeins í boði @@ -814,6 +901,7 @@ is: college: Framhaldsskólabygging commercial: Verslunarhús construction: Bygging á framkvæmdastigi + cowshed: Fjós detached: Aðskilið hús dormitory: Heimavist duplex: Parhús @@ -843,6 +931,7 @@ is: shed: Skúr stable: Hesthús static_caravan: Hjólhýsi + sty: Stía temple: Trúarleg bygging terrace: Raðhús train_station: Lestarstöðvarbygging @@ -1495,7 +1584,7 @@ is: title_html: Tilkynna %{link} missing_params: Get ekki búið til nýja skýrslu disclaimer: - intro: 'Áður en þú sendir skýrsluna þína inn til stjórnenda vefsins, skaltu + intro: 'Áður en þú sendir skýrsluna þína inn til umsjónarmanna vefsins, skaltu ganga úr skugga um að:' not_just_mistake: Þú sért viss um að vandamálið sé ekki bara mistök unable_to_fix: Þér hefur sjálfum ekki tekist að leysa vandamálið eða með hjálp @@ -1554,7 +1643,10 @@ is: intro_text: OpenStreetMap er heimskort gert af fólki eins og þér. Það er gefið út með opnu hugbúnaðarleyfi og það kostar ekkert að nota það. intro_2_create_account: Búa til notandaaðgang + hosting_partners_2024_html: Vefhýsing er studd af %{fastly}, %{corpmembers} og + öðrum %{partners}. partners_fastly: Fastly + partners_corpmembers: Fyrirtækjameðlimir OSMF partners_partners: samstarfsaðilum tou: Notkunarskilmálar osm_offline: OpenStreetMap gagnagrunnurinn er niðri vegna viðhalds. @@ -1575,6 +1667,7 @@ is: more: Meira user_mailer: diary_comment_notification: + description: 'OpenStreetMap bloggfærsla #%{id}' subject: '[OpenStreetMap] %{user} bætti athugasemd við bloggfærslu þína' hi: Hæ %{to_user}, header: '%{from_user} hefur bætt við athugasemd á OpenStreetMap bloggfærsluna @@ -1585,6 +1678,8 @@ is: á %{commenturl} eða sent skilaboð til höfundarins á %{replyurl} footer_html: Þú getur einnig lesið athugasemdina á %{readurl} og skrifað athugasemd á %{commenturl} eða sent skilaboð til höfundarins á %{replyurl} + footer_unsubscribe: Þú getur hætt áskrift að umræðunni á %{unsubscribeurl} + footer_unsubscribe_html: Þú getur hætt áskrift að umræðunni á %{unsubscribeurl} message_notification: subject: '[OpenStreetMap] %{message_title}' hi: Hæ %{to_user}, @@ -1605,13 +1700,19 @@ is: befriend_them: Þú getur líka bætt þeim við sem vinum á %{befriendurl}. befriend_them_html: Þú getur líka bætt þeim við sem vinum á %{befriendurl}. gpx_description: + description_with_tags: 'Hitt sér út sem að þinn GPX-fil %{trace_name} með lýsingunni + %{trace_description} og eftirfarandi merki: %{tags}' description_with_tags_html: 'Hitt sér út sem að þinn GPX-fil %{trace_name} með lýsingunni %{trace_description} og eftirfarandi merki: %{tags}' + description_with_no_tags: Hitt sér út sem að þinn GPX-fil %{trace_name} með + lýsingunni %{trace_description} og engin merki description_with_no_tags_html: Hitt sér út sem að þinn GPX-fil %{trace_name} með lýsingunni %{trace_description} og engin merki gpx_failure: hi: Hæ %{to_user}, failed_to_import: 'tókst ekki að flytja inn. Hér er villan:' + more_info: Frekari upplýsingar um bilanir í GPX-innflutningi og hvernig á að + forðast þær má finna á %{url}. more_info_html: Frekari upplýsingar um bilanir í GPX-innflutningi og hvernig á að forðast þær má finna á %{url}. import_failures_url: https://wiki.openstreetmap.org/wiki/GPX_Import_Failures @@ -1621,6 +1722,9 @@ is: loaded: one: var hlaðið inn með %{trace_points} af %{count} punkti mögulegum. other: var hlaðið inn með %{trace_points} punktum af %{count} mögulegum. + trace_location: Ferillinn þinn er núna tiltækur á %{trace_url} + all_your_traces: Alla GPX-ferla sem þú hefur sent inn má finna á %{url} + all_your_traces_html: Alla GPX-ferla sem þú hefur sent inn má finna á %{url}. subject: '[OpenStreetMap] GPX skrá flutt inn' signup_confirm: subject: '[OpenStreetMap] Velkomin í OpenStreetMap' @@ -1646,6 +1750,7 @@ is: click_the_link: Ef þú óskaðir eftir þessari endurstillingu, skaltu fylgja tenglinum hér fyrir neðan til að staðfesta breytinguna. note_comment_notification: + description: 'OpenStreetMap-minnispunktur #%{id}' anonymous: Nafnlaus notandi greeting: Hæ, commented: @@ -1687,9 +1792,10 @@ is: hefur gert athugasemd við. Minnispunkturinn er nálægt %{place}.' commented_note_html: '%{commenter} hefur endurvirkjað minnispunkt á korti sem þú hefur gert athugasemd við. Minnispunkturinn er nálægt %{place}.' - details: Nánari upplýsingar um minnispunktinn er að finna á %{url}. - details_html: Nánari upplýsingar um minnispunktinn er að finna á %{url}. + details: Svaraðu eða fáðu nánari upplýsingar um minnispunktinn á %{url}. + details_html: Svaraðu eða fáðu nánari upplýsingar um minnispunktinn á %{url}. changeset_comment_notification: + description: 'OpenStreetMap-breytingasett #%{id}' hi: Hæ %{to_user}, greeting: Hæ, commented: @@ -1708,12 +1814,11 @@ is: partial_changeset_with_comment: með umsögninni '%{changeset_comment}' partial_changeset_with_comment_html: með umsögninni '%{changeset_comment}' partial_changeset_without_comment: án athugasemdar - details: Nánari upplýsingar um breytingasettið er að finna á %{url}. - details_html: Nánari upplýsingar um breytingasettið er að finna á %{url}. - unsubscribe: Til að hætta áskrift að uppfærslum á þessu breytingasetti, farðu - þá á %{url} og smelltu á "Segja upp áskrift". - unsubscribe_html: Til að hætta áskrift að uppfærslum á þessu breytingasetti, - farðu þá á %{url} og smelltu á "Segja upp áskrift". + details: Svaraðu eða fáðu nánari upplýsingar um breytingasettið á %{url}. + details_html: Svaraðu eða fáðu nánari upplýsingar um breytingasettið á %{url}. + unsubscribe: Þú getur hætt áskrift að uppfærslum á þessu breytingasetti á %{url}. + unsubscribe_html: Þú getur hætt áskrift að uppfærslum á þessu breytingasetti + á %{url}. confirmations: confirm: heading: Skoðaðu tölvupóstinn þinn! @@ -1736,7 +1841,7 @@ is: press confirm button: Hér getur þú staðfest breytingu á netfangi. button: Staðfesta success: Breyting á netfanginu þínu hefur verið staðfest. - failure: Netfang hefur þegar verið staðfest með þessum lykli. + failure: Netfang hefur þegar verið staðfest með þessu aðgangsteikni. unknown_token: Þessi staðfestingarkóði er útrunninn eða er ekki til staðar. resend_success_flash: confirmation_sent: Við höfum sent nýja staðfestingarmiða til %{email} og um @@ -1792,6 +1897,9 @@ is: people_mapping_nearby: nálæga notendur muted: title: Þögguð skilaboð + messages: + one: '%{count} þögguð skilaboð' + other: Þú ert með %{count} þögguð skilaboð reply: wrong_user: Þú hefur skráð þig inn sem `%{user}' en skilaboðin sem þú baðst um að svara voru ekki send til þess notanda. Skráðu þig inn sem réttan notanda @@ -1810,9 +1918,13 @@ is: heading: my_inbox: Innhólfið mitt my_outbox: Úthólfið mitt + muted_messages: Þögguð skilaboð mark: as_read: Skilaboðin voru merkt sem lesin as_unread: Skilaboðin voru merkt sem ólesin + unmute: + notice: Skilaboð voru færð í Innhólf + error: Ekki var hægt að færa skilaboðin í innhólfið. destroy: destroyed: Skilaboðunum var eytt passwords: @@ -1823,13 +1935,18 @@ is: new password button: Endurstilla lykilorð help_text: Sláðu inn netfangið sem þú skráðir þig með, við munum senda tengil á það sem þú getur notað til að breyta lykilorðinu þínu. + create: + send_paranoid_instructions: Ef tölvupóstfangið þitt fyrirfinnst í gagnagrunninum + okkar, munt þú innan nokkurra mínútna fá tölvupóst með tengli til að endurheimta + lykilorðið þitt. edit: title: Endurstilla lykilorð heading: Endurstilla lykilorð fyrir %{user} reset: Endurstilla lykilorð - flash token bad: Þessi leynistrengur fannst ekki, kannski er slóðin röng? + flash token bad: Þetta aðgangsteikn fannst ekki, kannski er slóðin röng? update: flash changed: Lykilorðinu þínu hefur verið breytt + flash token bad: Þetta aðgangsteikn fannst ekki, kannski er slóðin röng? preferences: show: title: Kjörstillingar @@ -1852,6 +1969,7 @@ is: image: Mynd gravatar: gravatar: Nota Gravatar-auðkennismynd + link: https://wiki.openstreetmap.org/wiki/Gravatar what_is_gravatar: Hvað er Gravatar? disabled: Gravatar-auðkennismynd hefur verið gerð óvirk. enabled: Birting Gravatar-auðkennismyndar hefur verið gerð virk. @@ -1871,15 +1989,17 @@ is: failure: Gat ekki uppfært kjörstillingar. sessions: new: - title: Innskrá - tab_title: Innskrá + title: Skrá inn + tab_title: Skrá inn + login_to_authorize_html: Skráðu inn á OpenStreetMap til að fá aðgang að %{client_app_name}. email or username: Tölvupóstur eða notandanafn password: Lykilorð remember: Muna innskráninguna lost password link: Gleymdirðu lykilorðinu þínu? - login_button: Innskrá + login_button: Skrá inn register now: Skrá þig núna - with external: 'Þú getur líka notað utanaðkomandi þjónustur til innskráningar:' + with external: eða skráð inn með utanaðkomandi þjónustu + or: eða auth failure: Þetta notandanafn eða lykilorð er rangt. destroy: title: Útskráning @@ -1907,6 +2027,7 @@ is: image: Mynd alt: Alt-texti url: Vefslóð + codeblock: Kóðablokk richtext_field: edit: Breyta preview: Forskoða @@ -2069,7 +2190,13 @@ is: Resources Canada), og StatCan (Geography Division, Statistics Canada). contributors_ca_canada: Kanada + contributors_cz_credit_html: |- + %{czechia}: Inniheldur gögn frá Ríkisumsýslu landmælinga + og Landskrá fasteigna gefið út með %{cc_licence_link} notkunarleyfi contributors_cz_czechia: Tékkland + contributors_cz_cc_licence: Creative Commons HöfundarGetið 4.0 alþjóðlegt + notkunarleyfi (CC BY 4.0) + contributors_cz_cc_licence_url: https://creativecommons.org/licenses/by/4.0/ contributors_fi_credit_html: |- %{finland}: Inniheldur gögn frá landupplýsingagagnagrunni Landmælinga Finnlands @@ -2081,6 +2208,14 @@ is: %{france}: Inniheldur afleidd gögn frá Direction Générale des Impôts (Skattstjóraembættið). contributors_fr_france: Frakkland + contributors_hr_credit_html: |- + %{croatia}: Inniheldur gögn frá %{dgu_link} og %{open_data_portal} + (opinberar upplýsingar um Króatíu). + contributors_hr_croatia: Króatía + contributors_hr_dgu: Jarðfræðistofnun Króatíska ríkisins + contributors_hr_dgu_url: https://dgu.gov.hr/ + contributors_hr_open_data_portal: National Open Data Portal + contributors_hr_open_data_portal_url: https://data.gov.hr/ contributors_nl_credit_html: '%{netherlands}: Inniheldur AND-gögn ©, 2007 (%{and_link})' contributors_nl_netherlands: Holland @@ -2099,7 +2234,9 @@ is: (opinberar upplýsingar um Serbíu), 2018. contributors_rs_serbia: Serbía contributors_rs_rgz: Serbneska jarðfræðistofnunin + contributors_rs_rgz_url: https://geosrbija.rs/ contributors_rs_open_data_portal: National Open Data Portal + contributors_rs_open_data_portal_url: https://data.gov.rs/sr/ contributors_si_credit_html: |- %{slovenia}: Inniheldur gögn frá %{gu_link} og %{mkgp_link} (opinberar upplýsingar frá Slóveníu). @@ -2321,6 +2458,7 @@ is: ferry: Ferja light_rail: Léttlest tram: Sporvagn + trolleybus: Rafknúinn strætisvagn bus: Strætó cable_car: Kláflyfta chair_lift: Stólalyfta @@ -2330,11 +2468,13 @@ is: admin: Stjórnsýslumörk capital: Höfuðborg city: Borg + orchard: Trjágarður vineyard: Vínekra forest: Ræktaður skógur wood: Skógur farmland: Ræktarland grass: Gras + meadow: Rjóður bare_rock: Berar klappir sand: Sandur golf: Golfvöllur @@ -2349,6 +2489,7 @@ is: scrubland: Kjarrlendi lake: Vatn reservoir: Uppistöðulón + intermittent_water: Ósamfellt vatnasvæði glacier: Jökull reef: Sker wetland: Votlendi @@ -2374,9 +2515,11 @@ is: destination: Umferð leyfileg á ákveðinn áfangastað construction: Vegir í byggingu bus_stop: Strætisvagnabiðstöð + stop: Biðstöð bicycle_shop: Hjólaverslun bicycle_rental: Reiðhjólaleiga bicycle_parking: Reiðhjólastæði + bicycle_parking_small: Lítið reiðhjólastæði toilets: Salerni welcome: title: Velkomin! @@ -2424,6 +2567,7 @@ is: automated_edits: Sjálfvirkar breytingar automated_edits_url: https://wiki.openstreetmap.org/wiki/Automated_Edits_code_of_conduct start_mapping: Hefja kortlagningu + continue_authorization: Halda auðkenningu áfram add_a_note: title: Enginn tími fyrir breytingar? Bættu við athugasemd! para_1: Það er auðvelt að bæta við minnispunkti ef þú vilt laga eitthvað smávægilegt @@ -2529,6 +2673,8 @@ is: identifiable: AUÐKENNANLEGT private: EINKA trackable: REKJANLEGT + details_with_tags_html: '%{time_ago} af %{user} í %{tags}' + details_without_tags_html: '%{time_ago} af %{user}' index: public_traces: Allir ferlar my_gps_traces: GPS ferlarnir mínir @@ -2562,6 +2708,10 @@ is: other: GPX-skrá með %{count} punktum frá %{user} description_without_count: GPX-skrá frá %{user} application: + basic_auth_disabled: 'Einföld HTTP-auðkenning (Basic Authentication) er óvirk: + %{link}' + oauth_10a_disabled: 'OAuth 1.0 og 1.0a eru óvirk: %{link}' + auth_disabled_link: https://wiki.openstreetmap.org/wiki/2024_authentication_update permission_denied: Þú hefur ekki réttindi til að nota þessa aðgerð require_cookies: cookies_needed: Þú virðist ekki vera með stuðning við vefkökur í vafranum þínum. @@ -2584,24 +2734,26 @@ is: oauth2_authorizations: OAuth 2 auðkenningar muted_users: Þaggaðir notendur auth_providers: + openid_url: OpenID-slóð + openid_login_button: Halda áfram openid: title: Skrá inn með OpenID - alt: Skrá inn með OpenID-slóð + alt: Táknmerki OpenID google: title: Skrá inn með Google - alt: Skrá inn með Google OpenID-aðgangi + alt: Táknmerki Google facebook: title: Skrá inn með Facebook - alt: Skrá inn með Facebook-aðgangi + alt: Táknmerki Facebook microsoft: title: Skrá inn með Microsoft - alt: Skrá inn með Microsoft-aðgangi + alt: Táknmerki Microsoft github: title: Skrá inn með GitHub - alt: Skrá inn með GitHub-aðgangi + alt: Táknmerki GitHub wikipedia: title: Skrá inn með Wikipedia - alt: Skrá inn með Wikipedia-aðgangi + alt: Táknmerki Wikipedia oauth: authorize: title: Auðkenndu aðgang að notandaaðganginum þínum @@ -2642,11 +2794,17 @@ is: read_gpx: Lesa einka-GPS-ferlana þína. write_gpx: Senda inn GPS feril. write_notes: Breyta minnispunktum. + write_redactions: Endurskoða kortagögn read_email: Lesa tölvupóstfang notanda + consume_messages: Lesa, uppfæra stöðu og eyða skilaboðum notenda + send_messages: Senda einkaskilaboð til annara notenda skip_authorization: Samþykkja forrit sjálfvirkt + for_roles: + moderator: Þessi heimild er fyrir aðgerðir sem eingöngu tiltækar fyrir umsjónarmenn oauth_clients: new: title: Skrá nýtt forrit + disabled: Skráning OAuth 1 forrita hefur verið gerð óvirk edit: title: Breyta forritinu þínu show: @@ -2692,6 +2850,7 @@ is: no_applications_html: Ert þú að nota forrit sem þú myndir vilja skrá til notkunar hjá okkur með %{oauth2} staðlinum? Þú verður að skrá vefforritið áður en það fer að senda OAuth-beiðnir á þessa þjónustu. + oauth_2: OAuth 2 new: Skrá nýtt forrit name: Nafn permissions: Heimildir @@ -2731,38 +2890,60 @@ is: title: Auðkenndu forritin mín application: Forrit permissions: Heimildir + last_authorized: Síðast auðkennt no_applications_html: Þú hefur ekki ennþá heimilað nein %{oauth2} forrit. + oauth_2: OAuth 2 application: revoke: Afturkalla aðgang confirm_revoke: Afturkalla aðgang fyrir þetta forrit? users: new: title: Nýskrá + tab_title: Nýskrá + signup_to_authorize_html: Skráðu þig á OpenStreetMap til að fá aðgang að %{client_app_name}. no_auto_account_create: Því miður getum við eki búið til reikning fyrir þig sjálfkrafa. please_contact_support_html: Hafðu samband við %{support_link} til að fá aðgang búinn til - við munum reyna að afgreiða beiðnina eins fljótt og mögulegt er. support: aðstoðarteymið about: - header: Frjálst og breytanlegt + header: Frjálst og breytanlegt. paragraph_1: Ólíkt öðrum landakortum, er OpenStreetMap gert frá grunni af fólki eins og þér, öllum er heimilt að laga það, uppfæra, sækja og nota. - paragraph_2: Skráðu þig sem notanda til að geta tekið þátt. Við munum senda - þér tölvupóst til staðfestingar á aðgangnum. + paragraph_2: Skráðu þig sem notanda til að geta tekið þátt. + welcome: Velkomin í OpenStreetMap + duplicate_social_email: Ef þú ert þegar með notandaaðgang á OpenStreetMap en + óskar eftir að nota utanaðkomandi auðkenningarþjónustu, skaltu skrá þig inn + með lykilorðinu þínu og gera viðeigandi breytingar í stillingum notandaaðgangsins + þíns. display name description: Nafn þitt sem aðrir notendur sjá, þú getur breytt því síðar í stillingunum þínum. by_signing_up: + html: Með því að skrá þig, samþykkir þú %{tou_link}, %{privacy_policy_link} + og %{contributor_terms_link} hjá okkur. privacy_policy: meðferð persónuupplýsinga + privacy_policy_url: https://wiki.osmfoundation.org/wiki/Privacy_Policy privacy_policy_title: persónuverndarstefnu OSMF, þar með talinn hlutann um tölvupóstföng + contributor_terms_url: https://wiki.osmfoundation.org/wiki/Licence/Contributor_Terms + contributor_terms: skilmálar vegna framlags + tou: notkunarskilmálar external auth: 'Auðkenning með þriðja aðila:' continue: Nýskrá terms accepted: Bestu þakkir fyrir að samþykkja nýju skilmálana vegna framlags þíns! email_help: + privacy_policy: stefna vegna meðferðar persónuupplýsinga + privacy_policy_url: https://wiki.osmfoundation.org/wiki/Privacy_Policy + privacy_policy_title: persónuverndarstefnu OSMF, þar með talinn hlutann um + tölvupóstföng html: Netfangið þitt er ekki birt opinberlega, skoðaðu síðuna um %{privacy_policy_link} til að sjá nánari upplýsingar. - use external auth: Þú getur líka notað utanaðkomandi þjónustur til innskráningar + consider_pd_html: Ég lít svo á að framlög mín verði í %{consider_pd_link}. + consider_pd: almenningseign + consider_pd_url: https://wiki.osmfoundation.org/wiki/Licence_and_Legal_FAQ/Why_would_I_want_my_contributions_to_be_public_domain + or: eða + use external auth: eða nýskráð þig með utanaðkomandi þjónustu terms: title: Skilmálar heading: Skilmálar @@ -2798,6 +2979,7 @@ is: nýja skilmála vegna framlags (contributor terms). Til að sjá ítarlegri upplýsingar, geturðu skoðað %{terms_declined_link}. terms_declined_link: þessari wiki síðu + terms_declined_url: https://wiki.openstreetmap.org/wiki/Contributor_Terms_Declined no_such_user: title: Notandi ekki til heading: Notandinn %{user} er ekki til @@ -2818,6 +3000,7 @@ is: blocks on me: Bönn gegn mér blocks by me: Bönn eftir mig create_mute: Þagga þennan notanda + destroy_mute: Hætta að þagga niður í þessum notanda edit_profile: Breyta notandasíðu send message: Senda skilaboð diary: Blogg @@ -2827,6 +3010,9 @@ is: remove as friend: Fjarlægja úr vinum add as friend: Bæta við sem vini mapper since: 'Í kortlagningu síðan:' + last map edit: 'Síðasta breyting á korti:' + no activity yet: Engin virkni ennþá + uid: 'Notandaauðkenni:' ct status: 'Skilmálar vegna framlags:' ct undecided: Óvíst ct declined: Hafnað @@ -2837,14 +3023,18 @@ is: role: administrator: Þessi notandi er möppudýr moderator: Þessi notandi er prófarkalesari + importer: Þessi notandi hefur heimild til innflutnings grant: administrator: Veita möppudýrsréttindi moderator: Veita stjórnandaréttindi + importer: Veita aðgang að innflutningi revoke: administrator: Svifta möppudýrsréttindum moderator: Svifta stjórnandaréttindum + importer: Afturkalla aðgang að innflutningi block_history: Virk bönn moderator_history: Úthlutuð bönn (eftir notandann) + revoke_all_blocks: Aflétta öllum bönnum comments: Athugasemdir create_block: Banna þennan notanda activate_user: Virkja þennan notanda @@ -2861,6 +3051,11 @@ is: index: title: Notendur heading: Notendur + older: Eldri notendur + newer: Nýrri notendur + found_users: + one: '%{count} notandi fannst' + other: '%{count} notendur fundust' summary_html: '%{name} var útbúinn frá %{ip_address} þann %{date}' summary_no_ip_html: '%{name} útbúinn þann %{date}' confirm: Staðfesta valda notendur @@ -2930,12 +3125,13 @@ is: show: Sýna þetta bann back: Listi yfir öll bönn filter: - block_expired: Bannið er þegar útrunnið og er ekki hægt að breyta. block_period: Banntíminn verður að vera í forstillingunum. create: flash: Bjó til bann gegn %{name}. update: only_creator_can_edit: Aðeins stjórnandinn sem bjó til bannið getur breytt því. + only_creator_or_revoker_can_edit: Aðeins þeir umsjónarmenn sem hafa sett bannið + geta breytt því. success: Banninu var breytt. index: title: Bönn @@ -2950,6 +3146,16 @@ is: confirm: Staðfestu að þú viljir eyða þessu banni. revoke: Eyða banninu flash: Banninu var eytt. + revoke_all: + title: Eyði öllum bönnum á %{block_on} + heading_html: Eyði öllum bönnum á %{block_on} + empty: '%{name} er ekki með nein virk bönn.' + confirm: Ertu viss um að þú viljir aflétta %{active_blocks}? + active_blocks: + one: '%{count} virkt bann' + other: '%{count} virk bönn' + revoke: Afturkalla! + flash: Öllum virkum bönnum hefur verið aflétt. helper: time_future_html: Endar eftir %{time} until_login: Virkt þangað til notandinn skráir sig inn. @@ -3004,14 +3210,39 @@ is: reason: Ástæða banns status: Staða revoker_name: Eytt af + older: Eldri bönn + newer: Nýrri bönn + navigation: + all_blocks: Öll bönn + blocks_on_me: Bönn gegn mér + blocks_on_user: Bönn gegn %{user} + blocks_by_me: Bönn eftir mig + blocks_by_user: Bönn eftir %{user} + block: 'Bann #%{id}' user_mutes: index: + title: Þaggaðir notendur + my_muted_users: Þaggaðir notendur mínir + you_have_muted_n_users: + one: Þú hefur þaggað niður í %{count} notanda + other: Þú hefur þaggað niður í %{count} notendum + user_mute_explainer: Skilaboð frá þögguðum notendum eru sett í sérstakt pósthólf + og þú munt ekki fá tilkynningar í tölvupósti. + user_mute_admins_and_moderators: Þú getur þaggað niður í stjórnendum og umsjónarfólki + en skilaboð þeirra verða ekki þögguð. table: thead: muted_user: Þaggaður notandi actions: Aðgerðir tbody: + unmute: Ekki þagga send_message: Senda skilaboð + create: + notice: Þú þaggaðir niður í %{name}. + error: Ekki tókst að þagga niður í %{name}. %{full_message}. + destroy: + notice: Þú hættir að þagga niður í %{name}. + error: Ekki tókst að þagga niður í notandanum. Reyndu aftur. notes: index: title: Minnispunktar sem hafa verið sendir inn eða gerðar athugasemdir við af @@ -3019,6 +3250,8 @@ is: heading: Minnispunktar frá %{user} subheading_html: Minnispunktar sem hafa verið %{submitted} eða gerð %{commented} við af %{user} + subheading_submitted: sendi inn + subheading_commented: setti inn athugasemd á no_notes: Engir minnispunktar id: Auðkenni (ID) creator: Búið til af @@ -3049,6 +3282,7 @@ is: reactivate: Virkja aftur comment_and_resolve: Athugasemd & leysa comment: Athugasemd + log_in_to_comment: Skráðu þig inn til að gera athugasemd við þennan minnispunkt report_link_html: Ef þessi minnispunktur inniheldur viðkvæmar upplýsingar sem þarf að fjarlægja geturðu %{link}. other_problems_resolve: Fyrir öll önnur vandamál með minnispunktinn, skaltu @@ -3061,6 +3295,10 @@ is: intro: Fannstu mistök eða eitthvað sem vantar? Láttu aðra kortagerðarmenn vita svo hægt sé að laga það. Færðu kortamerkið á réttan stað og skrifaðu minnispunkt til að útskýra vandamálið. + anonymous_warning_html: Þú ert ekki skráð/ur inn. Notaðu %{log_in} eða %{sign_up} + ef þú vilt fá uppfærslur varðandi minnispunktinn þinn. + anonymous_warning_log_in: skrá inn + anonymous_warning_sign_up: Nýskráðu þig advice: Minnispunkturinn þinn er opinber og gæti verið notaður til að uppfæra kortið; því ættirðu ekki að setja inn neinar persónulegar upplýsingar, eða upplýsingar úr höfundarvörðu efni. @@ -3079,14 +3317,15 @@ is: custom_dimensions: Setja sérsniðnar stærðir format: 'Snið:' scale: 'Kvarði:' - image_dimensions: Myndin mun sýna venjulegt lag á %{width} x %{height} + image_dimensions: Myndin mun sýna %{layer} lagið í %{width} x %{height} download: Sækja short_url: Stutt URL-slóð include_marker: Hafa með kortamerkið center_marker: Miðja kort á kortamerki paste_html: Notaðu þennan HTML kóða til að bæta kortinu á vefsíðu view_larger_map: Skoða stærra kort - only_standard_layer: Eingöngu er hægt að flytja staðallagið út sem mynd + only_standard_layer: Eingöngu er hægt að flytja lögin Staðlað, Hjólakort og + Samgöngur út sem mynd embed: report_problem: Tilkynna vandamál key: @@ -3107,8 +3346,10 @@ is: other: Þú ert minna en %{count} fet frá þessum punkti base: standard: Staðlað + cyclosm: CyclOSM cycle_map: Hjólakort transport_map: Umferðarkort + tracestracktop_topo: Tracestrack Topo hot: Hjálparstarf layers: header: Lög á korti @@ -3126,6 +3367,8 @@ is: osm_france: OpenStreetMap Frakklandi thunderforest_credit: Kortatíglar frá %{thunderforest_link} andy_allan: Andy Allan + tracestrack_credit: Kortatíglar frá %{tracestrack_link} + tracestrack: Tracestrack hotosm_credit: Stíll kortatígla frá %{hotosm_link} hýst af %{osm_france_link} hotosm_name: Humanitarian OpenStreetMap teyminu site: @@ -3137,6 +3380,7 @@ is: map_data_zoom_in_tooltip: Renndu að til að skoða gögn kortsins queryfeature_tooltip: Rannsaka fitjur queryfeature_disabled_tooltip: Renndu að til að rannsaka fitjur + embed_html_disabled: Ívafið HTML ekki tiltækt fyrir þetta kortalag edit_help: Færðu kortið og stilltu aðdrátt inn á staðinn sem þú vilt breyta, smelltu síðan hér. directions: diff --git a/config/locales/it.yml b/config/locales/it.yml index 1209efa6d..a83e2b521 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -3070,7 +3070,6 @@ it: show: Visualizza questo blocco back: Visualizza tutti i blocchi filter: - block_expired: Il blocco è già scaduto e non può essere modificato. block_period: Il periodo di blocco deve essere uno dei valori selezionabili nella lista a tendina. create: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 1676d84ad..6f2693f16 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -2725,7 +2725,6 @@ ja: show: このブロックを閲覧 back: すべてのブロックを閲覧 filter: - block_expired: このブロック期間は既に終了しており、変更できません。 block_period: ブロック期間はドロップダウンリストから一つ選択してください。 create: flash: 利用者 %{name} をブロックしました。 diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 703afbbf0..5f0c6bb7a 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -2731,7 +2731,6 @@ ko: show: 이 차단 보기 back: 모든 차단 보기 filter: - block_expired: 차단은 이미 만료되었고 편집할 수 없습니다. block_period: 차단 기간은 드롭 다운 목록에서 선택할 수 있는 값 중 하나여야 합니다. create: flash: '%{name} 사용자를 차단했습니다.' diff --git a/config/locales/ku-Latn.yml b/config/locales/ku-Latn.yml index 3bfeae8d5..b8feb250e 100644 --- a/config/locales/ku-Latn.yml +++ b/config/locales/ku-Latn.yml @@ -388,7 +388,7 @@ ku-Latn: relation: eleqe start_rjs: feature_warning: '%{num_features} taybetmendî bar dibin, dibe ku ev taybetmendî - bikin ku geroka te nikaribe bişixule yan jî hêditir bibe. Tu pê bawerî ku + bikin ku geroka te nikaribe bişixule yan jî hêdîtir bibe. Tu pê bawer î ku tu dixwazî vê daneyê bibînî?' load_data: Daneyan Bar Bike loading: Tê barkirin... @@ -1662,8 +1662,8 @@ ku-Latn: da aktîvkirin. Ev not nêzîkî %{place} (y)e.' commented_note_html: '%{commenter} notekî nexşeyê yê ku te şiroveyek berdabû jinûve da aktîvkirin. Ev not nêzîkî %{place} (y)e.' - details: Dêtayên zêdetir yên derbarê notê de hûn dikarin ji %{url} bibînin. - details_html: Dêtayên zêdetir yên derbarê notê de hûn dikarin ji %{url} bibînin. + details: Cewab bide an di derbarê notê de zêdetir hîn bibe ji %{url}. + details_html: Cewab bide an di derbarê notê de zêdetir hîn bibe ji %{url}. changeset_comment_notification: hi: Merheba %{to_user}, greeting: Merheba, @@ -1685,14 +1685,14 @@ ku-Latn: partial_changeset_with_comment: tevî şiroveya '%{changeset_comment}' partial_changeset_with_comment_html: tevî şiroveya '%{changeset_comment}' partial_changeset_without_comment: bêyî şirove - details: Dêtayên zêdetir yên derbarê desteya guherandinê de hûn dikarin ji %{url} - bibînin. - details_html: Dêtayên zêdetir yên derbarê desteya guherandinê de hûn dikarin - ji %{url} bibînin. - unsubscribe: Ji bo ku ji abonetiya rojanekirinên vê desteya guherandinê derbikevî, - here %{url} û bitikîne ser "Abonetiyê betal bike". - unsubscribe_html: Ji bo ku ji abonetiya rojanekirinên vê desteya guherandinê - derbikevî, here %{url} û bitikîne ser "Abonetiyê betal bike". + details: Cewab bide an di derbarê desteya guherandinê de zêdetir hîn bibe ji + %{url}. + details_html: Cewab bide an di derbarê desteya guherandinê de zêdetir hîn bibe + ji %{url}. + unsubscribe: Tu dikarî ji %{url} ji abonetiya rojanekirinên vê desteya guherandinê + derkevî. + unsubscribe_html: Tu karî ji %{url} ji abonetiya rojanekirinên vê desteya guherandinê + derkevî. confirmations: confirm: heading: E-nameya xwe kontrol bikeǃ @@ -1765,18 +1765,18 @@ ku-Latn: bi hinek kesên nêzîkê xwe re nakevî îrtîbatê? people_mapping_nearby: lînka nexşesazên li derdorên nêzîk reply: - wrong_user: Te wek `%{user}' têket, lê peyamê ku te dixwest were cewabdayîn - ji wî/wê bikarhênerê re nehate şandin. Xêra xwe ji bo cewabdanê wekî bikarhênerê - rast têbikeve. + wrong_user: Te wek `%{user}' têket, lê peyama ku te dixwest were cewabdayîn + ji wî bikarhênerê re nehat şandin. Xêra xwe ji bo cewabdanê wekî bikarhênerê + rast têkeve. show: title: Peyamê bixwîne reply_button: Bersiv bide unread_button: Wek nexwendî nîşan bide destroy_button: Jê bibe back: Paşve vegere - wrong_user: Te wek `%{user}' têket, lê peyamê ku dihate xwestin ku tu wê bixwînî + wrong_user: Te wek `%{user}' têket, lê peyama ku dihate xwestin ku tu wê bixwînî ji aliyê wî/wê bikarhênerê ve an jî ji wî/wê bikarhênerê re nehatiye şandin. - Xêra xwe ji bo xwendinê wekî bikarhênerê rast têbikeve. + Xêra xwe ji bo xwendinê wekî bikarhênerê rast têkeve. sent_message_summary: destroy_button: Jê bibe heading: @@ -1791,7 +1791,7 @@ ku-Latn: new: title: Şîfreya wenda heading: Te şîfreya xwe ji bîr kir? - email address: 'Navnîşana E-peyamê:' + email address: Adresa e-peyamê new password button: Şîfreyê nû bike help_text: E-peyama ku te pê xwe qeydkiribû binivîse, em ê ji te re lînkek bişînin tu yê bi wê lînkê bikaribî şîfreya xwe nû bikî. @@ -1848,13 +1848,13 @@ ku-Latn: new: title: Têkeve tab_title: Têkeve - email or username: Adrêsa E-peyamê an jî Navê Bikarhêneriyêː - password: 'Şîfre:' + email or username: Adresa e-peyamê an Navê Bikarhêneriyê + password: Şîfre remember: Min bi bîr bîne lost password link: Te şîfreya xwe winda kir? login_button: Têkeve register now: Vê gavê xwe qeyd bike - with external: Wek alternatîv, ji bo têketinê yek ji van sepanan bi kar bîneː + with external: An bi sepaneke alîyê sêyem têkeve auth failure: Bibore, bi van dêtayan re tu têneketî. destroy: title: Derkeve @@ -2007,8 +2007,9 @@ ku-Latn: title: Rêbera ji bo kesên ku nû dest pê kirine description: Civata me, ji bo kesên ku nû dest pê kirine rêbertî dike. community: - title: Foruma civatê - description: Cihê hevpar ji bo sohbetên di derbarê OpenStreetMapê de. + title: Foruma Alîkarî û Civatê + description: Cihê hevpar ji bo gihîna alîkarîyê sohbetên di derbarê OpenStreetMapê + de. mailing_lists: title: Lîsteya E-nameyan description: Di lîsteyên e-nameyan yên deverî an jî herêmî yên cur bi cur @@ -2258,23 +2259,23 @@ ku-Latn: oauth2_authorizations: Destûrdarkirinên OAuth 2 auth_providers: openid: - title: Bi OpenID'yê têkeve - alt: Têketina bi URL'yek OpenID'yê + title: Bi OpenIDyê têkeve + alt: Logoya OpenIDyê google: - title: Bi Google têkeve - alt: Têketina bi OpenID ya Googlê + title: Bi Googlê têkeve + alt: Logoya Googlê facebook: title: Bi Facebookê têkeve - alt: Bi hesabekî Facebookê têkeve + alt: Logoya Facebookê microsoft: title: Bi Microsoftê têkeve - alt: Bi hesabê xwe yê Microsoftê têkeve + alt: Logoya Microsoftê github: - title: Bi GitHub'ê têkeve - alt: Bi hesabekî GitHubê têbikeve + title: Bi GitHubê têkeve + alt: Logoya GitHubê wikipedia: - title: Bi Wîkîpediyayê têkeve - alt: Bi hesabekî Wîkîpediyayê têkeve + title: Logoya Wîkîpediyayê + alt: Logoya Wîkîpediyayê oauth: authorize: title: Ji bo gihîna hesabê xwe selahiyetê bide @@ -2413,14 +2414,14 @@ ku-Latn: çareser bikin. support: piştgirî about: - header: Belaş e û dikare were sererastkirin + header: Belaş e û dikare were sererastkirin. display name description: Navê te yê ku ji her kesê re tê xuyan. Tu paşê dikarî vê navê ji hevyazên xwe biguherînî. external auth: 'Teyîdkirina bi aliyên sêyem:' continue: Qeyd bibe terms accepted: Em spasiya te dikin ji bo ku te şertên beşdariyê yê nû qebûl kirǃ - use external auth: Wek alternatîv, ji bo têketinê yekî ji van bi kar bîne + use external auth: An bi yek ji aplîkasyonên alîyê sêyem qeyd bibe terms: title: Şertûmerc heading: Şertûmerc @@ -2542,8 +2543,8 @@ ku-Latn: option_1: Eger tu di OpenStreetMapê de nû bî, xêra xwe bi vê formê li jêr, ji xwe re hesabekî nû çêbike. option_2: Heke jixwe hesabekî te hebe, tu dikarî navê xwe yê bikarhêneriyê û - şîfreyê xwe binivîsî û têkevî, û piştre jî ji mîhengên bikarhênerê nasnameya - (ID'ya) xwe bi hesabê xwe ve girê bidî. + şîfreya xwe binivîsî û têkevî, û piştre jî ji mîhengên bikarhênerê nasnameya + (IDya) xwe bi hesabê xwe ve girê bidî. user_role: filter: not_a_role: '`%{role}'' ne rolek muteber e.' @@ -2586,7 +2587,6 @@ ku-Latn: show: Vê astengiyê bibîne back: Hemû astengiyan bibîne filter: - block_expired: Wextê astengiyê derbas bûye û nikare were guhartin. block_period: Wextê astengiyê, divê yek ji nirxên vê lîsteya ku dikare were vekirin be. create: @@ -2729,14 +2729,15 @@ ku-Latn: custom_dimensions: Mezinahiyên taybet eyar bike format: 'Format:' scale: 'Pîvan (miqyas):' - image_dimensions: Wêne wê tebeqeya standard li %{width} x %{height} nîşan bide + image_dimensions: Wêne wê tebeqeya %{layer} li %{width} x %{height} nîşan bide download: Daxîne short_url: URLya kurt include_marker: Nîşanek deyne center_marker: Nîşanê bike merkeza nexşeyê paste_html: Ji bo ku di malperê de bi cih bikî HTMLê pê ve bike view_larger_map: Nexşeya Mestir Bibîne - only_standard_layer: Tenê mezinahiya standard wek rismek dikare were derxistin + only_standard_layer: Tenê tebeqeyên Standard, Nexşeya Bisiklêtê û Transportê + wek rism kare were derxistin embed: report_problem: Pirsgirêkek rapor bike key: @@ -2757,7 +2758,7 @@ ku-Latn: other: Tu di nava %{count} gavên vê nuqteyê de yî base: standard: Standard - cycle_map: Nexşeya bisiklête + cycle_map: Nexşeya bisiklêtê transport_map: Nexşeya transportê hot: Mirovatî layers: diff --git a/config/locales/lt.yml b/config/locales/lt.yml index bfbc4ba8b..10479ebab 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -2763,7 +2763,6 @@ lt: show: PeržiÅ«rėti šį blokavimą back: PeržiÅ«rėti visus blokavimus filter: - block_expired: Blokavimo laikas jau baigėsi, todėl negali bÅ«ti keičiamas. block_period: Blokavimo periodo reikÅ¡mė turi bÅ«ti pasirinkta iÅ¡ iÅ¡krentančio sąraÅ¡o. create: diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 9a24f0e61..61be609c8 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -2072,7 +2072,6 @@ lv: show: ApskatÄ«t Å¡o bloku back: SkatÄ«t visus blokus filter: - block_expired: Å is liegums jau ir beidzies un nevar tikt labots. block_period: Lieguma periodam jābÅ«t vienam no izvēlamām iespējām krÄ«toÅ¡ajā sarakstā. create: diff --git a/config/locales/mk.yml b/config/locales/mk.yml index 68a208db8..7a77d5fc1 100644 --- a/config/locales/mk.yml +++ b/config/locales/mk.yml @@ -1664,13 +1664,19 @@ mk: befriend_them: Можете личноста и да ја додадете како пријател на %{befriendurl}. befriend_them_html: Можете личноста и да ја додадете како пријател на %{befriendurl}. gpx_description: + description_with_tags: 'Вашата GPX-податотека %{trace_name} со описот %{trace_description} + и следниве ознаки: %{tags}' description_with_tags_html: 'Вашата GPX-податотека %{trace_name} со описот %{trace_description} и следниве ознаки: %{tags}' + description_with_no_tags: Вашата GPX-податотека %{trace_name} со описот %{trace_description} + и без ознаки description_with_no_tags_html: Вашата GPX-податотека %{trace_name} со описот %{trace_description} и без ознаки gpx_failure: hi: Здраво %{to_user}, failed_to_import: не можеше да се увезе. Еве ја грешката; + more_info: Повеќе информации за неуспесите на увозот на GPX и тоа како да ги + одбегнете ќе најдете на %{url}. more_info_html: Повеќе информации за неуспесите на увозот на GPX и тоа како да ги одбегнете ќе најдете на %{url}. import_failures_url: https://wiki.openstreetmap.org/wiki/GPX_Import_Failures?uselang=mk @@ -1680,6 +1686,8 @@ mk: loaded: one: успешно вчитано со %{trace_points} од %{count} можни точки. other: успешно вчитано со %{trace_points} од %{count} можни точки. + trace_location: Вашата трага е достапна на %{trace_url} + all_your_traces: Сите ваши успешно подигнати GPX-траги ќе ги најдете на %{url} all_your_traces_html: Сите ваши успешно подигнати GPX-траги ќе ги најдете на %{url}. subject: '[OpenStreetMap] Успешен увоз на GPX-податотека' @@ -2675,6 +2683,8 @@ mk: write_notes: Менување на белешки write_redactions: Прикриј податоци за картата read_email: Читање на корисничка е-пошта + consume_messages: Читајте, менувајте статуси и бришете кориснички пораки + send_messages: Испраќајте приватни пораки до други корисници skip_authorization: Автоодобрување на прилог for_roles: moderator: Оваа дозвола е за дејства достапни само за модератори. @@ -2993,12 +3003,13 @@ mk: show: Преглед на овој блок back: Преглед на сите блокови filter: - block_expired: Блокот е веќе истечен и затоа не може да се менува. block_period: Периодот на блокада мора да биде со рок избран од паѓачкиот список. create: flash: Направен е блок на корисникот %{name}. update: only_creator_can_edit: Само модераторот кој го направил блоков може да го менува. + only_creator_or_revoker_can_edit: Овој блок можат да го менуваат само модератори + кои го создале или отповикале. success: Блокот е изменет. index: title: Кориснички блокови @@ -3179,14 +3190,15 @@ mk: custom_dimensions: Димензии по ваш избор format: 'Формат:' scale: 'Размер:' - image_dimensions: Сликата ќе го покаже стандардниот слој при %{width} × %{height} + image_dimensions: Сликата ќе го покаже слојот %{layer} со %{width} x %{height} download: Преземи short_url: Кратка URL include_marker: Вклучи го бележникот center_marker: Сосред. картата на бележникот paste_html: Ископирајте го HTML-кодот за да го вметнете во страницата. view_larger_map: Преглед на поголема карта - only_standard_layer: Само стандардниот слој може да се извезува како слика + only_standard_layer: Како слика можат да се извезуваат само слоевите Стандарден, + Велосипедска карта и Превоз embed: report_problem: Пријави проблем key: diff --git a/config/locales/ms.yml b/config/locales/ms.yml index aae77d325..4aa69ff99 100644 --- a/config/locales/ms.yml +++ b/config/locales/ms.yml @@ -2091,7 +2091,6 @@ ms: show: Lihat sekatan ini back: Lihat semua sekatan filter: - block_expired: Sekatan ini sudah luput dan tidak boleh disunting. block_period: Tempoh sekatan mestilah salah satu nilai yang boleh dipilih dalam senarai juntai bawah ini. create: diff --git a/config/locales/nb.yml b/config/locales/nb.yml index 8af954036..a5b467e55 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -2302,7 +2302,6 @@ nb: show: Vis denne blokkeringen back: Vis alle blokkeringer filter: - block_expired: Blokkeringen har allerede utløpt og kan ikke endres. block_period: Blokkeringsperioden mÃ¥ være en av verdiene som kan velges fra rullegardinen. create: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 0f2311ba4..0a90b62e7 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -462,9 +462,9 @@ nl: way: weg relation: relatie start_rjs: - feature_warning: Er worden %{num_features} objecten geladen, waardoor uw browser - traag kan worden of niet meer kan reageren. Weet u zeker dat u deze gegevens - wilt weergeven? + feature_warning: '%{num_features} functies worden geladen, waardoor uw browser + traag kan worden of niet reageert. Weet u zeker dat je deze gegevens wilt + weergeven?' load_data: Gegevens laden loading: Bezig met laden… tag_details: @@ -694,6 +694,8 @@ nl: comment: Reactie newer_comments: Nieuwere reacties older_comments: Oudere reacties + new: + heading: Een reactie toevoegen aan de volgende dagboekaantekening? doorkeeper: errors: messages: @@ -2138,7 +2140,7 @@ nl: credit_title_html: Hoe OpenStreetMap te vermelden credit_1_html: 'Wanneer u OpenStreetMap-gegevens gebruikt, bent u verplicht de volgende twee dingen te doen:' - credit_2_1: Vermeld OpenStreetMap door onze copyrightmelding te tonen. + credit_2_1: Vermeld OpenStreetMap door onze copyrightmelding weer te geven. credit_2_2: Maak duidelijk dat de data beschikbaar is onder de Open Database-licentie. credit_3_html: Voor de auteursrechtelijke vermelding hanteren wij verschillende voorschriften ten aanzien van de manier waarop deze moet worden weergegeven, @@ -3086,7 +3088,6 @@ nl: show: Deze blokkade weergeven back: Alle blokkades weergeven filter: - block_expired: De blokkade is al vervallen en kan niet bijgewerkt worden. block_period: De duur van de blokkade moet één van de waarden in het menu zijn. create: flash: Heeft gebruiker %{name} geblokkeerd. @@ -3275,14 +3276,15 @@ nl: custom_dimensions: Aangepaste afmetingen instellen format: 'Formaat:' scale: 'Schaal:' - image_dimensions: Afbeelding geeft standaardlaag weer op %{width} x %{height} + image_dimensions: Afbeelding geeft laag %{layer} weer op %{width} x %{height} download: Downloaden short_url: Korte URL include_marker: Marker opnemen center_marker: Kaart centreren op de marker paste_html: Kopieer de HTML-code en voeg deze toe aan uw website view_larger_map: Grotere kaart weergeven - only_standard_layer: Alleen de standaard laag kan worden geëxporteerd als afbeelding + only_standard_layer: Alleen de lagen Standaard, Fietskaart en Transportlagen + kunnen worden geëxporteerd als afbeelding embed: report_problem: Een probleem melden key: @@ -3442,7 +3444,7 @@ nl: directions_from: Routebeschrijving vanaf hier directions_to: Routebeschrijving naar hier add_note: Hier een opmerking toevoegen - show_address: Adres tonen + show_address: Adres weergeven query_features: Kaartelementen opvragen centre_map: De kaart hier centreren redactions: diff --git a/config/locales/nn.yml b/config/locales/nn.yml index ce8463ba0..aaf4a90ef 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -2485,7 +2485,6 @@ nn: show: Vis denne blokkeringa back: Vis alle blokkeringar filter: - block_expired: Blokkeringa har allereie utløpt og kan ikkje endrast. block_period: Blokkeringsperioden mÃ¥ vere ein av verdia som kan vert frÃ¥ valde rullegardinen. create: diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 63393cdaf..7b5341362 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -2348,8 +2348,6 @@ oc: ? show: Afichar aqueste blocatge back: Veire totes los blocatges - filter: - block_expired: Lo blocatge a ja expirat e pòt pas èsser modificat. create: flash: Blocatge creat sus l'utilizaire %{name}. update: diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 4ef001e02..3b69092b5 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -2960,7 +2960,6 @@ pl: show: Zobacz tę blokadę back: Wyświetl wszystkie blokady filter: - block_expired: Blokada zakończyła się i nie można jej edytować. block_period: Długość blokady należy wybrać z listy rozwijanej. create: flash: Nałożono blokadę na użytkownika %{name}. diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 81451108b..a4d652ec2 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -3037,7 +3037,6 @@ pt-PT: show: Ver este bloqueio back: Ver todos os bloqueios filter: - block_expired: Este bloqueio já expirou e não pode ser editado. block_period: O período de bloqueio tem de corresponder a um dos valores selecionáveis da lista. create: diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 11b64b6a8..74693572b 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -3039,7 +3039,6 @@ pt: show: Ver esse bloqueio back: Ver todos bloqueios filter: - block_expired: O bloqueio já expirou e não pode mais ser editado. block_period: O período de bloqueio deve ser um dos valores selecionáveis na lista. create: diff --git a/config/locales/ro.yml b/config/locales/ro.yml index 7ee0f7fcf..6ce044206 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -2927,7 +2927,6 @@ ro: show: Vezi această blocare back: Vezi toate blocările filter: - block_expired: Blocul a expirat deja și nu poate fi editat. block_period: Perioada de blocare trebuie să fie una dintre valorile selectabile din lista derulată. create: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index ce87fb379..7aeef9696 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -1067,6 +1067,8 @@ ru: gardener: Садовник glaziery: Стекольщик handicraft: Ремесло + hvac: Специалист по микроклиматическим системам + metal_construction: Мастерская металлоконструкций painter: Художник photographer: Фотограф plumber: Сантехник @@ -1075,6 +1077,7 @@ ru: shoemaker: Сапожник stonemason: Каменщик tailor: Портной + window_construction: Оконная мастерская winery: Винодельня "yes": Мастерская emergency: @@ -1085,7 +1088,10 @@ ru: fire_extinguisher: Огнетушитель fire_water_pond: Пожарный водоём landing_site: Место аварийной посадки + life_ring: Спасательный круг phone: Телефон экстренной связи + siren: Аварийная сирена + suction_point: Пожарный пирс water_tank: Пожарный водоём/резервуар highway: abandoned: Заброшенная дорога @@ -1216,6 +1222,7 @@ ru: beach_resort: Пляж с насаждениями bird_hide: Засидка (пункт скрытого наблюдения за птицами) bleachers: Трибуны + bowling_alley: Дорожка для боулинга common: Общественно-доступная земля dance: Танцевальный зал dog_park: Площадка для собак @@ -1225,7 +1232,7 @@ ru: fitness_station: Тренажёр garden: Сад golf_course: Поле для гольфа - horse_riding: Конная база + horse_riding: Центр верховой езды ice_rink: Каток marina: Пристань miniature_golf: Минигольф @@ -3001,7 +3008,6 @@ ru: show: Просмотреть эту блокировку back: Просмотреть все блокировки filter: - block_expired: Блокировка уже закончилась и не может быть отредактирована. block_period: Период блокировки должен быть одним из значений, выбираемых из выпадающего списка. create: diff --git a/config/locales/sc.yml b/config/locales/sc.yml index 2c21ee07e..c9eefb03c 100644 --- a/config/locales/sc.yml +++ b/config/locales/sc.yml @@ -2903,7 +2903,6 @@ sc: show: Pòmpia custu blocu back: Pòmpia totu sos blocos filter: - block_expired: Su blocu est giai iscadidu e non si podet modificare. block_period: Su perìodu de blocu depet èssere unu de sos valores chi si podent seletzionare dae sa lista a calada. create: diff --git a/config/locales/scn.yml b/config/locales/scn.yml index a3308824b..3a61ab83b 100644 --- a/config/locales/scn.yml +++ b/config/locales/scn.yml @@ -1874,7 +1874,6 @@ scn: show: Talìa stu bloccu back: Talìa tutti li blocchi filter: - block_expired: Lu bloccu già scadìu e nun si pò canciari. block_period: Lu pirìudu di bloccu havi a èssiri unu dî valuri chi si ponnu scègghiri di l'elencu a scinnuta. create: diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 5e8369c33..19b8ad615 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -2729,7 +2729,6 @@ sk: show: ZobraziÅ¥ tento blok back: ZobraziÅ¥ vÅ¡etky bloky filter: - block_expired: Blok už vyprÅ¡al a nemôže byÅ¥ upravený. block_period: Blokovacia doba musí byÅ¥ jedna z hodnôt voliteľná v roletovom menu. create: diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 1203d9d3f..a8ac63113 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -2725,6 +2725,8 @@ sl: write_notes: Spreminjanje opomb write_redactions: Skrij podatke na zemljevidu read_email: Branje uporabnikovega e-poÅ¡tnega naslova + consume_messages: Branje, posodabljanje stanja in brisanje uporabniÅ¡kih sporočil + send_messages: PoÅ¡iljanje zasebnih sporočil drugim uporabnikom skip_authorization: Samodejna odobritev aplikacije for_roles: moderator: To dovoljenje je za dejanja, ki so na voljo samo moderatorjem @@ -3028,7 +3030,6 @@ sl: show: Prikaži blokiranje back: Prikaži vsa blokiranja filter: - block_expired: Blokiranje je že poteklo in ga ni mogoče urejati. block_period: Čas blokiranja mora biti ena od izbir s spustnega seznama vrednosti. create: flash: Ustvarjeno blokiranje uporabnika %{name}. diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index c20241b01..950b04562 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -1300,7 +1300,6 @@ sr-Latn: show: Pogledaj ovu blokadu back: Pogledaj sve blokade filter: - block_expired: Blokada je već istekla i ne može se uređivati. block_period: Period blokade mora biti jedna od vrednosti iz padajućeg spiska. create: flash: Blokiraj korisnika %{name}. diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 623cea7f3..195c559c5 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -2346,7 +2346,6 @@ sr: show: Погледај ову блокаду back: Погледај све блокаде filter: - block_expired: Блокада је већ истекла и не може се уређивати. block_period: Период блокаде мора бити једна од вредности из падајућег списка. create: flash: Блокирај корисника %{name}. diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 0730a2fab..61c145fdb 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -444,8 +444,8 @@ sv: relation: relation start_rjs: feature_warning: Laddar %{num_features} kartkomponenter, vilket kan göra din - webbläsare lÃ¥ngsam eller fÃ¥ den att sluta svara. Är säker pÃ¥ att du vill visa - denna data? + webbläsare lÃ¥ngsam eller fÃ¥ den att sluta svara. Är du säker pÃ¥ att du vill + visa denna data? load_data: Ladda data loading: Läser in … tag_details: @@ -614,6 +614,8 @@ sv: title: '%{user}s dagbok | %{title}' user_title: '%{user}s dagbok' discussion: Diskussion + subscribe: Prenumerera + unsubscribe: Avsluta prenumeration leave_a_comment: Lämna en kommentar login_to_leave_a_comment_html: '%{login_link} för att lämna en kommentar' login: Logga in @@ -673,6 +675,8 @@ sv: comment: Kommentar newer_comments: Nyare kommentarer older_comments: Äldre kommentarer + new: + heading: Lägg en kommentar pÃ¥ följande diskussion om dagboksinlägg? doorkeeper: errors: messages: @@ -907,6 +911,7 @@ sv: college: Högskolebyggnad commercial: Kommersiell byggnad construction: Byggnad under uppförande + cowshed: Kostall detached: FristÃ¥ende hus dormitory: Studenthem duplex: Dubbelhus @@ -936,6 +941,7 @@ sv: shed: Skjul stable: Stall static_caravan: Husvagn + sty: Stia temple: Tempelbyggnad terrace: Terrassbyggnad train_station: Järnvägsstation @@ -1643,6 +1649,8 @@ sv: intro_text: OpenStreetMap är en karta över världen, skapad av människor som du och fri att använda under en öppen licens. intro_2_create_account: Skapa ett användarkonto + hosting_partners_2024_html: Driften stöds av %{fastly}, %{corpmembers} och andra + %{partners}. partners_fastly: Fastly partners_corpmembers: OSMF-företagsmedlemmar partners_partners: partners @@ -1921,6 +1929,9 @@ sv: new password button: Återställ lösenord help_text: Ange e-postadressen du använde för att registrera dig sÃ¥ skickar vi en länk till den som du kan använda för att Ã¥terställa ditt lösenord. + create: + send_paranoid_instructions: Om din e-postadress finns i vÃ¥r databas kommer du + fÃ¥ ett e-postmeddelande för att bekräfta din e-postadress pÃ¥ nÃ¥gra minuter. edit: title: Återställ lösenord heading: Återställ lösenord för %{user} @@ -2140,6 +2151,9 @@ sv: contributors_at_cc_by: CC BY contributors_at_land_vorarlberg: Förbundsland Vorarlberg contributors_at_cc_by_at_with_amendments: CC BY AT med tillägg + contributors_au_credit_html: '%{australia}: Inkorporerades eller utvecklades + med hjälp av administrativa gränser © %{geoscape_australia_link} licensierades + av Samväldet Australien under %{cc_licence_link}.' contributors_au_australia: Australien contributors_au_geoscape_australia: Geoscape Australien contributors_au_cc_licence: Creative Commons Erkännande 4.0 Internationell-licens @@ -2168,6 +2182,7 @@ sv: och %{open_data_portal} (offentlig information om Kroatien)' contributors_hr_croatia: Kroatien contributors_hr_dgu: Kroatiens statliga geodatiska förvaltning + contributors_hr_open_data_portal: Nationella öppen data-portalen contributors_nl_credit_html: '%{netherlands}: InnehÃ¥ller © AND data, 2007 (%{and_link}).' contributors_nl_netherlands: Nederländerna @@ -2198,6 +2213,7 @@ sv: contributors_za_credit_html: '%{south_africa}: InnehÃ¥ller data frÃ¥n %{ngi_link}, statens upphovsrätt förbehÃ¥lls.' contributors_za_south_africa: Sydafrika + contributors_za_ngi: 'Chief Directorate: National Geo-Spatial Information' contributors_gb_credit_html: '%{united_kingdom}: InnehÃ¥ller Ordnance Survey data © Crown copyright and database right 2010-2023.' contributors_gb_united_kingdom: Storbritannien @@ -2644,25 +2660,26 @@ sv: oauth2_authorizations: OAuth 2-auktoriseringar muted_users: Tystade användare auth_providers: + openid_url: OpenID-URL openid_login_button: Fortsätt openid: title: Logga in med OpenID - alt: Logga in med en OpenID-URL + alt: OpenID-logotyp google: title: Logga in med Google - alt: Logga in med ett Google OpenID + alt: Google-logotyp facebook: title: Logga in med Facebook - alt: Logga in med ett Facebook-konto + alt: Facebook-logotyp microsoft: title: Logga in med Microsoft - alt: Logga in med ett Microsoft-konto + alt: Microsoft-logotyp github: title: Logga in med GitHub - alt: Logga in med ett GitHub-Konto + alt: GitHub-logotyp wikipedia: title: Logga in med Wikipedia - alt: Logga in med ett Wikipedia-konto + alt: Wikipedia-logotyp oauth: authorize: title: Auktorisera tillgÃ¥ng till ditt konto @@ -2817,9 +2834,14 @@ sv: ner och använda. paragraph_2: Registrera dig för att börja bidra. welcome: Välkommen till OpenStreetMap + duplicate_social_email: Om du redan har ett OpenStreetMap-konto och vill använda + en identitetsleverantör frÃ¥n en tredjepart, kan du logga in med ditt lösenord + och modifiera inställningarna för ditt konto. display name description: Ditt offentligt visade användarnamn. Du kan ändra detta senare i alternativ. by_signing_up: + html: Genom att registrera dig accepterar du vÃ¥r %{tou_link}, %{privacy_policy_link} + och %{contributor_terms_link}. privacy_policy: integritetspolicy privacy_policy_title: OSMFs integritetspolicy inklusive avsnitt om e-postadresser contributor_terms: bidragsvillkor @@ -2829,6 +2851,8 @@ sv: terms accepted: Tack för att du accepterat de nya villkoren för bidrag till kartan! email_help: + privacy_policy: integritetspolicy + privacy_policy_title: OSMF:s integritetspolicy inkluderingsavsnitt om e-postadresser html: Din adress visas inte offentligt, se vÃ¥r %{privacy_policy_link} för mer information. consider_pd_html: Jag anser mina bidrag vara i %{consider_pd_link}. @@ -2900,6 +2924,8 @@ sv: remove as friend: Ta bort vän add as friend: Lägg till vän mapper since: 'Karterar sedan:' + last map edit: 'Senaste kartredigering:' + no activity yet: Ännu ingen aktivitet uid: 'Användar id:' ct status: 'Användarvillkor:' ct undecided: Ej bestämda @@ -3016,13 +3042,14 @@ sv: show: Visa denna blockering back: Visa alla blockeringar filter: - block_expired: Blockeringen har redan upphört att gälla och kan inte redigeras. block_period: Blockeringsperioden mÃ¥ste ha ett av värdena i rullgardinslistan. create: flash: Upprättade en blockering av användare %{name}. update: only_creator_can_edit: Bara moderatorn som skapade denna blockering kan redigera den. + only_creator_or_revoker_can_edit: Endast moderatorer som skapade eller drog + tillbaka den här blockeringen kan redigera den. success: Blockering uppdaterad. index: title: Användarblockeringar @@ -3203,14 +3230,15 @@ sv: custom_dimensions: Ange anpassade dimensioner format: 'Format:' scale: 'Skala:' - image_dimensions: Bilden kommer visa standardlager pÃ¥ %{width} x %{height} + image_dimensions: Bilden kommer visa lager %{layer} pÃ¥ %{width} x %{height} download: Ladda ned short_url: Kortlänk include_marker: Lägg till markör center_marker: Centrera kartan pÃ¥ markören paste_html: Klistra in HTML-koden för att publicera pÃ¥ en webbsida view_larger_map: Visa större karta - only_standard_layer: Endast standardlagret kan exporteras som en bild + only_standard_layer: Endast lagrena Standard, Cykelkarta och Transport kan exporteras + som en bild embed: report_problem: Rapportera ett problem key: diff --git a/config/locales/te.yml b/config/locales/te.yml index cc11d5d45..5633e0b8d 100644 --- a/config/locales/te.yml +++ b/config/locales/te.yml @@ -2300,7 +2300,6 @@ te: show: ఈ నిరోధాన్ని చూడండి back: అన్ని నిరోధాలను చూడండి filter: - block_expired: నిరోధం ఈసరికే ముగిసిపోయింది. దాన్ని సవరించలేరు. block_period: నిరోధ కాలం డ్రాప్ డౌన్ జాబితా లోంచి ఎంచుకునే విలువల్లో ఒకటై ఉండాలి. create: flash: వాడుకరి %{name} పై నిరోధం సృష్టించారు. diff --git a/config/locales/th.yml b/config/locales/th.yml index 7d8a2b485..12cec4ce3 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -2306,7 +2306,6 @@ th: show: ดูรายละเอียดการระงับนี้ back: แสดงการกีดกันทั้งหมด filter: - block_expired: การกีดกันนี้สิ้นผลแล้วแก้ไขไม่ได้ block_period: ดูระยะเวลาที่ระงับ ให้เป็นหนึ่งในค่าที่เลือกไว้จากรายการนี้ update: only_creator_can_edit: การระงับนี้สามารถแก้ไขได้ โดยผู้ดูแลที่เป็นผู้สั่งระงับเองเท่านั้น diff --git a/config/locales/tl.yml b/config/locales/tl.yml index 65aedc8a7..15de8f6ed 100644 --- a/config/locales/tl.yml +++ b/config/locales/tl.yml @@ -2039,7 +2039,6 @@ tl: show: Tingnan ang hadlang na ito back: Tingnan ang lahat ng mga paghadlang filter: - block_expired: Napaso na ang pagharang at hindi na mababago pa. block_period: Ang panahon ng pagharang ay dapat na isa sa mga halagang mapipili sa loob ng talaang naibabagsak na paibaba. create: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 655bbd08a..d44f9418b 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -2613,8 +2613,8 @@ tr: trace: pending: BEKLEMEDE count_points: - one: '%{count} puan' - other: '%{count} puan' + one: '%{count} nokta' + other: '%{count} nokta' more: daha fazla trace_details: İz Ayrıntılarını Görüntüle view_map: Haritayı Görüntüle @@ -3057,7 +3057,6 @@ tr: show: Bu engellemeyi gör back: Tüm engellemeleri göster filter: - block_expired: Engelin süresi dolmuş ve değiştirilemiyor. block_period: Engel süresi, açılır listeden seçilebilen değerlerden biri olmalıdır. create: flash: '%{name} kullanıcısına engel oluşturuldu.' diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 580c25f90..3b7647e52 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -3100,7 +3100,6 @@ uk: show: Переглянути блокування back: Переглянути всі блокування filter: - block_expired: Блокування вже закінчилось і не може бути змінено. block_period: Період блокування повинен бути одним зі значень зі списку, що розкривається. create: diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 53ffcbdff..3a36ac507 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -2836,7 +2836,6 @@ vi: show: Xem tác vụ cấm này back: Xem tất cả tác vụ cấm filter: - block_expired: Không thể sá»­a đổi tác vụ cấm này vì nó đã hết hạn. block_period: Thời hạn cấm phải là một trong những giá trị từ danh sách kéo xuống. create: diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index ba56b9f24..46a72f47a 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -1649,6 +1649,7 @@ zh-CN: tou: 使用条款 osm_offline: 由于正在进行基本的数据库维护工作,OpenStreetMap 数据库目前处于脱机状态。 osm_read_only: 由于正在进行基本的数据库维护工作,OpenStreetMap 数据库目前处于只读模式。 + nothing_to_preview: 无可预览内容。 donate: 通过给硬件升级基金%{link}支持 OpenStreetMap。 help: 帮助 about: 关于 @@ -1689,17 +1690,22 @@ zh-CN: befriend_them: 您也可以在 %{befriendurl} 添加他们为朋友。 befriend_them_html: 您也可以在%{befriendurl}把他们添加为朋友。 gpx_description: + description_with_tags: 看起来您的GPX文件%{trace_name}(描述为%{trace_description},带如下标签:%{tags}) description_with_tags_html: 您的GPX文件 %{trace_name} ,其描述为 %{trace_description} 并有以下标签: %{tags} + description_with_no_tags: 看起来您的GPX文件%{trace_name}(描述为%{trace_description},不带标签) description_with_no_tags_html: 似乎您的GPX文件%{trace_name},描述为%{trace_description},没有标签 gpx_failure: hi: 您好,%{to_user}: failed_to_import: 导入失败。下面是错误信息: + more_info: 更多有关GPX导入失败的信息及如何避免这些问题,可以在%{url}找到。 more_info_html: 更多关于 GPX 导入失败的信息,以及如何避免失败可在%{url}找到。 subject: '[OpenStreetMap] GPX 导入失败' gpx_success: hi: 您好,%{to_user}: loaded: 已成功加载%{count}个可能轨迹点中的%{trace_points}个。 + trace_location: 您的轨迹可在%{trace_url}查看 + all_your_traces: 您可以在%{url}找到所有您成功上传的GPX轨迹 all_your_traces_html: 您可以在 %{url} 找到所有您成功上传的 GPX 轨迹。 subject: '[OpenStreetMap] GPX 导入成功' signup_confirm: @@ -2225,7 +2231,7 @@ zh-CN: trunk: 主干道路 primary: 一级道路 secondary: 二级道路 - unclassified: 无等级道路 + unclassified: 等外道路 pedestrian: 人行道 track: 小路 bridleway: 马道 @@ -2268,7 +2274,7 @@ zh-CN: retail: 零售区 industrial: 工业区 commercial: 商业区 - heathland: 荒原 + heathland: 欧石楠荒地 scrubland: 灌木丛林地 lake: 湖 reservoir: 水库 @@ -2526,6 +2532,8 @@ zh-CN: write_notes: 修改备注 write_redactions: 隐删地图数据 read_email: 查看用户邮箱地址 + consume_messages: 读取、更新状态和删除用户留言 + send_messages: 向其他用户发送私信 skip_authorization: 自动核准应用 for_roles: moderator: 此权限仅适用于仲裁员可用的操作。 @@ -2807,12 +2815,12 @@ zh-CN: show: 查看此封禁 back: 查看所有封禁 filter: - block_expired: 这个封禁已经过期,并且不能再编辑。 block_period: 封禁时期必须是在下拉菜单中可选择的数值之一。 create: flash: 已建立对用户 %{name} 的封禁 update: only_creator_can_edit: 只有执行此封禁的仲裁员才能编辑。 + only_creator_or_revoker_can_edit: 只有建立或撤销此封禁的仲裁员才能编辑。 success: 封禁已更新。 index: title: 用户的封禁 @@ -2982,14 +2990,14 @@ zh-CN: custom_dimensions: 设定自定义区域 format: 格式: scale: 比例: - image_dimensions: 将以%{width} x %{height}的尺寸按标准图层输出图像 + image_dimensions: 将以%{width} x %{height}的尺寸按%{layer}图层输出图像 download: 下载 short_url: 短URL include_marker: 包含标记 center_marker: 以标记作为地图中心 paste_html: 粘贴HTML以嵌入网站 view_larger_map: 查看更大的地图 - only_standard_layer: 只有标准图层可被导出为图片 + only_standard_layer: 只有标准图层、自行车地图和交通运输图层可被导出为图片 embed: report_problem: 报告问题 key: diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index aa2cdb135..732499dc2 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -39,6 +39,7 @@ # Author: SupaplexTW # Author: Tntchn # Author: TongcyDai +# Author: Wayne Su # Author: Wehwei # Author: WiiUf # Author: Winston Sung @@ -89,7 +90,7 @@ zh-TW: messages: invalid_email_address: 似乎不是有效的電子郵件信箱地址。 email_address_not_routable: 不可發送 - display_name_is_user_n: 不能是「user_n」除非「n」是您的使用者 ID + display_name_is_user_n: 不能是「user_n」,除非「n」是你的使用者 ID models: user_mute: is_already_muted: 已忽視 @@ -124,21 +125,21 @@ zh-TW: tracetag: 軌跡標籤 user: 使用者 user_preference: 使用者偏好設定 - user_token: 使用者Token + user_token: 使用者授權密鑰 way: 路徑 way_node: 路徑節點 way_tag: 路徑標籤 attributes: client_application: - name: 名稱(必填) - url: 主要應用程式 URL(必填) + name: 名稱 (必填) + url: 主要應用程式 URL (必填) callback_url: 回撥 (Callback) URL support_url: 支援 URL allow_read_prefs: 讀取使用者偏好設定 allow_write_prefs: 修改使用者偏好設定 allow_write_diary: 建立日記、評論和加入好友 allow_write_api: 修改地圖 - allow_read_gpx: 讀取個人GPS軌跡 + allow_read_gpx: 讀取個人 GPS 軌跡 allow_write_gpx: 上傳 GPS 軌跡 allow_write_notes: 修改註記 diary_comment: @@ -197,7 +198,7 @@ zh-TW: pass_crypt_confirmation: 確認密碼 help: doorkeeper/application: - confidential: 應用程式會在客戶端密鑰可以維持機密時使用(本地端移動應用程式和單一頁面應用程式不保密) + confidential: 應用程式會在客戶端密鑰可以維持機密時使用 (本地端移動應用程式和單一頁面應用程式不保密) redirect_uri: 每條 URI 使用一行 trace: tagstring: 以逗點分隔 @@ -270,7 +271,7 @@ zh-TW: opened: 新的註記 (在 %{place} 附近) commented: 新的評論 (在 %{place} 附近) closed: 關閉的註記 (在 %{place} 附近) - reopened: 重新開啟的註記(在%{place}附近) + reopened: 重新開啟的註記 (在%{place}附近) entry: comment: 評論 full: 註記原文 @@ -407,7 +408,7 @@ zh-TW: way: 路徑 relation: 關聯 start_rjs: - feature_warning: 載入 %{num_features} 項物件的資料,可能使您的瀏覽器延遲或無法回應。您是否想要顯示這些資料嗎? + feature_warning: 載入 %{num_features} 項物件的資料,可能會使你的瀏覽器延遲或無法回應。你確定要顯示這些資料嗎? load_data: 載入資料 loading: 正在載入… tag_details: @@ -442,7 +443,7 @@ zh-TW: previous: « 上一頁 changeset: anonymous: 匿名 - no_edits: (沒有編輯) + no_edits: (沒有編輯) view_changeset_details: 檢視變更集詳細資料 changesets: id: ID @@ -481,7 +482,7 @@ zh-TW: no_such_entry: title: 沒有這樣的變更集 heading: 沒有 id 為 %{id} 的項目 - body: 抱歉,沒有 id 為 %{id} 的變更集。請檢查您的拼字,或者可能是您按到錯誤的連結。 + body: 抱歉,沒有 id 為 %{id} 的變更集。請檢查你的拼字,或者可能是你按到錯誤的連結。 show: title: 變更集:%{id} created: 建立於:%{when} @@ -510,7 +511,7 @@ zh-TW: relations: 關聯 (%{count}) relations_paginated: 關聯 (%{count} 的 %{x}-%{y}) timeout: - sorry: 很抱歉,您請求的變更集清單過長無法讀取。 + sorry: 很抱歉,你請求的變更集清單過長無法讀取。 changeset_comments: comment: comment: '由 %{author} 對變更集 #%{changeset_id} 發表的新評論' @@ -521,22 +522,22 @@ zh-TW: title_all: OpenStreetMap 變更集討論 title_particular: OpenStreetMap 變更集 %{changeset_id} 討論 timeout: - sorry: 很抱歉,您請求的變更集評論過長無法讀取 + sorry: 很抱歉,你請求的變更集評論過長無法讀取 dashboards: contact: km away: '%{count} 公里遠' m away: '%{count} 公尺遠' latest_edit_html: 上次編輯於%{ago}: popup: - your location: 您的位置 + your location: 你的位置 nearby mapper: 附近的製圖者 friend: 好友 show: title: 我的功能面板 - no_home_location_html: '%{edit_profile_link}並編輯您的家位置,來查看附近的使用者。' - edit_your_profile: 編輯您的個人檔案 + no_home_location_html: '%{edit_profile_link}並編輯你的家位置,來查看附近的使用者。' + edit_your_profile: 編輯你的個人檔案 my friends: 我的好友 - no friends: 您尚未加入任何好友。 + no friends: 你尚未加入任何好友。 nearby users: 其他附近的使用者 no nearby users: 附近沒有已加入製圖的使用者。 friends_changesets: 好友的變更集 @@ -577,7 +578,7 @@ zh-TW: no_such_entry: title: 沒有這樣的日記項目 heading: 沒有 id 為 %{id} 的項目 - body: 抱歉,沒有日記項目或評論的 id 是 %{id}。請檢查您的拼字,或者可能是您按到錯誤的連結。 + body: 抱歉,沒有日記項目或評論的 id 是 %{id}。請檢查你的拼字,或者可能是你按到錯誤的連結。 diary_entry: posted_by_html: 於 %{created} 由 %{link_user} 以%{language_link}發表。 updated_at_html: 上一次更新在 %{updated}。 @@ -653,44 +654,44 @@ zh-TW: 缺少設置導致失敗。 select_account_for_resource_owner_not_configured: 因 Doorkeeper::OpenidConnect.configure.select_account_for_resource_owner 缺少設置導致失敗。 subject_not_configured: 因 Doorkeeper::OpenidConnect.configure.subject 缺少配置,產生 - ID 權杖失敗。 + ID 授權密鑰失敗。 scopes: - address: 查看您的實際地址 - email: 查看您的電子郵件位址 - openid: 驗證您的帳號 - phone: 查看您的電話號碼 - profile: 查看您的個人資訊 + address: 查看你的實際地址 + email: 查看你的電子郵件信箱 + openid: 驗證你的帳號 + phone: 查看你的電話號碼 + profile: 查看你的個人資訊 errors: contact: contact_url_title: 各種聯絡管道說明 contact: 聯絡 - contact_the_community_html: 如果您發現有損壞的連結/錯誤,請隨時%{contact_link}OpenStreetMap 社群。並請記下您的請求的確切 - URL 位址。 + contact_the_community_html: 如果你發現有損壞的連結/錯誤,請隨時%{contact_link}OpenStreetMap 社群。並請記下你的請求的確切 + URL 網址。 bad_request: title: 錯誤請求 - description: 您在 OpenStreetMap 伺服器上請求的操作無效(HTTP 400) + description: 你在 OpenStreetMap 伺服器上請求的操作無效 (HTTP 400) forbidden: title: Forbidden - description: 您在 OpenStreetMap 伺服器上請求的運作僅限管理員使用(HTTP 403) + description: 你在 OpenStreetMap 伺服器上請求的運作僅限管理員使用 (HTTP 403} internal_server_error: title: 應用程式錯誤 - description: OpenStreetMap 伺服器遇到意外情況,而無法滿足請求(HTTP 500) + description: OpenStreetMap 伺服器遇到意外情況,而無法滿足請求 (HTTP 500) not_found: title: 檔案未找到 - description: 在 OpenStreetMap 伺服器上找不到該名稱的檔案/目錄/API 操作(HTTP 404) + description: 在 OpenStreetMap 伺服器上找不到該名稱的檔案/目錄/API 操作 (HTTP 404) friendships: make_friend: heading: 將 %{user} 加入為好友? button: 加入為好友 - success: '%{name} 現在已成為您的好友!' + success: '%{name} 現在已成為你的好友!' failed: 抱歉,無法將 %{name} 加入為好友。 - already_a_friend: 您已經是 %{name} 的好友了。 - limit_exceeded: 您最近與許多使用者成為朋友。在與其他人成為朋友前請稍候。 + already_a_friend: 你已經是 %{name} 的好友了。 + limit_exceeded: 你最近與許多使用者成為朋友,要再與其他人成為朋友前請稍候。 remove_friend: heading: 移除好友 %{user}? button: 移除好友 - success: '%{name} 已從您的好友中移除。' - not_a_friend: '%{name} 並不是您的好友。' + success: '%{name} 已從你的好友中移除。' + not_a_friend: '%{name} 並不是你的好友。' geocoder: search: title: @@ -702,43 +703,43 @@ zh-TW: prefix: aerialway: cable_car: 大型纜車 - chair_lift: 升降吊椅 - drag_lift: 上山牽引梯 + chair_lift: 吊椅式索道 + drag_lift: 拖拉式索道 gondola: 小型纜車 - magic_carpet: 滑雪升降機 - platter: 纜椅 - pylon: 高壓電塔 - station: 空中纜車車站 - t-bar: T 字纜椅 - "yes": 空中纜線 + magic_carpet: 魔毯 (自動步道) + platter: 圓盤拖拉式索道 + pylon: 塔柱 + station: 纜車站 + t-bar: T 型桿拖拉式索道 + "yes": 空中索道 aeroway: aerodrome: 機場 - airstrip: 飛機跑道 + airstrip: 簡易跑道 apron: 停機坪 gate: 登機口 hangar: 機棚 helipad: 直升機停機坪 holding_position: 等待位置 navigationaid: 航空導航輔助 - parking_position: 停車位置 + parking_position: 停放位置 runway: 跑道 taxilane: 滑行道 taxiway: 滑行道 - terminal: 航廈 - windsock: 布製風標 + terminal: 機場航廈 + windsock: 風向袋 amenity: - animal_boarding: 動物寄宿 + animal_boarding: 寵物旅館 animal_shelter: 動物收容所 arts_centre: 藝術中心 - atm: 提款機 + atm: 自動提款機 bank: 銀行 bar: 酒吧 - bbq: 烤肉場 + bbq: 公共烤爐 bench: 長椅 bicycle_parking: 自行車停車場 bicycle_rental: 自行車出租 bicycle_repair_station: 自行車維修站 - biergarten: 啤酒庭園 + biergarten: 露天啤酒場 blood_bank: 血液銀行 boat_rental: 船艇出租 brothel: 妓院 @@ -746,7 +747,7 @@ zh-TW: bus_station: 公車站 cafe: 咖啡廳 car_rental: 汽車出租 - car_sharing: 汽車共乘 + car_sharing: 共享汽車 car_wash: 洗車 casino: è³­å ´ charging_station: 充電站 @@ -760,7 +761,7 @@ zh-TW: courthouse: 法院 crematorium: 火葬場 dentist: 牙醫 - doctors: 醫師 + doctors: 私人診所 drinking_water: 飲用水 driving_school: 駕訓班 embassy: 大使館 @@ -771,11 +772,11 @@ zh-TW: food_court: 美食廣場 fountain: 噴泉 fuel: 加油站 - gambling: 博弈店 - grave_yard: 墓園 + gambling: 賭博店 + grave_yard: 宗教墓地 grit_bin: 砂箱 hospital: 醫院 - hunting_stand: 狩獵站 + hunting_stand: 狩獵小屋 ice_cream: 冰淇淋 internet_cafe: 網咖 kindergarten: 幼兒園 @@ -787,23 +788,23 @@ zh-TW: mobile_money_agent: 行動支付代理 monastery: 修道院 money_transfer: 匯款 - motorcycle_parking: 機車停車場 + motorcycle_parking: 摩托車停車場 music_school: 音樂學校 - nightclub: 夜總會 - nursing_home: 療養院 + nightclub: 夜店 + nursing_home: 照護中心 parking: 停車場 parking_entrance: 停車場入口 parking_space: 停車位 - payment_terminal: 互動式資訊服務站 + payment_terminal: 付費資訊服務站 pharmacy: 藥房 - place_of_worship: 禮拜場所 + place_of_worship: 宗教場所 police: 警察 post_box: 郵筒 post_office: 郵局 prison: 監獄 pub: 酒館 - public_bath: 公共浴場 - public_bookcase: 公共書櫃 + public_bath: 公共澡堂 + public_bookcase: 街頭書櫃 public_building: 公共建築 ranger_station: 巡山員站 recycling: 回收點 @@ -811,16 +812,16 @@ zh-TW: sanitary_dump_station: 衛生排污站 school: 學校 shelter: 涼亭 - shower: 淋浴 - social_centre: 聚會所 + shower: 淋浴間 + social_centre: 社會團體中心 social_facility: 社會福利設施 - studio: 錄音室 + studio: 工作室 swimming_pool: 游泳池 taxi: 計程車 telephone: 公共電話 theatre: 劇院 toilets: 廁所 - townhall: 政府大廈 + townhall: 鄉鎮公所 training: 訓練設施 university: 大學 vehicle_inspection: 車輛檢驗 @@ -830,8 +831,8 @@ zh-TW: waste_basket: 垃圾桶 waste_disposal: 垃圾子車 waste_dump_site: 垃圾掩埋場 - watering_place: 集水地點 - water_point: 取水點 + watering_place: 動物飲水處 + water_point: 供水點 weighbridge: 地磅 "yes": 便利設施 boundary: @@ -844,29 +845,29 @@ zh-TW: "yes": 邊界 bridge: aqueduct: 高架水道 - boardwalk: 木板走道 + boardwalk: 木棧走道 suspension: 吊橋 - swing: 平旋橋 + swing: 平轉橋 viaduct: 高架橋 - "yes": 橋 + "yes": 橋樑 building: apartment: 公寓 apartments: 公寓 barn: 穀倉 bungalow: 平房 cabin: 小木屋 - chapel: 禮拜堂 + chapel: 小聖堂 church: 教堂建築 civic: 城市建築 college: 學院建物 commercial: 商業建築 - construction: 在建建築 + construction: 興建中建築 cowshed: 牛棚 - detached: 獨立式住宅 + detached: 獨立透天厝 dormitory: 宿舍 duplex: 複式住宅 farm: 農舍 - farm_auxiliary: 附屬農舍建築 + farm_auxiliary: 農業設施 garage: 車庫 garages: 車庫 greenhouse: 溫室 @@ -882,115 +883,115 @@ zh-TW: office: 辦公建築 public: 公共建築 residential: 住宅建築 - retail: 零售建物 + retail: 零售商建物 roof: 屋頂 - ruins: 已毀損建築 + ruins: 毀損建築 school: 學校建物 - semidetached_house: 半獨立房 + semidetached_house: 半獨立房屋 service: 服務建築 - shed: 舍 + shed: 工寮 stable: 馬廄 static_caravan: 旅行拖車 sty: 豬圈 - temple: 廟宇建築 - terrace: 排屋 + temple: 寺廟建築 + terrace: 連棟透天厝 train_station: 車站建物 university: 大學建築 warehouse: 倉庫 "yes": 建築物 club: - scout: 童軍團團部 + scout: 童軍團本部 sport: 運動俱樂部 "yes": 俱樂部 craft: - beekeeper: 養蜂人家 + beekeeper: 養蜂人 blacksmith: 鐵匠 - brewery: 釀酒廠 + brewery: 地方小型釀造廠 carpenter: 木匠 - caterer: 外燴承辦 - confectionery: 糖果店 + caterer: 宴會承辦 + confectionery: 甜點店 dressmaker: 女裝裁縫 - electrician: 電工 - electronics_repair: 電子維修 - gardener: 園丁 - glaziery: 玻璃工 + electrician: 電匠 + electronics_repair: 電器維修 + gardener: 園藝師 + glaziery: 玻璃匠 handicraft: 手工藝 - hvac: 暖通空調製作 - metal_construction: 金屬建造 - painter: 畫家 + hvac: 暖通空調工程 + metal_construction: 金屬加工 + painter: 油漆匠 photographer: 攝影師 - plumber: 管道工 - roofer: 屋頂工 - sawmill: 鋸木廠 + plumber: 水管工 + roofer: 屋頂修繕 + sawmill: 製材廠 shoemaker: 鞋匠 - stonemason: 石工 + stonemason: 石匠 tailor: 裁縫師 - window_construction: 窗戶建設 + window_construction: 窗戶工程 winery: 酒廠 - "yes": 工藝品店 + "yes": 專業技術服務 emergency: - access_point: 進入點 - ambulance_station: 急救站 - assembly_point: 集合處 - defibrillator: 除顫器 + access_point: 急難地點指示 + ambulance_station: 救護站 + assembly_point: 避難場所 + defibrillator: 自動心臟去顫器 (AED) fire_extinguisher: 滅火器 - fire_water_pond: 消防水塘 + fire_water_pond: 消防用水池 landing_site: 緊急降落點 life_ring: 緊急救生圈 phone: 緊急電話 - siren: 緊急警報器 - suction_point: 緊急吸水點 + siren: 警報器 + suction_point: 消防用水抽取點 water_tank: 緊急水箱 highway: abandoned: 廢棄道路 - bridleway: 馬車道 - bus_guideway: 導向公車道 - bus_stop: 公車站 - construction: 建造中道路 + bridleway: 騎馬道 + bus_guideway: 導軌巴士車道 + bus_stop: 公車站牌 + construction: 興建中道路 corridor: 走廊 - crossing: 路口 + crossing: 行人穿越道 cycleway: 自行車道 elevator: 電梯 - emergency_access_point: 緊急聯絡點 + emergency_access_point: 急難地點指示 emergency_bay: 緊急臨停空間 footway: 步道 - ford: 河床便道 - give_way: 讓路標誌 + ford: 須涉水 + give_way: 前方優先標誌 living_street: 生活街道 milestone: 里程標 motorway: 高速公路 - motorway_junction: 高速公路出口 - motorway_link: 高速公路聯絡道 + motorway_junction: 高速公路交流道 + motorway_link: 高速公路匝道 passing_place: 避車彎 path: 小徑 pedestrian: 人行道 platform: 月台 - primary: 一級道路 - primary_link: 一級道路聯絡道 + primary: 省道 + primary_link: 省道聯絡道 proposed: 計畫中道路 raceway: 賽道 residential: 住宅區道路 rest_area: 休息區 road: 道路 - secondary: 二級道路 - secondary_link: 二級道路聯絡道 - service: 服務道路 + secondary: 縣道 + secondary_link: 縣道聯絡道 + service: 專用道路 services: 高速公路服務區 - speed_camera: 測速照相機 + speed_camera: 測速相機 steps: 階梯 stop: 停止標誌 street_lamp: 路燈 - tertiary: 三級道路 - tertiary_link: 地區道路聯絡道 + tertiary: 鄉道 + tertiary_link: 鄉道聯絡道 track: 產業道路 traffic_mirror: 道路反射鏡 traffic_signals: 交通號誌 - trailhead: 小徑入口處 - trunk: 快速道路 - trunk_link: 快速道路聯絡道 - turning_circle: 回轉圈 + trailhead: 步道起點 + trunk: 快速公路 + trunk_link: 快速公路匝道 + turning_circle: 迴轉空間 turning_loop: 環形迴車道 - unclassified: 無編制道路 + unclassified: 未分級道路 "yes": 道路 historic: aircraft: 歷史飛行機 @@ -1002,98 +1003,98 @@ zh-TW: bunker: 掩體 cannon: 古砲 castle: 城堡 - charcoal_pile: 歷史木炭堆 + charcoal_pile: 古炭窯 church: 教堂 city_gate: 城門 citywalls: 城牆 fort: 堡壘 - heritage: 遺蹟 - hollow_way: 低窪道路 - house: 房屋 + heritage: 古蹟 + hollow_way: 古道 + house: 老屋 manor: 莊園 - memorial: 紀念館 + memorial: 紀念物 milestone: 歷史里程碑 mine: 礦場 - mine_shaft: 礦井 - monument: 古蹟 + mine_shaft: 豎井 + monument: 紀念建築 railway: 歷史鐵路 roman_road: 羅馬道路 - ruins: 廢墟 - rune_stone: 盧恩符文石 - stone: 石造史蹟 - tomb: 墳墓 + ruins: 遺跡 + rune_stone: 盧恩石刻 + stone: 史蹟石 + tomb: 墓園 tower: 塔 - wayside_chapel: 路邊教堂 - wayside_cross: 路邊十字架 - wayside_shrine: 路邊神龕 - wreck: 殘骸 + wayside_chapel: 小聖堂 + wayside_cross: 小十字架 + wayside_shrine: 小祠堂 + wreck: 沈船 "yes": 古蹟 junction: "yes": 路口 landuse: allotments: 社區農園 aquaculture: 水產養殖 - basin: 盆地 - brownfield: 低污染再利用地 - cemetery: 墓地 + basin: 蓄水池 + brownfield: 棕色地 (受污染放置待恢復重開發地) + cemetery: 公墓 commercial: 商業區 conservation: 保留區 - construction: 建造中區域 + construction: 工地 farmland: 農地 - farmyard: 農舍 + farmyard: 農用設施 forest: 人工林 - garages: 倉庫 + garages: 車庫 grass: 草坪 - greenfield: 空地 + greenfield: 綠色地 (未使用待開發地) industrial: 工業區 landfill: 垃圾掩埋場 meadow: 牧草地 military: 軍事區 mine: 礦場 orchard: 果園 - plant_nursery: 植物苗圃 - quarry: 露天礦場 + plant_nursery: 苗圃 + quarry: 砂石礦場 railway: 鐵路用地 - recreation_ground: 遊樂場 + recreation_ground: 遊樂區 religious: 宗教場地 - reservoir: 蓄水設施 - reservoir_watershed: 蓄水設施集水區 + reservoir: 水庫/大型蓄水池 + reservoir_watershed: 水庫集水區 residential: 住宅區 - retail: 零售區 + retail: 零售商區 village_green: 社區綠地 vineyard: 葡萄園 - "yes": 土地利用 + "yes": 土地用途 leisure: - adult_gaming_centre: 成人遊戲中心 + adult_gaming_centre: 成人遊樂中心 amusement_arcade: 電子遊樂場 - bandstand: 演奏台 - beach_resort: 海灘遊樂區 - bird_hide: 賞鳥亭 - bleachers: 露天看台 - bowling_alley: 保齡球場 - common: 公共用地 + bandstand: 室外音樂台 + beach_resort: æµ·æ°´æµ´å ´ + bird_hide: 野鳥觀察屋 + bleachers: 看台 + bowling_alley: 保齡球球道 + common: 共有地 dance: 舞廳 dog_park: 遛狗公園 - firepit: 火坑 - fishing: 垂釣區 + firepit: 營火場 + fishing: 釣魚區 fitness_centre: 健身中心 - fitness_station: 健身設施 - garden: 花園 - golf_course: 高爾夫球道 - horse_riding: 騎馬中心 + fitness_station: 戶外健身區 + garden: 庭園 + golf_course: 高爾夫球場 + horse_riding: 馬術中心 ice_rink: 溜冰場 - marina: 小船塢 - miniature_golf: 小型高爾夫球場 - nature_reserve: 自然保護區 + marina: 碼頭 + miniature_golf: 迷你高爾夫球場 + nature_reserve: 自然保育 outdoor_seating: 戶外座椅 park: 公園 picnic_table: 野餐桌 - pitch: 運動場 + pitch: 運動場地 playground: 遊樂區 - recreation_ground: 遊樂場 + recreation_ground: 遊樂區 resort: 度假村 sauna: 三溫暖 - slipway: 船臺 + slipway: 下水滑道 sports_centre: 運動中心 stadium: 體育館 swimming_pool: 游泳池 @@ -1101,55 +1102,55 @@ zh-TW: water_park: 水上樂園 "yes": 休閒 man_made: - adit: 坑道 + adit: 坑口 advertising: 廣告 antenna: 天線 avalanche_protection: 雪崩防護 - beacon: 信標台 + beacon: 信標/燈號 beam: 橫樑 beehive: 蜂巢 breakwater: 防波堤 - bridge: 橋 + bridge: 橋樑 bunker_silo: 掩體 - cairn: 石標 + cairn: 疊石 chimney: 煙囪 clearcut: 皆伐區域 communications_tower: 通訊塔 crane: 起重機 cross: 十字架 dolphin: 繫船柱 - dyke: å ¤ - embankment: å ¤ + dyke: 堤防 + embankment: 路堤 flagpole: 旗竿 - gasometer: 儲氣槽 + gasometer: 儲氣鼓 groyne: 丁壩 kiln: 窯 lighthouse: 燈塔 manhole: 人孔 - mast: 柱杆 + mast: 桅杆 mine: 礦場 - mineshaft: 礦井 - monitoring_station: 監控站台 + mineshaft: 豎井 + monitoring_station: 監測站 petroleum_well: 油井 pier: 碼頭 pipeline: 管線 - pumping_station: 泵站 - reservoir_covered: 有蓋蓄水槽 + pumping_station: 泵浦站 + reservoir_covered: 加蓋水庫/大型蓄水池 silo: 筒倉 snow_cannon: 雪砲 snow_fence: 雪欄 - storage_tank: 儲油罐 - street_cabinet: 街櫃 - surveillance: 監視攝影機 + storage_tank: 儲存槽 + street_cabinet: 路上設施箱 + surveillance: 監視器 telescope: 望遠鏡 tower: 塔 - utility_pole: 電線桿 - wastewater_plant: 污水處理處 + utility_pole: 多用途電桿 + wastewater_plant: 污水處理廠 watermill: 水車 water_tap: 水龍頭 water_tower: 水塔 - water_well: 牆 - water_works: 供水設施 + water_well: 水井 + water_works: 淨水廠 windmill: 風車 works: 工廠 "yes": 人工設施 @@ -1158,52 +1159,52 @@ zh-TW: barracks: 軍營 bunker: 掩體 checkpoint: 檢查站 - trench: 溝渠 + trench: 壕溝 "yes": 軍事 mountain_pass: "yes": 埡口 natural: atoll: 環礁 - bare_rock: 裸露岩石 + bare_rock: 裸岩 bay: 灣 beach: 海灘 cape: 海角 cave_entrance: 洞穴入口 - cliff: 懸崖 + cliff: 峭壁 coastline: 海岸線 crater: 火山口 dune: 沙丘 - fell: 高原荒地 + fell: 副寒帶、高山草苔 fjord: 峽灣 - forest: 管理林 + forest: 人工林 geyser: 間歇泉 glacier: 冰河 - grassland: 雜草地 + grassland: 草原 heath: 石楠荒地 - hill: 小山 + hill: 小山丘 hot_spring: 溫泉 island: å³¶å¶¼ isthmus: 地峽 land: 陸地 - marsh: 河川濕地 - moor: 停泊處 + marsh: 草沼澤 + moor: 泥炭沼 mud: 泥地 peak: 山峰 peninsula: 半島 point: 點 - reef: 礁 - ridge: 山脊 + reef: 暗礁 + ridge: 稜線 rock: 獨立岩 saddle: 鞍部 sand: 沙地 - scree: 碎石堆 + scree: 碎石坡 scrub: 灌木 - shingle: 礫石 - spring: 泉 + shingle: 礫石灘 + spring: 湧泉 stone: 巨石 strait: 海峡 - tree: 樹木 - tree_row: 行列樹木 + tree: 單棵樹 + tree_row: 一排樹 tundra: 苔原 valley: 谷地 volcano: 火山 @@ -1213,29 +1214,29 @@ zh-TW: "yes": 自然地貌 office: accountant: 會計師事務所 - administrative: 管理局 - advertising_agency: 廣告代理 + administrative: 政府機關 + advertising_agency: 廣告公司 architect: 建築師事務所 - association: 協會 + association: 非營利組織 company: 公司 - diplomatic: 使館 + diplomatic: 外國外交機關 educational_institution: 教育機構 - employment_agency: 人力仲介 - energy_supplier: 能源供應辦公處 + employment_agency: 就業服務/人材仲介 + energy_supplier: 能源供應商 estate_agent: 房地產仲介 - financial: 財務處 - government: 政府辦事處 - insurance: 保險公司辦公室 - it: IT 辦公室 - lawyer: 律師 + financial: 財務部門 + government: 政府機關 + insurance: 保險公司 + it: 資訊專家 + lawyer: 律師事務所 logistics: 物流辦公處 newspaper: 報社 - ngo: 非政府組織辦公室 - notary: 公證人 - religion: 宗教辦公處 - research: 研究室 + ngo: 非政府組織 + notary: 公證人事務所 + religion: 宗教組織 + research: 研發單位 tax_advisor: 稅務顧問 - telecommunication: 電信業辦事處 + telecommunication: 電信公司 travel_agent: 旅行社 "yes": 辦公室 place: @@ -1244,62 +1245,62 @@ zh-TW: city: 城市 city_block: 街區 country: 國家 - county: 縣 + county: 郡縣 farm: 農田 - hamlet: 村莊 + hamlet: 聚落 house: 房屋 houses: 房屋 - island: å³¶å¶¼ + island: 小島 islet: 礁岩 isolated_dwelling: 獨立住宅 - locality: 地區 - municipality: 自治市 - neighbourhood: 社區 - plot: 地塊 + locality: 地方 + municipality: 自治邦 + neighbourhood: 鄰近區 + plot: 社區 postcode: 郵遞區號 - quarter: 住處 - region: 區域 + quarter: 地區 + region: 區 sea: æµ· square: 廣場 - state: 省 - subdivision: 次分區 - suburb: 郊區 + state: 州 + subdivision: 行政分區 + suburb: 市區 town: 鄉鎮 village: 村里 "yes": 地點 railway: abandoned: 遺跡鐵路 - buffer_stop: 緩衝站 - construction: 建造中鐵路 + buffer_stop: 止衝擋 + construction: 興建中鐵路 disused: 廢棄鐵路 - funicular: 纜索鐵路 + funicular: 地索軌道鐵路 halt: 鐵路招呼站 junction: 鐵路交匯處 level_crossing: 平交道 light_rail: 輕軌 - miniature: 微型鐵路 + miniature: 小火車 monorail: 單軌鐵路 narrow_gauge: 窄軌鐵路 platform: 鐵路月臺 - preserved: 保留鐵路 + preserved: 保存線鐵路 proposed: 規劃中鐵路 rail: 鐵路 - spur: 鐵路支線 + spur: 鐵路專用側線 station: 鐵路車站 - stop: 鐵路招呼站 + stop: 鐵路停靠點 subway: 地下鐵 subway_entrance: 地下鐵出入口 switch: 道岔 tram: 路面電車軌道 tram_stop: 路面電車停靠站 - turntable: 轉盤 - yard: 鐵路站場 + turntable: 轉車台 + yard: 鐵路調車場 shop: - agrarian: 農業商品店 - alcohol: 酒館 + agrarian: 農業用品店 + alcohol: 酒舖 (未開瓶) antiques: 古董店 - appliance: 家用電器店 - art: 藝品店 + appliance: 家用電器行 + art: 藝術品店 baby_goods: 嬰兒用品 bag: 包包店 bakery: 麵包店 @@ -1308,82 +1309,82 @@ zh-TW: bed: 寢具 beverages: 飲料店 bicycle: 自行車店 - bookmaker: 投注處 + bookmaker: 簽注站 books: 書店 boutique: 精品店 butcher: 肉品店 - car: 汽車店 + car: 汽車經銷商 car_parts: 汽車零件 car_repair: 汽車維修 carpet: 地毯店 - charity: 慈善商店 - cheese: 起士店鋪 + charity: 公益商店 + cheese: 起士店 chemist: 藥妝店 - chocolate: 巧克力店鋪 + chocolate: 巧克力店 clothes: 服飾店 - coffee: 咖啡店 - computer: 電腦商店 + coffee: 咖啡豆專賣店 + computer: 電腦店 confectionery: 甜點店 - convenience: 便利商店 + convenience: 便利超商 copyshop: 複印店 cosmetics: 化妝品店 - craft: 工藝品供應店 + craft: 工藝用品店 curtain: 窗簾店 - dairy: 乳品店 - deli: 高級食品店 + dairy: 乳製品店 + deli: 高級食材店 department_store: 百貨商店 discount: 特價商品店 doityourself: DIY 用品店 - dry_cleaning: 乾洗 + dry_cleaning: 乾洗店 e-cigarette: 電子菸店 - electronics: 電子材料行 + electronics: 電器行 erotic: 情趣用品店 estate_agent: 房地產仲介 fabric: 布料行 - farm: 農場商店 - fashion: 時裝店 - fishing: 釣魚用品店 + farm: 農產直銷店 + fashion: 流行服飾店 + fishing: 釣具店 florist: 花店 food: 食品店 frame: 相框店 funeral_directors: 葬儀社 furniture: 傢俱行 garden_centre: 園藝中心 - gas: 加油站 + gas: 瓦斯行 general: 一般商店 gift: 禮品店 - greengrocer: 生鮮食品店 + greengrocer: 果菜店 grocery: 雜貨店 hairdresser: 理髮店 hardware: 五金行 health_food: 保健食品店 hearing_aids: 助聽器 - herbalist: 藥草供應商 - hifi: 音響店 - houseware: 生活用品店 + herbalist: 藥草店/中藥行 + hifi: 視聽音響店 + houseware: 居家用品店 ice_cream: 冰淇淋店 - interior_decoration: 室內裝潢 - jewelry: 珠寶店 + interior_decoration: 室內擺飾 + jewelry: 珠寶飾品店 kiosk: 販售亭 kitchen: 廚房用品店 laundry: 洗衣店 locksmith: 鎖店 lottery: 樂透 - mall: 購物商場 + mall: 購物中心 massage: 按摩店 - medical_supply: 醫療用品店 + medical_supply: 醫療器材與輔具店 mobile_phone: 行動通訊行 money_lender: 貸款 - motorcycle: 機車行 - motorcycle_repair: 機車維修行 + motorcycle: 摩托車經銷商 + motorcycle_repair: 摩托車維修行 music: 唱片行 musical_instrument: 樂器 - newsagent: 新聞代理商 - nutrition_supplements: 營養補品 - optician: 驗光師 + newsagent: 書報攤 + nutrition_supplements: 營養補給品 + optician: 眼鏡行 organic: 有機食品店 outdoor: 戶外用品店 - paint: 油漆店 + paint: 油漆行 pastry: 糕餅店 pawnbroker: 當鋪 perfumery: 香水店 @@ -1392,68 +1393,68 @@ zh-TW: photo: 照相館 seafood: 海產 second_hand: 二手商品店 - sewing: 縫紉店 + sewing: 縫紉材料行 shoes: 鞋店 sports: 體育用品店 stationery: 文具店 - storage_rental: 迷你倉 - supermarket: 超級市場 + storage_rental: 出租倉庫 + supermarket: 超市 tailor: 裁縫店 tattoo: 刺青屋 - tea: 茶舖 + tea: 茶葉行 ticket: 售票處 - tobacco: 菸草販賣 + tobacco: 香菸店 toys: 玩具店 travel_agency: 旅行社 - tyres: 輪胎販售 + tyres: 輪胎行 vacant: 空置店舖 - variety_store: 雜貨店 + variety_store: 均一價商店 video: 影音店 video_games: 電子遊戲專賣店 - wholesale: 批發商 - wine: 葡萄酒館 + wholesale: 批發量販店 + wine: 葡萄酒商 "yes": 商店 tourism: - alpine_hut: 山屋 + alpine_hut: 山莊 apartment: 假日公寓 - artwork: 美工 + artwork: 藝術品 attraction: 景點 - bed_and_breakfast: 家庭旅館 - cabin: 旅遊小屋 - camp_pitch: 營地 + bed_and_breakfast: B&B + cabin: 小木屋 + camp_pitch: 營位 camp_site: 營地 caravan_site: RV 宿營區 chalet: 小木屋 - gallery: 圖庫 - guest_house: 賓館 - hostel: 旅舍 - hotel: 酒店 - information: 旅遊中心 + gallery: 藝廊 + guest_house: 民宿 + hostel: 青年旅舍 + hotel: 旅館 + information: 資訊服務處 motel: 汽車旅館 museum: 博物館 - picnic_site: 野餐地 + picnic_site: 野餐區 theme_park: 主題公園 viewpoint: 觀景點 - wilderness_hut: 荒野小屋 + wilderness_hut: 避難山屋 zoo: 動物園 tunnel: - building_passage: 建築物通道 + building_passage: 建築物穿堂 culvert: 涵管 "yes": 隧道 waterway: artificial: 人工水道 - boatyard: 船塢 - canal: 運河 + boatyard: 船廠 + canal: 運河/大水渠 dam: 水壩 derelict_canal: 廢棄運河 - ditch: 小溝渠 - dock: 碼頭 + ditch: 土溝 + dock: 船塢 drain: 溝渠 - lock: 水門 - lock_gate: 船閘 + lock: 船閘 + lock_gate: 閘門 mooring: 停泊處 rapids: 急流 - river: 河流 + river: 河川 stream: 小溪 wadi: 乾河 waterfall: 瀑布 @@ -1462,18 +1463,18 @@ zh-TW: admin_levels: level2: 國界 level3: 區界 - level4: 省界 + level4: 州界 level5: 區界 level6: 縣界 - level7: 自治市界 + level7: 自治邦界 level8: 市界 level9: 村里界 - level10: 郊區邊界 - level11: 社區邊界 + level10: 市區邊界 + level11: 鄰近區界 types: cities: 城市 towns: 鄉鎮 - places: 地區 + places: 地點 results: no_results: 找不到結果 more_results: 更多結果 @@ -1500,7 +1501,7 @@ zh-TW: reported_item: 已回報項目 states: ignored: 已忽略 - open: 開啟 + open: 開放 resolved: 已解決 show: title: '%{status} 問題 #%{issue_id}' @@ -1537,17 +1538,17 @@ zh-TW: note: '註記 #%{note_id}' issue_comments: create: - comment_created: 您的評論已成功建立 - issue_reassigned: 已建立您的評論,並重新分配問題 + comment_created: 你的評論已成功建立 + issue_reassigned: 已建立你的評論,並重新分配問題 reports: new: title_html: 回報 %{link} missing_params: 無法建立新的回報 disclaimer: - intro: 發送您的回報給站台仲裁員前,請確認: - not_just_mistake: 您確定了該問題內容並非誤會 - unable_to_fix: 您無法自行或在您的社群成員協助下修正問題 - resolve_with_user: 您已準備嘗試解決使用者關注的問題 + intro: 發送你的回報給站台仲裁員前,請確認: + not_just_mistake: 你確定了該問題內容並非誤會 + unable_to_fix: 你無法自行、或在社群成員協助下修正問題 + resolve_with_user: 你已準備嘗試解決使用者關注的問題 categories: diary_entry: spam_label: 此日記項目為/含有垃圾訊息 @@ -1571,7 +1572,7 @@ zh-TW: abusive_label: 此註記有辱駡內容 other_label: 其它 create: - successful_report: 已成功登記您的回報 + successful_report: 已成功登記你的回報 provide_details: 請提供所需的詳情 layouts: project_name: @@ -1597,7 +1598,7 @@ zh-TW: edit_with: 以 %{editor} 編輯 tag_line: 自由的 wiki 世界地圖 intro_header: 歡迎來到 OpenStreetMap! - intro_text: OpenStreetMap 是一幅世界地圖,由像您這樣的人們所建立,在開放授權下可以自由使用。 + intro_text: OpenStreetMap 是一份全世界的地圖,由像你這樣的人們所建立,在開放授權下可以自由使用。 intro_2_create_account: 建立使用者帳號 hosting_partners_2024_html: 由%{fastly}、%{corpmembers},和其他%{partners}支援代管。 partners_fastly: Fastly @@ -1606,6 +1607,7 @@ zh-TW: tou: 使用條款 osm_offline: OpenStreetMap 資料庫目前正在離線,直到必要的資料庫維護工作完成為止。 osm_read_only: OpenStreetMap 資料庫目前處於唯讀模式,直到必要的資料庫維護工作完成為止。 + nothing_to_preview: 無可預覽內容。 donate: 以 %{link} 給硬體升級基金來支援 OpenStreetMap。 help: 說明 about: 關於 @@ -1623,34 +1625,37 @@ zh-TW: diary_comment_notification: description: 'OpenStreetMap 日記項目 #%{id}' subject: '[OpenStreetMap] %{user} 已評論日記項目' - hi: '%{to_user} 您好,' + hi: '%{to_user} 你好,' header: '%{from_user} 評論主旨為 %{subject} 的 OpenStreetMap 日記項目:' header_html: '%{from_user} 評論主旨為 %{subject} 的 OpenStreetMap 日記項目:' - footer: 您也可以在 %{readurl} 閱讀評論,並且在 %{commenturl} 留下評論,或在 %{replyurl} 發送訊息給作者 - footer_html: 您也可以在 %{readurl} 閱讀評論,並且在 %{commenturl} 留下評論,或在 %{replyurl} 發送訊息給作者 - footer_unsubscribe: 您可以在%{unsubscribeurl}取消訂閱討論 - footer_unsubscribe_html: 您可以在%{unsubscribeurl}取消訂閱討論 + footer: 你也可以在 %{readurl} 閱讀評論,並且在 %{commenturl} 留下評論,或在 %{replyurl} 發送訊息給作者 + footer_html: 你也可以在 %{readurl} 閱讀評論,並且在 %{commenturl} 留下評論,或在 %{replyurl} 發送訊息給作者 + footer_unsubscribe: 你可以在%{unsubscribeurl}取消訂閱討論 + footer_unsubscribe_html: 你可以在%{unsubscribeurl}取消訂閱討論 message_notification: subject: '[OpenStreetMap] %{message_title}' hi: '%{to_user} 您好,' - header: '%{from_user} 透過 OpenStreetMap 寄給您主旨為 %{subject} 的訊息:' - header_html: '%{from_user} 透過 OpenStreetMap 寄給您主旨為 %{subject} 的訊息:' - footer: 您也可以在 %{readurl} 閱讀訊息,並且在 %{replyurl} 發送訊息給作者 - footer_html: 您也可以在 %{readurl} 閱讀訊息,並且在 %{replyurl} 發送訊息給作者 + header: '%{from_user} 透過 OpenStreetMap 寄給你主旨為 %{subject} 的訊息:' + header_html: '%{from_user} 透過 OpenStreetMap 寄給你主旨為 %{subject} 的訊息:' + footer: 你也可以在 %{readurl} 閱讀訊息,並且在 %{replyurl} 發送訊息給作者 + footer_html: 你也可以在 %{readurl} 閱讀訊息,並且在 %{replyurl} 發送訊息給作者 friendship_notification: hi: 嗨 %{to_user}, - subject: '[OpenStreetMap] %{user} 將您加入為好友' - had_added_you: '%{user} 已在 OpenStreetMap 將您加入為好友。' - see_their_profile: 您可以在 %{userurl} 查看他的基本資料。 - see_their_profile_html: 您可以在 %{userurl} 查看他的基本資料。 - befriend_them: 您可以在 %{befriendurl} 把他加入為好友。 - befriend_them_html: 您可以在 %{befriendurl} 把他加入為好友。 + subject: '[OpenStreetMap] %{user} 將你加為好友' + had_added_you: '%{user} 已在 OpenStreetMap 將你加為好友。' + see_their_profile: 你可以在 %{userurl} 查看他的基本資料。 + see_their_profile_html: 你可以在 %{userurl} 查看他的基本資料。 + befriend_them: 你可以在 %{befriendurl} 把他加入為好友。 + befriend_them_html: 你可以在 %{befriendurl} 把他加入為好友。 gpx_description: - description_with_tags_html: 看起來似乎是您的 GPX 檔案%{trace_name}帶有%{trace_description}描述而且沒有標籤:%{tags} - description_with_no_tags_html: 看起來似乎是您的 GPX 檔案%{trace_name}帶有%{trace_description}描述而且沒有標籤 + description_with_tags: 看起來似乎是你的 GPX 檔案%{trace_name}帶有%{trace_description}描述而且沒有標籤:%{tags} + description_with_tags_html: 看起來似乎是你的 GPX 檔案%{trace_name}帶有%{trace_description}描述而且沒有標籤:%{tags} + description_with_no_tags: 看起來似乎是你的 GPX 檔案%{trace_name}帶有%{trace_description}描述而且沒有標籤 + description_with_no_tags_html: 看起來似乎是你的 GPX 檔案%{trace_name}帶有%{trace_description}描述而且沒有標籤 gpx_failure: - hi: '%{to_user} 您好,' + hi: '%{to_user} 你好,' failed_to_import: 看來匯入失敗。錯誤訊息為: + more_info: 更多關於 GPX 匯入失敗的資訊與如何避免,可在 %{url} 查詢。 more_info_html: 更多關於 GPX 匯入失敗的資訊與如何避免,可在 %{url} 查詢。 subject: '[OpenStreetMap] GPX 匯入失敗' gpx_success: @@ -1658,35 +1663,37 @@ zh-TW: loaded: one: 成功載入 %{count} 個可能軌跡點中的 %{trace_points} 個。 other: 成功載入 %{count} 個可能軌跡點中的 %{trace_points} 個。 - all_your_traces_html: 您可以在 %{url} 找到所有您上傳成功的 GPX 軌跡。 + trace_location: 你的軌跡已在 %{trace_url} 上可用 + all_your_traces: 你可以在 %{url} 找到所有上傳成功的 GPX 軌跡 + all_your_traces_html: 你可以在 %{url} 找到所有上傳成功的 GPX 軌跡。 subject: '[OpenStreetMap] GPX 匯入成功' signup_confirm: subject: '[OpenStreetMap] 歡迎加入 OpenStreetMap' - greeting: 您好! - created: 有人 (希望是您) 剛在 %{site_url} 建立了帳號。 - confirm: 在我們作出任何動作之前,我們需要確認這是您提出的要求。如果確實是這樣,請按以下連結,以確認你的帳號: + greeting: 你好! + created: 有人 (希望是你) 剛在 %{site_url} 建立了帳號。 + confirm: 在我們作出任何動作之前,我們需要確認這是你提出的要求。如果確實是這樣,請按以下連結,以確認你的帳號: welcome: 在確認你的帳號後,我們將提供一些額外的訊息,幫助你開始使用 OpenStreetMap。 email_confirm: - subject: '[OpenStreetMap] 確認您的電子郵件地址' + subject: '[OpenStreetMap] 確認你的電子郵件信箱' greeting: 您好, - hopefully_you: 有人 (希望是您) 希望在 %{server_url} 更改電子郵件地址至 %{new_address} 。 - click_the_link: 如果這是您,請按下列連結確認此變更。 + hopefully_you: 有人 (希望是你) 想在 %{server_url} 更改電子郵件信箱為 %{new_address} 。 + click_the_link: 如果這是你,請按下列連結確認此變更。 lost_password: subject: '[OpenStreetMap] 密碼重設要求' - greeting: 您好, - hopefully_you: 有人 (或許是您) 要求將以此電子郵件地址註冊的 openstreetmap.org 帳號,重設密碼。 - click_the_link: 如果這是您,請按下列連結重設您的密碼。 + greeting: 你好, + hopefully_you: 有人 (或許是你) 要求將這個電子郵件信箱註冊的 openstreetmap.org 帳號重設密碼。 + click_the_link: 如果這是你,請按下列連結重設密碼。 note_comment_notification: description: 'OpenStreetMap 註記 #%{id}' anonymous: 匿名使用者 - greeting: 您好, + greeting: 你好, commented: - subject_own: '[OpenStreetMap] %{commenter} 在您的註記評論' - subject_other: '[OpenStreetMap] %{commenter} 就您感興趣的註記評論' - your_note: '%{commenter} 在 %{place} 附近的地圖註記評論。' - your_note_html: '%{commenter} 在 %{place} 附近的地圖註記評論。' - commented_note: '%{commenter} 在你感興趣的地圖註記評論。該註記在 %{place} 附近。' - commented_note_html: '%{commenter} 在你感興趣的地圖註記評論。該註記在 %{place} 附近。' + subject_own: '[OpenStreetMap] %{commenter} 對你的註記做了評論' + subject_other: '[OpenStreetMap] %{commenter} 對你感興趣的註記做了評論' + your_note: '%{commenter} 對 %{place} 附近的地圖註記做了評論。' + your_note_html: '%{commenter} 對 %{place} 附近的地圖註記做了評論。' + commented_note: '%{commenter} 對你感興趣的地圖註記做了評論。該註記在 %{place} 附近。' + commented_note_html: '%{commenter} 對你感興趣的地圖註記做了評論。該註記在 %{place} 附近。' closed: subject_own: '[OpenStreetMap] %{commenter} 解決你其中一筆註記 %{commenter}' subject_other: '[OpenStreetMap]%{commenter} 已解決一項你感興趣的註記' @@ -1699,8 +1706,8 @@ zh-TW: subject_other: '[OpenStreetMap] %{commenter} 再次開啟你感興趣的註記。' your_note: '%{commenter} 已經再次開啟你其中一筆接近 %{place} 的地圖註記。' your_note_html: '%{commenter} 已經再次開啟你其中一筆接近 %{place} 的地圖註記。' - commented_note: '%{commenter} 重新開啟了一個您曾評論的地圖註記。該註記位於 %{place} 附近。' - commented_note_html: '%{commenter} 重新開啟了一個您曾評論的地圖註記。該註記位於 %{place} 附近。' + commented_note: '%{commenter} 重新開啟了一個你曾評論的地圖註記。該註記位於 %{place} 附近。' + commented_note_html: '%{commenter} 重新開啟了一個你曾評論的地圖註記。該註記位於 %{place} 附近。' details: 關於註記的更多詳細資料可在 %{url} 找到。 details_html: 在%{url}回覆或是瞭解更多有關註記的訊息。 changeset_comment_notification: @@ -1708,43 +1715,43 @@ zh-TW: hi: 嗨 %{to_user}, greeting: 您好, commented: - subject_own: '[OpenStreetMap] %{commenter} 在您的變更集評論' - subject_other: '[OpenStreetMap] %{commenter} 就您感興趣的變更集評論' - your_changeset: '%{commenter}於 %{time} 在您的變更集之一裡留下了評論' - your_changeset_html: '%{commenter}於 %{time} 在您的變更集之一裡留下了評論' - commented_changeset: '%{commenter}於 %{time} 在您監視的由%{changeset_author}所建立變更集裡留下了評論' - commented_changeset_html: '%{commenter}於 %{time} 在您監視的由%{changeset_author}所建立變更集裡留下了評論' + subject_own: '[OpenStreetMap] %{commenter} 對你的變更集做了評論' + subject_other: '[OpenStreetMap] %{commenter} 對你感興趣的變更集做了評論' + your_changeset: '%{commenter}於 %{time} 在你的變更集做了評論' + your_changeset_html: '%{commenter}於 %{time} 在你的變更集做了評論' + commented_changeset: '%{commenter}於 %{time} 在你監視、由%{changeset_author}建立的變更集做了評論' + commented_changeset_html: '%{commenter}於 %{time} 在你監視、由%{changeset_author}建立的變更集做了評論' partial_changeset_with_comment: 評論 "%{changeset_comment}" partial_changeset_with_comment_html: 評論 "%{changeset_comment}" partial_changeset_without_comment: 沒有評論 details: 在 %{url} 回覆或瞭解更多有關於變更集的資訊。 details_html: 在 %{url} 回覆或瞭解更多有關變更集的資訊。 - unsubscribe: 您可以在 %{url} 取消訂閱此變更集的更新內容。 - unsubscribe_html: 您可以在 %{url} 取消訂閱此變更集的更新內容。 + unsubscribe: 你可以在 %{url} 取消訂閱此變更集的更新內容。 + unsubscribe_html: 你可以在 %{url} 取消訂閱此變更集的更新內容。 confirmations: confirm: - heading: 請檢查您的電子郵件! - introduction_1: 我們寄給您一封確認電子郵件。 + heading: 檢查你的電子郵件! + introduction_1: 我們已經寄給你一封確認電子郵件。 introduction_2: 按電子郵件中的連結以確認你的帳號,然後你就可以開始繪製地圖。 - press confirm button: 按下確認按鈕以開啟您的帳號。 + press confirm button: 按下確認按鈕以開啟你的帳號。 button: 確認 - success: 已確認您的帳號,感謝您的註冊! + success: 已確認你的帳號,感謝你的註冊! already active: 該帳號已經確認。 unknown token: 確認碼已經過期或不存在。 - resend_html: 如果您要我們重新發送確認郵件,%{reconfirm_link}。 + resend_html: 如果你要我們重新發送確認郵件,%{reconfirm_link}。 click_here: 在此點擊 confirm_resend: failure: 找不到使用者 %{name}。 confirm_email: heading: 確認電子郵件地址的變更 - press confirm button: 按下確認按鈕以確認您的新電子郵件地址。 + press confirm button: 按下確認按鈕以確認你的新電子郵件地址。 button: 確認 - success: 已確認您變更的電子郵件地址! - failure: 電子郵件地址已使用此權杖確認過。 + success: 已確認你變更的電子郵件地址! + failure: 已有電子郵件地信箱使用此授權密鑰認證過。 unknown_token: 確認碼已經過期或不存在。 resend_success_flash: - confirmation_sent: 我們已發送新的確認通知到 %{email},一旦您確認您的帳號後,就能取得製圖。 - whitelist: 如果您用來發送確認請求的信箱有反垃圾郵件系統,請確認有將 %{sender} 將入白名單,因為我們無法回覆任何確認請求。 + confirmation_sent: 我們已發送新的確認通知到 %{email},一旦你確認你的帳號後,就能取得製圖權限。 + whitelist: 如果你用來發送確認請求的信箱有反垃圾郵件系統,請確認有將 %{sender} 將入白名單,因為我們無法回覆任何確認請求。 messages: inbox: title: 收件匣 @@ -1755,7 +1762,7 @@ zh-TW: old_messages: one: '%{count} 項舊訊息' other: '%{count} 項舊訊息' - no_messages_yet_html: 您還沒有訊息。何不跟一些 %{people_mapping_nearby_link} 接觸看看? + no_messages_yet_html: 你還沒有訊息。何不跟一些 %{people_mapping_nearby_link} 接觸看看? people_mapping_nearby: 在附近製圖的人 messages_table: from: 寄件者 @@ -1775,7 +1782,7 @@ zh-TW: back_to_inbox: 回到收件匣 create: message_sent: 已傳送訊息 - limit_exceeded: 您最近寄出了大量的訊息。在嘗試寄出其他訊息之前請稍候。 + limit_exceeded: 你最近寄出了大量的訊息,要再寄出訊息前請稍候 no_such_message: title: 沒有這個訊息 heading: 沒有這個訊息 @@ -1784,24 +1791,24 @@ zh-TW: title: 寄件匣 actions: 操作 messages: - one: 您有 %{count} 項已寄訊息 - other: 您有 %{count} 項已寄訊息 - no_sent_messages_html: 您還沒有已寄訊息。何不跟一些 %{people_mapping_nearby_link} 接觸看看? + one: 你有 %{count} 項已寄訊息 + other: 你有 %{count} 項已寄訊息 + no_sent_messages_html: 你還沒有已寄訊息。何不跟一些 %{people_mapping_nearby_link} 接觸看看? people_mapping_nearby: 附近製作地圖的使用者 muted: title: 已忽視訊息 messages: one: 1 條忽視訊息 - other: 您有 %{count} 條忽視訊息 + other: 你有 %{count} 條忽視訊息 reply: - wrong_user: 您已經以「%{user}」的身份登入,但是您想要回覆的訊息並非寄給這個使用者。請以正確的使用者身份登入以回覆這個訊息。 + wrong_user: 你已經以「%{user}」的身份登入,但是你想要回覆的訊息並非寄給這個使用者。請以正確的使用者身份登入以回覆這個訊息。 show: title: 閱讀訊息 reply_button: 回覆 unread_button: 標記為未讀 destroy_button: 刪除 back: 返回 - wrong_user: 您已經以「%{user}」的身份登入,但是您想要閱讀的訊息並非寄給那個使用者。請以正確的使用者身份登入以閱讀它。 + wrong_user: 你已經以「%{user}」的身份登入,但是你想要閱讀的訊息並非寄給那個使用者。請以正確的使用者身份登入以閱讀它。 sent_message_summary: destroy_button: 刪除 heading: @@ -1822,17 +1829,17 @@ zh-TW: heading: 忘記密碼? email address: 電子郵件地址 new password button: 重設密碼 - help_text: 輸入您的電子郵件地址來註冊,我們會將連結送至該地址,而您可以用它來重設密碼。 + help_text: 輸入你的電子郵件地址來註冊,我們會將連結送至該地址,而你可以用它來重設密碼。 create: - send_paranoid_instructions: 如果您的電子郵件地址存於我們的資料庫裡,您將在幾分鐘內收到密碼恢復連結的電郵。 + send_paranoid_instructions: 如果你的電子郵件地址存於我們的資料庫裡,你將在幾分鐘內收到有可恢復密碼連結的電子郵件。 edit: title: 重設密碼 heading: 重設 %{user} 的密碼 reset: 重設密碼 - flash token bad: 找不到該權杖,可能要檢查一下 URL? + flash token bad: 找不到該授權密鑰,可能要檢查一下 URL? update: - flash changed: 您的密碼已經變更。 - flash token bad: 找不到該權杖,可能要檢查一下 URL? + flash changed: 你的密碼已經變更。 + flash token bad: 找不到該授權密鑰,可能要檢查一下 URL? preferences: show: title: 我的偏好設定 @@ -1857,14 +1864,14 @@ zh-TW: gravatar: 使用 Gravatar what_is_gravatar: 什麼是 Gravatar? disabled: Gravatar已停用。 - enabled: 您的Gravatar顯示功能已啟用。 + enabled: 你的 Gravatar 顯示功能已啟用。 new image: 加入圖片 keep image: 保持目前的圖片 delete image: 移除目前的圖片 replace image: 取代目前的圖片 image size hint: ' (方形圖片至少 100x100 的效果最好)' home location: 家的位置 - no home location: 您尚未輸入家的位置。 + no home location: 你尚未輸入家的位置。 update home location on click: 當我點選地圖時更新家的位置? show: 顯示 delete: 刪除 @@ -1880,7 +1887,7 @@ zh-TW: email or username: 電子郵件地址或使用者名稱 password: 密碼 remember: 記住我 - lost password link: 忘記您的密碼? + lost password link: 忘記密碼了? login_button: 登入 register now: 立即註冊 with external: 或者使用第三方服務登入 @@ -1891,8 +1898,8 @@ zh-TW: heading: 從 OpenStreetMap 登出 logout_button: 登出 suspended_flash: - suspended: 抱歉,由於可疑活動,您的帳戶已被暫停。 - contact_support_html: 如果您想商討此事,請聯繫 %{support_link}。 + suspended: 抱歉,由於可疑活動,你的帳戶已被暫停。 + contact_support_html: 如果你想討論此事,請聯絡 %{support_link}。 support: 支援 shared: markdown_help: @@ -1934,18 +1941,18 @@ zh-TW: community_driven_community_blogs: 社群部落格 community_driven_osm_foundation: OSM 基金會 open_data_title: 開放資料 - open_data_1_html: OpenStreetMap 是%{open_data}的:您可以自由地使用作任何用途,前提是您須標明作者為 OpenStreetMap - 及其貢獻者。若您在我們的資料上作修改或以之透過某些方式衍生其他資料,則只可依相同授權條款散佈有關成果。詳情請參閱%{copyright_license_link}。 + open_data_1_html: OpenStreetMap 是%{open_data}的:你可以自由地使用作任何用途,前提是必須標明作者為 OpenStreetMap + 及其貢獻者。若你在我們的資料上作修改或以之透過某些方式衍生其他資料,則只可依相同授權條款散佈有關成果。詳情請參閱%{copyright_license_link}。 open_data_open_data: 開放資料 open_data_copyright_license: 版權與授權條款頁面 legal_title: 法律資訊 - legal_1_1_html: 本站以及許多相關的服務正式由%{openstreetmap_foundation_link}(OSMF)代表社群所營運。所有使用的 + legal_1_1_html: 本站以及許多相關的服務正式由%{openstreetmap_foundation_link} (OSMF) 代表社群所營運。所有使用的 OSMF 運行服務皆符合我們的%{terms_of_use_link}、%{aup_link}、和%{privacy_policy_link}。 legal_1_1_openstreetmap_foundation: OpenStreetMap 基金會 legal_1_1_terms_of_use: 使用條款 legal_1_1_aup: 可接受使用方針 legal_1_1_privacy_policy: 隱私權政策 - legal_2_1_html: 若您有授權、版權、或其他法律上的問題,請%{contact_the_osmf_link}。 + legal_2_1_html: 若你有授權、版權、或其他法律上的問題,請%{contact_the_osmf_link}。 legal_2_1_contact_the_osmf: 聯絡 OSMF legal_2_2_html: OpenStreetMap,查看地圖狀態的放大鏡模樣標誌是%{registered_trademarks_link}。 legal_2_2_registered_trademarks: OSMF 的註冊商標 @@ -1958,28 +1965,29 @@ zh-TW: english_link: 英文原文 native: title: 關於此頁 - html: 您正在檢閱英文版本的版權頁。你可以返回這個網頁的 %{native_link},您亦可以停止閱讀版權並 %{mapping_link}。 + html: 你正在檢閱英文版本的版權頁。你可以返回這個網頁的 %{native_link},也可以停止閱讀版權並 %{mapping_link}。 native_link: 繁體中文版 mapping_link: 開始製圖 legal_babble: - introduction_1_html: OpenStreetMap%{registered_trademark_link}是%{open_data},透過%{osm_foundation_link}(OSMF)在%{odc_odbl_link}(ODbL)下授權。 + introduction_1_html: OpenStreetMap%{registered_trademark_link}是%{open_data},透過%{osm_foundation_link} + (OSMF) 在%{odc_odbl_link}(ODbL)下授權。 introduction_1_open_data: 開放資料 introduction_1_odc_odbl: 開放資料共享開放資料庫授權 introduction_1_osm_foundation: OpenStreetMap 基金會 - introduction_2_html: 您可以自由地複製、散布、傳輸及修改我們的資料,前提是您須標明作者為 OpenStreetMap 及其貢獻者。若您在我們的資料上作變動或以此來建立其他資料,您只能依照相同授權條款來散佈成果。%{legal_code_link}有詳述您的權責。 + introduction_2_html: 你可以自由複製、散布、傳輸及修改我們的資料,前提是必須標明作者為 OpenStreetMap 及其貢獻者。若在我們的資料上作變動或以此來建立其他資料,你只能依照相同授權條款來散佈成果。%{legal_code_link}有詳述你的權責。 introduction_2_legal_code: 法律條款 introduction_3_html: 我們的文件是依據 %{creative_commons_link} 授權條款(CC BY-SA 2.0)獲得許可。 introduction_3_creative_commons: 創用 CC 姓名標示-相同方式分享 introduction_3_creative_commons_url: https://creativecommons.org/licenses/by-sa/2.0/deed.zh_TW credit_title_html: 如何標明作者是 OpenStreetMap - credit_1_html: 當您使用 OpenStreetMap 的資料,您會被要求遵循兩件事: + credit_1_html: 當你使用 OpenStreetMap 的資料,你會被要求遵循兩件事: credit_2_1: 透過顯示我們的版權聲明為 OpenStreetMap 提供屬名。 credit_2_2: 明確資料在開放資料共享開放資料庫授權下可用。 - credit_3_html: 對於版權聲明的顯示,我們會依據您如何使用我們的資料,而有不同的要求。例如,不同的規則要如何顯示版權聲明,具體取決於您是否有建立可瀏覽的地圖、列印的地圖、或靜態圖片。完整的詳細資訊要求可以在%{attribution_guidelines_link}上查看。 + credit_3_html: 對於版權聲明的顯示,我們會依據你如何使用我們的資料,而有不同的要求。例如:不同的規則要如何顯示版權聲明,具體取決於你是否有建立可瀏覽的地圖、列印的地圖、或靜態圖片。完整的詳細資訊要求可以在%{attribution_guidelines_link}上查看。 credit_3_attribution_guidelines: 姓名標示指南 credit_4_1_html: |- - 請明確表示資料在開放資料庫授權條款下可用,您可以連結到%{this_copyright_page_link}。 - 相對地,如果您以資料表來分發 OSM,您可以命名並直接連結到授權條款。在一些無法作出連結的媒體(例如印刷品),我們建議您引導您的讀者到 openstreetmap.org(像是註明「OpenStreetMap」的完整網址)以及 opendatacommons.org。 + 請明確表示資料在開放資料庫授權條款下可用,你可以連結到%{this_copyright_page_link}。 + 相對地,如果你以資料表來分發 OSM,你可以命名並直接連結到授權條款。在一些無法作出連結的媒體 (例如印刷品),我們建議引導你的讀者到 openstreetmap.org (像是註明「OpenStreetMap」的完整網址) 以及 opendatacommons.org。 在此範例中,版權相關聲明會出現在地圖的角落處。 credit_4_1_this_copyright_page: 此版權頁面 attribution_example: @@ -1996,8 +2004,8 @@ zh-TW: more_2_1_nominatim_usage_policy: 提名使用方針 contributors_title_html: 我們的貢獻者 contributors_intro_html: 我們的貢獻者為成千上萬的人。我們也收納了從國家測繪機構及其他來源等取得的開放版權資料,其中包括: - contributors_at_credit_html: '%{austria}:包含來自%{stadt_wien_link}(依據%{cc_by_link})、%{land_vorarlberg_link}、與 - Land Tirol(依據%{cc_by_at_with_amendments_link})的資料。' + contributors_at_credit_html: '%{austria}:包含來自%{stadt_wien_link} (依據%{cc_by_link})、%{land_vorarlberg_link}、與 + Land Tirol (依據%{cc_by_at_with_amendments_link}) 的資料。' contributors_at_austria: 奧地利 contributors_at_stadt_wien: 維也納 contributors_at_cc_by: 創用 CC 姓名標示 @@ -2009,12 +2017,12 @@ zh-TW: contributors_au_geoscape_australia: Geoscape Australia contributors_au_cc_licence: 創用 CC 姓名標示 4.0 國際授權條款(CC BY 4.0) contributors_au_cc_licence_url: https://creativecommons.org/licenses/by/4.0/deed.zh_TW - contributors_ca_credit_html: '%{canada}:包含來自 GeoBase®ã€GeoGratis(©åŠ æ‹¿å¤§è‡ªç„¶è³‡æºè™•ï¼‰ã€CanVec(©åŠ æ‹¿å¤§è‡ªç„¶è³‡æºè™•ï¼‰ã€å’Œ - StatCan(地理部,加拿大統計局)的資料。' + contributors_ca_credit_html: '%{canada}:包含來自 GeoBase®ã€GeoGratis (©åŠ æ‹¿å¤§è‡ªç„¶è³‡æºè™•)、CanVec + (©åŠ æ‹¿å¤§è‡ªç„¶è³‡æºè™•)、和 StatCan (地理部,加拿大統計局) 的資料。' contributors_ca_canada: 加拿大 contributors_cz_credit_html: '%{czechia}:包含來自土地測量局與依據%{cc_licence_link}許可的地籍資料' contributors_cz_czechia: 捷克 - contributors_cz_cc_licence: 創用 CC 姓名標示 4.0 國際授權條款(CC BY 4.0) + contributors_cz_cc_licence: 創用 CC 姓名標示 4.0 國際授權條款 (CC BY 4.0) contributors_cz_cc_licence_url: https://creativecommons.org/licenses/by/4.0/deed.zh-hant contributors_fi_credit_html: '%{finland}:包含來自芬蘭測量局地形資料庫與其他資料集的資料,依據%{nlsfi_license_link}授權。' contributors_fi_finland: 芬蘭 @@ -2027,7 +2035,7 @@ zh-TW: contributors_hr_croatia: 克羅埃西亞 contributors_hr_dgu: 克羅埃西亞國家大地測量局 contributors_hr_open_data_portal: 國家開放資料入口網站 - contributors_nl_credit_html: '%{netherlands}:包含 © AND 資料,2007(%{and_link})' + contributors_nl_credit_html: '%{netherlands}:包含 © AND 資料,2007 (%{and_link})' contributors_nl_netherlands: 荷蘭 contributors_nz_credit_html: '%{new_zealand}:包含來自 %{linz_data_service_link}與基於%{cc_by_link} 的重複使用授權條款。' @@ -2061,26 +2069,26 @@ zh-TW: infringement_title_html: 侵犯版權 infringement_1_html: OSM 的貢獻者會被提醒,絕不要在沒有版權所有人的明確淮許下,加入來自任何有版權的來源的資料 (如 Google 地圖或印刷地圖)。 - infringement_2_1_html: 如果您認為有受版權保護的素材被不恰當地加到 OpenStreetMap 資料庫或本網站,請參考我們的%{takedown_procedure_link},或直接在我們的%{online_filing_page_link}反應。 + infringement_2_1_html: 如果你認為有受版權保護的素材被不恰當地加到 OpenStreetMap 資料庫或本網站,請參考我們的%{takedown_procedure_link},或直接在我們的%{online_filing_page_link}反應。 infringement_2_1_takedown_procedure: 侵權處理程序 infringement_2_1_online_filing_page: 線上申請頁面 trademarks_title: 商標 trademarks_1_1_html: OpenStreetMap、網站上的放大鏡標誌,和 State of the Map 是 OpenStreetMap - 基金會的註冊商標。如果您對商標的使用有任何疑問,請參閱我們的%{trademark_policy_link}。 + 基金會的註冊商標。如果你對商標的使用有任何疑問,請參閱我們的%{trademark_policy_link}。 trademarks_1_1_trademark_policy: 商標方針 index: - js_1: 您使用不支援 JavaScript 的瀏覽器,或者停用了 JavaScript。 + js_1: 你使用不支援 JavaScript 的瀏覽器,或者停用了 JavaScript。 js_2: OpenStreetMap 使用 JavaScript 讓地圖更平順。 license: copyright: 版權所有,由 OpenStreetMap 及貢獻者根據開放的授權協議提供 remote_failed: 編輯失敗 - 請確定已載入 JOSM 或 Merkaartor 並開啟遠端控制選項 edit: - not_public: 您尚未將您的編輯設為公開。 - not_public_description_html: 在您這麼做之前將無法再編輯地圖。您可以在您的 %{user_page} 將自己的編輯設定為公開。 + not_public: 你尚未將你的編輯設為公開。 + not_public_description_html: 在你這麼做之前將無法再編輯地圖,可以在你的 %{user_page} 將自己的編輯設定為公開。 user_page_link: 使用者頁面 anon_edits_link_text: 瞭解為什麼這很重要。 id_not_configured: iD 尚未設定 - no_iframe_support: 您的瀏覽器不支援 HTML 嵌入式框架,這是這項功能所必要的。 + no_iframe_support: 你的瀏覽器不支援 HTML 嵌入式框架,這是這項功能所必要的。 export: title: 匯出 manually_select: 手動選擇不同的區域 @@ -2115,10 +2123,10 @@ zh-TW: add_a_note: instructions_1_html: |- 只需點選%{note_icon}或地圖上顯示的同一圖示, - 這會在地圖上加入一個標記,您可以拖動它,並新增您的註記,然後點選儲存,其他製圖者會作出查證。 + 這會在地圖上加入一個標記,你可以拖動它,並新增你的註記,然後點選儲存,其他製圖者會作出查證。 other_concerns: title: 其他問題 - concerns_html: 如果您對我們的資料使用方面或內容有所疑慮,請參考我們的%{copyright_link}來了解更多法律資訊,或是聯繫相應的%{working_group_link}。 + concerns_html: 如果你對我們的資料使用方面或內容有所疑慮,請參考我們的%{copyright_link}來了解更多法律資訊,或是聯繫相應的%{working_group_link}。 copyright: 版權頁面 working_group: OSMF 工作小組 help: @@ -2146,16 +2154,16 @@ zh-TW: description: 協助公司與組織改用 OpenStreetMap 為基礎的地圖與相關服務。 welcomemat: title: 對於組織 - description: 想要以組織來對 OpenStreetMap 製作計劃嗎?請在 Welcome Mat 查找您所需要的事項。 + description: 想要以組織來對 OpenStreetMap 製作計劃嗎?請在 Welcome Mat 查找你所需要的事項。 wiki: title: 開放街圖 Wiki description: 瀏覽 wiki,取得詳盡的開放街圖文件。 potlatch: - removed: 您預設的開放街圖編輯器是設定成 Potlatch。因為 Adobe Flash Player 已終止維護,Potlatch 已不在網路瀏覽器上可用。 - desktop_application_html: 您仍然可以透過 %{download_link} 使用 Potlatch。 + removed: 你預設的開放街圖編輯器是設定為 Potlatch。但因為 Adobe Flash Player 已終止維護,Potlatch 已不能在網路瀏覽器上使用。 + desktop_application_html: 你仍然可以透過 %{download_link} 使用 Potlatch。 download: 下載適用於 Mac 和 Windows 的桌面應用程式 - id_editor_html: 除此之外,您可以設定您的預設編輯器成 iD,這可以和先前的 Potlatch 一樣在您的網路瀏覽器上運作。%{change_preferences_link}。 - change_preferences: 在此更改您的偏好設定 + id_editor_html: 除此之外,你可以設定預設編輯器為 iD,這可以和之前的 Potlatch 一樣在你的網路瀏覽器上運作。%{change_preferences_link}。 + change_preferences: 在此更改你的偏好設定 any_questions: title: 有任何問題嗎? paragraph_1_html: |- @@ -2181,18 +2189,18 @@ zh-TW: entry: motorway: 高速公路 main_road: 主要幹道 - trunk: 主要幹路 - primary: 一級道路 - secondary: 二級道路 - unclassified: 無編制道路 + trunk: 快速公路 + primary: 省道 + secondary: 縣道 + unclassified: 未分級道路 pedestrian: 人行道 track: 產業道路 bridleway: 馬道 cycleway: 自行車道 cycleway_national: 國家自行車道 - cycleway_regional: 區域自行車道 - cycleway_local: 地區自行車道 - cycleway_mtb: 登山車路徑 + cycleway_regional: 地區自行車道 + cycleway_local: 地方自行車道 + cycleway_mtb: 登山車路線 footway: 步道 rail: 鐵路 train: 列車 @@ -2203,7 +2211,7 @@ zh-TW: trolleybus: 無軌電車 bus: 公車 cable_car: 大型纜車 - chair_lift: 升降吊椅 + chair_lift: 吊椅式索道 runway: 機場跑道 taxiway: 滑行道 apron: 機場停機坪 @@ -2212,8 +2220,8 @@ zh-TW: city: 城市 orchard: 果園 vineyard: 葡萄園 - forest: 森林 - wood: 森林 + forest: 人工林 + wood: 自然林 farmland: 農地 grass: 草坪 meadow: 牧草地 @@ -2222,29 +2230,29 @@ zh-TW: golf: 高爾夫球場 park: 公園 common: 共有地 - built_up: 組成面積 + built_up: 建成區 resident: 住宅區 - retail: 商店區 + retail: 零售商區 industrial: 工業區 commercial: 商業區 heathland: 石楠荒地 scrubland: 灌木叢林地 lake: 湖泊 - reservoir: 水庫 + reservoir: 水庫/大型蓄水池 intermittent_water: 間歇性水體 glacier: 冰河 - reef: 礁 + reef: 暗礁 wetland: 濕地 farm: 農田 - brownfield: 低污染再利用地 + brownfield: 棕色地 (受污染放置待恢復重開發地) cemetery: 公墓 allotments: 社區農園 - pitch: 運動場 + pitch: 運動場地 centre: 運動中心 beach: 海灘 - reserve: 自然保護區 + reserve: 自然保育 military: 軍事區 - school: 學校;大學 + school: 學校 university: 大學 hospital: 醫院 building: 重要建築 @@ -2255,8 +2263,8 @@ zh-TW: bridge: 黑線邊框 = 橋樑 private: 私人進出 destination: 目的地進出 - construction: 建造中道路 - bus_stop: 公車站 + construction: 興建中道路 + bus_stop: 公車站牌 stop: 停車站 bicycle_shop: 自行車店 bicycle_rental: 自行車出租 @@ -2265,7 +2273,7 @@ zh-TW: toilets: 廁所 welcome: title: 歡迎! - introduction: 歡迎來到 OpenStreetMap,自由和可編輯的世界地圖。您目前已經登入,可以開始繪製地圖。這裡有一份您須知道最重要事項的快速指南。 + introduction: 歡迎來到 OpenStreetMap,自由和可編輯的世界地圖。你目前已經登入,可以開始繪製地圖。這裡有一份你必須知道的最重要事項的快速指南。 whats_on_the_map: title: 地圖上有什麼 on_the_map_html: |- @@ -2290,7 +2298,7 @@ zh-TW: rules: title: 規則! para_1_html: |- - OpenStreetMap 幾乎沒有正式規則,但我們希望所有參與者都能與社群合作與溝通!。如果您正在考慮 + OpenStreetMap 幾乎沒有正式規則,但我們希望所有參與者都能與社群合作與溝通!。如果你正在考慮 除手動編輯之外的任何活動,請閱讀並遵循 %{imports_link} 和 %{automated_edits_link}指南。 imports: 匯入 @@ -2336,9 +2344,9 @@ zh-TW: help_url: https://wiki.openstreetmap.org/wiki/Upload create: upload_trace: 上傳 GPS 軌跡 - trace_uploaded: 您的 GPX 檔案已經上傳並且在等候進入資料庫中。這通常不會超過半小時,完成時會以電子郵件通知您。 + trace_uploaded: 你的 GPX 檔案已經上傳並且在等候進入資料庫中。這通常不會超過半小時,完成時會以電子郵件通知。 upload_failed: 很抱歉,GPX 上傳失敗。已向管理員警告此錯誤,請再重試 - traces_waiting: 您有 %{count} 個軌跡等待上傳。請先等待先前的軌跡處理完後,再來繼續上傳其他軌跡,以免影響其他使用者的排程。 + traces_waiting: 你有 %{count} 個軌跡等待上傳。請先等待先前的軌跡處理完後,再來繼續上傳其他軌跡,以免影響其他使用者的排程。 edit: cancel: 取消 title: 編輯軌跡 %{name} @@ -2421,15 +2429,15 @@ zh-TW: application: basic_auth_disabled: HTTP 基本認證已停用:%{link} oauth_10a_disabled: OAuth 1.0 與 1.0a 已停用:%{link} - permission_denied: 您沒有權限來存取該操作。 + permission_denied: 你沒有權限來存取該操作。 require_cookies: - cookies_needed: 您似乎已停用 cookies - 請在瀏覽器中開啟 cookies,然後繼續。 + cookies_needed: 你似乎已停用 cookies - 請在瀏覽器中開啟 cookies 後再繼續。 require_admin: - not_an_admin: 您需要是一個管理員才可執行該動作。 + not_an_admin: 你必須是管理員才可執行該動作。 setup_user_auth: - blocked_zero_hour: 您在OpenStreetMap網站有一個緊急訊息。在您儲存您的編輯內容前請先閱讀該訊息。 - blocked: 您已經被封鎖使用 API。請登入網頁介面以瞭解更多資訊。 - need_to_see_terms: 我們已暫時中止您使用 API 的權限,請登入網頁介面查閱貢獻者條款,您不需要同意有關條款,但必須查閱它們。 + blocked_zero_hour: 你在 OpenStreetMap 網站有一個緊急訊息。在儲存你的編輯內容前請先閱讀該訊息。 + blocked: 你已經被封鎖使用 API。請登入網頁介面以瞭解更多資訊。 + need_to_see_terms: 我們已暫時中止你使用 API 的權限,請登入網頁介面查閱貢獻者條款,你不需要同意有關條款,但必須查閱它們。 settings_menu: account_settings: 帳號設定 oauth1_settings: OAuth 1 設定 @@ -2459,29 +2467,29 @@ zh-TW: alt: 維基百科標誌 oauth: authorize: - title: 授權使用您的帳號 - request_access_html: 應用程式 %{app_name} 要求使用您的帳號,%{user}。請確定您要讓此應用程式使用下列功能。您可以依自己喜好,選擇多少項功能。 + title: 授權使用你的帳號 + request_access_html: 應用程式 %{app_name} 要求使用你的帳號,%{user}。請確定你要讓此應用程式使用下列功能。你可以依自己喜好,選擇多少項功能。 allow_to: 允許用戶端應用程式: - allow_read_prefs: 讀取您的使用者偏好設定。 - allow_write_prefs: 修改您的使用者偏好設定。 + allow_read_prefs: 讀取你的使用者偏好設定。 + allow_write_prefs: 修改你的使用者偏好設定。 allow_write_diary: 建立日記、評論和加入好友。 allow_write_api: 修改地圖。 - allow_read_gpx: 讀取您的私人 GPS 軌跡。 + allow_read_gpx: 讀取你的私人 GPS 軌跡。 allow_write_gpx: 上傳 GPS 軌跡。 allow_write_notes: 修改註記。 grant_access: 授權存取 authorize_success: title: 允許授權請求 - allowed_html: 您已授權應用程式 %{app_name} 使用您的帳號。 + allowed_html: 你已授權應用程式 %{app_name} 使用你的帳號。 verification: 驗證碼是 %{code}。 authorize_failure: title: 授權請求失敗 - denied: 您已拒絕應用程式 %{app_name} 使用您的帳號。 - invalid: 授權權杖無效。 + denied: 你已拒絕應用程式 %{app_name} 使用你的帳號。 + invalid: 認證授權密鑰無效。 revoke: - flash: 您已經撤銷 %{application} 的授權密鑰。 + flash: 你已經撤銷 %{application} 的授權密鑰。 permissions: - missing: 您尚未允許應用程式來訪問此設施 + missing: 你尚未允許應用程式來訪問此設施 scopes: openid: 使用 OpenStreetMap 登入 read_prefs: 讀取使用者偏好設定 @@ -2493,6 +2501,8 @@ zh-TW: write_notes: 修改註記 write_redactions: 編寫地圖資料 read_email: 讀取使用者電子郵件位址 + consume_messages: 讀取、更新狀態、與刪除使用者訊息 + send_messages: 傳送私人訊息給其他使用者 skip_authorization: 自動核准申請 for_roles: moderator: 此權限用於僅可由仲裁員執行的操作 @@ -2501,31 +2511,31 @@ zh-TW: title: 註冊新的應用程式 disabled: 已停用 OAuth 1 應用程式的註冊 edit: - title: 編輯您的應用程式 + title: 編輯你的應用程式 show: title: '%{app_name} 的 OAuth 詳細資料' key: 消費者金鑰: secret: 消費者祕密金鑰: - url: 要求權杖 URL: - access_url: 存取記號 URL: + url: 要求授權密鑰 URL: + access_url: 連接授權密鑰 URL: authorize_url: 授權 URL: support_notice: 我們支援 HMAC-SHA1 (建議) 和 RSA-SHA1 署名。 edit: 編輯詳細資料 delete: 刪除客戶端 - confirm: 您確定嗎? + confirm: 你確定嗎? requests: 向使用者要求下列權限: index: title: 我的 OAuth 詳細資料 my_tokens: 我授權的應用程式 - list_tokens: 下列權杖已核發給您名下的應用程式: + list_tokens: 下列授權密鑰已核發給你名下的應用程式: application: 應用程式名稱 issued_at: 已發於 revoke: 撤銷! my_apps: 我的用戶端應用程式 - no_apps_html: 您是否有想要註冊以使用於 %{oauth} 標準的應用程式?您必須先註冊您的網頁應用程式,才能對這個服務進行 OAuth 要求。 + no_apps_html: 你是否有想要註冊以使用於 %{oauth} 標準的應用程式?你必須先註冊你的網頁應用程式,才能對這個服務進行 OAuth 要求。 oauth: OAuth - registered_apps: 您已經註冊下列用戶端應用程式: - register_new: 註冊您的應用程式 + registered_apps: 你已經註冊下列用戶端應用程式: + register_new: 註冊你的應用程式 form: requests: 向使用者要求下列權限: not_found: @@ -2539,8 +2549,8 @@ zh-TW: oauth2_applications: index: title: 我的客戶端應用程式 - no_applications_html: 您是否有想要註冊以使用於 %{oauth2} 標準的應用程式?您必須先註冊您的網頁應用程式,才能對這個服務進行 - OAuth 要求。 + no_applications_html: 你是否要跟我們註冊使用 %{oauth2} 標準的應用程式?你必須先註冊該應用程式,才能對這個服務進行 OAuth + 要求。 new: 註冊新的應用程式 name: 名稱 permissions: 權限 @@ -2551,7 +2561,7 @@ zh-TW: new: title: 註冊新的應用程式 edit: - title: 編輯您的應用程式 + title: 編輯你的應用程式 show: edit: 編輯 delete: 刪除 @@ -2566,7 +2576,7 @@ zh-TW: oauth2_authorizations: new: title: 需要授權 - introduction: 要授權 %{application} 能使用以下權限來存取您的帳號嗎? + introduction: 要授權 %{application} 能使用以下權限來存取你的帳號嗎? authorize: 授權 deny: 拒絕 error: @@ -2579,7 +2589,7 @@ zh-TW: application: 應用程式 permissions: 權限 last_authorized: 最後授權 - no_applications_html: 您未授權任何 %{oauth2} 應用程式。 + no_applications_html: 你未授權任何 %{oauth2} 應用程式。 application: revoke: 撤銷存取權限 confirm_revoke: 撤銷此應用程式的撤銷存取權限? @@ -2588,7 +2598,7 @@ zh-TW: title: 註冊 tab_title: 註冊 signup_to_authorize_html: 註冊 OpenStreetMap 以存取 %{client_app_name}。 - no_auto_account_create: 很不幸的我們現在無法自動為您建立帳號。 + no_auto_account_create: 很不幸的,我們現在無法自動為你建立帳號。 please_contact_support_html: 請聯繫 %{support_link} 來安排建立帳號 - 我們會盡快處理這份請求。 support: 支援 about: @@ -2596,10 +2606,10 @@ zh-TW: paragraph_1: 不像其他地圖,開放街圖是完全由像你我這類創建,而且任何都能修正、更新、下載與使用。 paragraph_2: 註冊並開始貢獻。 welcome: 歡迎來到 OpenStreetMap - duplicate_social_email: 若您已有 OpenStreetMap 帳號,並希望使用第三方身份提供者,請使用您的密碼登入並修改您帳號的設定。 - display name description: 您公開顯示的使用者名稱。您可以稍後在偏好設定中改變它。 + duplicate_social_email: 若你已有 OpenStreetMap 帳號,並希望使用第三方身份提供者,請使用你的密碼登入並修改帳號的設定。 + display name description: 你公開顯示的使用者名稱,之後可以在偏好設定中改變它。 by_signing_up: - html: 註冊即表示您同意我們的 %{tou_link}、%{privacy_policy_link} 與 %{contributor_terms_link}。 + html: 註冊即表示你同意我們的 %{tou_link}、%{privacy_policy_link} 與 %{contributor_terms_link}。 privacy_policy: 隱私權政策 privacy_policy_title: OSMF 隱私權政策包含電子郵件地址部份 contributor_terms_url: https://wiki.osmfoundation.org/wiki/Licence/Contributor_Terms @@ -2607,11 +2617,11 @@ zh-TW: tou: 使用條款 external auth: 第三方身份認證 continue: 註冊 - terms accepted: 感謝您接受新的貢獻條款! + terms accepted: 感謝你接受新的貢獻條款! email_help: privacy_policy: 隱私權政策 privacy_policy_title: OSMF 隱私權政策包含電子郵件地址部份 - html: 您的地址不會公開顯示,請參閱我們的%{privacy_policy_link}來了解更多資訊。 + html: 你的地址不會公開顯示,請參閱我們的%{privacy_policy_link}來了解更多資訊。 consider_pd_html: 我認為我的貢獻屬於 %{consider_pd_link}。 consider_pd: 公有領域 consider_pd_url: https://wiki.osmfoundation.org/wiki/Licence_and_Legal_FAQ/Why_would_I_want_my_contributions_to_be_public_domain @@ -2622,7 +2632,7 @@ zh-TW: heading: 條款 heading_ct: 貢獻者條款 read and accept with tou: 請閱讀貢獻者協議與使用條款,勾選兩項方框後點擊繼續按鈕。 - contributor_terms_explain: 此協議適用於您現有與往後貢獻的條款。 + contributor_terms_explain: 此協議適用於你現有與往後貢獻的條款。 read_ct: 我已閱讀過並同意以上的貢獻者條款 tou_explain_html: 這些%{tou_link}適用於網站方面的使用,與其它由 OSMF 提供的基礎內容。請在連結上點擊,閱讀並同意該文字。 read_tou: 我已經閱讀過並同意使用條款 @@ -2637,7 +2647,7 @@ zh-TW: legale_select: 請選擇您的居住地: legale_names: france: 法國 - italy: 意大利 + italy: 義大利 rest_of_world: 世界其他地區 terms_declined_flash: terms_declined_html: 我們很遺憾你已決定不接受新的貢獻者條款。有關詳細資訊,請參閱 %{terms_declined_link}。 @@ -2645,7 +2655,7 @@ zh-TW: no_such_user: title: 沒有這個使用者 heading: 使用者 %{user} 不存在 - body: 抱歉,沒有名為 %{user} 的使用者。請檢查您的拼字,或者可能是您按到錯誤的連結。 + body: 抱歉,沒有名為 %{user} 的使用者。請檢查你的拼字,或者可能是你按到錯誤的連結。 deleted: 已刪除賬號 show: my diary: 我的日記 @@ -2708,7 +2718,7 @@ zh-TW: confirm: 確認 report: 回報此使用者 go_public: - flash success: 現在您所有的編輯都是公開的,而您已獲准編輯。 + flash success: 現在你所有的編輯都是公開的,而你已獲准編輯。 index: title: 使用者 heading: 使用者 @@ -2726,8 +2736,8 @@ zh-TW: title: 帳號已暫停 heading: 帳號已暫停 support: 支援 - automatically_suspended: 很抱歉,出自於可疑活動緣故,您的帳號已被自動暫時停用。 - contact_support_html: 管理員將會很快審查此決定,若您想討論這個問題,您可以聯繫 %{support_link}。 + automatically_suspended: 很抱歉,出自於可疑活動緣故,你的帳號已被自動暫時停用。 + contact_support_html: 管理員將會很快審查此決定,若你想討論這個問題,可以聯繫 %{support_link}。 auth_failure: connection_failed: 連線至認證供應者失敗 invalid_credentials: 無效的認證憑證 @@ -2736,9 +2746,9 @@ zh-TW: invalid_scope: 無效範圍 unknown_error: 驗證失敗 auth_association: - heading: 您的ID尚未與OpenStreetMap帳號關聯。 - option_1: 如果您新來到OpenStreetMap,請使用下方表單建立一個帳號。 - option_2: 如果您已擁有一個帳號,您可以用您的使用者名稱與密碼登入您的帳號,並在使用者設定中關連您的ID。 + heading: 你的 ID 尚未與 OpenStreetMap 帳號關聯。 + option_1: 如果你是新來到 OpenStreetMap,請使用下方表單建立一個帳號。 + option_2: 如果你已擁有一個帳號,可以用你的使用者名稱與密碼登入你的帳號,並在使用者設定中關連你的 ID。 user_role: filter: not_a_role: 字串 "%{role}" 不是有效的身份。 @@ -2748,13 +2758,13 @@ zh-TW: grant: title: 確認授與身份 heading: 確認授與身份 - are_you_sure: 您確定要授予使用者 "%{name}" "%{role}" 的身份? + are_you_sure: 你確定要授予使用者 "%{name}" "%{role}" 的身份? confirm: 確認 fail: 無法授予使用者 "%{name}" "%{role}" 的身份。請檢查使用者和身份是否都正確。 revoke: title: 確認撤銷身份 heading: 確認撤銷身份 - are_you_sure: 您確定要撤銷使用者 "%{name}" "%{role}" 的身份? + are_you_sure: 你確定要撤銷使用者 "%{name}" "%{role}" 的身份? confirm: 確認 fail: 無法撤銷使用者 "%{name}" "%{role}" 的身份。請檢查使用者和身份是否都正確。 user_blocks: @@ -2776,12 +2786,12 @@ zh-TW: show: 檢視這項封鎖 back: 檢視所有的封鎖 filter: - block_expired: 這項封鎖已經逾期並且不能被編輯。 block_period: 封鎖期間必須是在下拉式選單中選填擇的其中一項數值。 create: flash: 已建立對使用者 %{name} 的封鎖。 update: only_creator_can_edit: 只有建立這項封鎖的仲裁員可作出編輯。 + only_creator_or_revoker_can_edit: 只有建立或撤銷此封鎖的仲裁員可作出編輯。 success: 封鎖已更新。 index: title: 使用者封鎖 @@ -2799,7 +2809,7 @@ zh-TW: title: 正在撤銷對%{block_on}的封鎖 heading_html: 正在撤銷對%{block_on}的所有封鎖 empty: '%{name}沒有生效的封鎖。' - confirm: 您確定要撤銷%{active_blocks}嗎? + confirm: 你確定要撤銷%{active_blocks}嗎? active_blocks: one: '%{count} 個生效封鎖' other: '%{count} 個生效封鎖' @@ -2843,7 +2853,7 @@ zh-TW: show: 顯示 edit: 編輯 revoke: 撤銷! - confirm: 您確定嗎? + confirm: 你確定嗎? reason: 封鎖的理由: revoker: 撤銷者: needs_view: 在還原這個封鎖之前,該使用者需要先登入。 @@ -2872,10 +2882,10 @@ zh-TW: title: 已忽視使用者 my_muted_users: 我忽視的使用者 you_have_muted_n_users: - one: 您已忽視 1 名使用者 - other: 您已忽視 %{count} 名使用者 + one: 你已忽視 1 名使用者 + other: 你已忽視 %{count} 名使用者 user_mute_explainer: 已忽視使用者的訊息會移至單獨的收件匣中,您將不會收到電子郵件通知。 - user_mute_admins_and_moderators: 您可以忽視管理員和仲裁員,但仍會收到他們的訊息通知。 + user_mute_admins_and_moderators: 你可以忽視管理員和仲裁員,但仍會收到他們的訊息通知。 table: thead: muted_user: 已忽視使用者 @@ -2884,10 +2894,10 @@ zh-TW: unmute: 取消忽視 send_message: 寄送訊息 create: - notice: 您已忽視%{name}。 + notice: 你已忽視%{name}。 error: 無法忽視%{name}。%{full_message}。 destroy: - notice: 您取消了忽視%{name}。 + notice: 你取消了忽視%{name}。 error: 無法忽視使用者。請再試一次。 notes: index: @@ -2925,17 +2935,17 @@ zh-TW: comment_and_resolve: 評論並解決 comment: 評論 log_in_to_comment: 登入來評論此註記 - report_link_html: 如果此註記含有需要移除的敏感資訊,您可以%{link}。 - other_problems_resolve: 對於註記的所有其他問題,您可以依據評論內容來自行處理。 + report_link_html: 如果此註記含有需要移除的敏感資訊,你可以%{link}。 + other_problems_resolve: 對於註記的所有其他問題,你可以依據評論內容來自行處理。 other_problems_resolved: 對於其他類型回報,解決已經足夠了。 disappear_date_html: 已解決的註記會在%{disappear_in}後從地圖中消失 new: title: 新增註記 intro: 發現錯誤或缺少些什麼東西嗎?請告訴其他地圖製作者以便於我們處理。將標記移動到正確的位置並輸入註記,以解釋問題。 - anonymous_warning_html: 您尚未登入。若您想收到您的註記更新內容,請%{log_in}或%{sign_up}。 + anonymous_warning_html: 你尚未登入。若想收到你的註記更新內容,請%{log_in}或%{sign_up}。 anonymous_warning_log_in: 登入 anonymous_warning_sign_up: 註冊 - advice: 您的註記已公開並可用於更新地圖,因此請不要輸入個人訊息,或是來自於具版權保護地圖的訊息以及目錄清單。 + advice: 你的註記已公開並可用於更新地圖,因此請不要輸入個人訊息,或是來自於具版權保護地圖的訊息以及目錄清單。 add: 送出註記 javascripts: close: 關閉 @@ -2951,14 +2961,14 @@ zh-TW: custom_dimensions: 設定自訂的尺寸 format: 格式: scale: 比例: - image_dimensions: 圖片會顯示成 %{width} x %{height} 標準圖層 + image_dimensions: 圖片會顯示成 %{width} x %{height} %{layer}圖層 download: 下載 short_url: 簡短 URL include_marker: 包括標記 center_marker: 將標記設為地圖中心點 paste_html: 貼上 HTML 以嵌入網站 view_larger_map: 查看更大的地圖 - only_standard_layer: 只有標準圖層能匯出成圖片 + only_standard_layer: 只有標準圖層、自行車地圖、交通運輸圖層能匯出成圖片 embed: report_problem: 回報問題 key: @@ -2972,11 +2982,11 @@ zh-TW: locate: title: 顯示我的位置 metersPopup: - one: 您距離此地點在 %{count} 公尺內 - other: 您距離此地點在 %{count} 公尺內 + one: 你距離此地點不到 %{count} 公尺 + other: 你距離此地點不到 %{count} 公尺 feetPopup: - one: 您距離此地點在 %{count} 英尺內 - other: 您距離此地點在 %{count} 英尺內 + one: 你距離此地點不到 %{count} 英尺 + other: 你距離此地點不到 %{count} 英尺 base: standard: 標準 cycle_map: 自行車地圖 @@ -3018,16 +3028,16 @@ zh-TW: fossgis_osrm_bike: 自行車(OSRM) fossgis_osrm_car: 開車 (OSRM) fossgis_osrm_foot: 步行(OSRM) - graphhopper_bicycle: 自行車(GraphHopper) - graphhopper_car: 汽車(GraphHopper) - graphhopper_foot: 徒步 (GraphHopper) - fossgis_valhalla_bicycle: 腳踏車 (瓦爾哈拉) - fossgis_valhalla_car: 車 (瓦爾哈拉) - fossgis_valhalla_foot: 步行 (瓦爾哈拉) + graphhopper_bicycle: 自行車 (GraphHopper) + graphhopper_car: 開車 (GraphHopper) + graphhopper_foot: 步行 (GraphHopper) + fossgis_valhalla_bicycle: 自行車 (Valhalla) + fossgis_valhalla_car: 開車 (Valhalla) + fossgis_valhalla_foot: 步行 (Valhalla) descend: 下降 directions: 路線 distance: 距離 - distance_m: '%{distance} m' + distance_m: '%{distance} 公尺' distance_km: '%{distance}公里' errors: no_route: 查無兩個地點間的路徑。 @@ -3131,13 +3141,13 @@ zh-TW: user: 建立者: edit: 編輯此修訂 destroy: 移除此修訂 - confirm: 您確定嗎? + confirm: 你確定嗎? create: flash: 修訂已建立 update: flash: 已儲存變更。 destroy: - not_empty: 修訂尚未清空。請在銷毀前清除所有此修訂的版本。 + not_empty: 修訂尚未清空,請在銷毀前清除所有此修訂的版本。 flash: 修訂已銷毀。 error: 銷毀此修訂時發生錯誤。 validations: diff --git a/config/routes.rb b/config/routes.rb index 12f6325ae..650818d6f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -78,15 +78,26 @@ OpenStreetMap::Application.routes.draw do end end + resources :messages, :path => "user/messages", :constraints => { :id => /\d+/ }, :only => [:create, :show, :destroy], :controller => "messages", :as => :api_messages do + collection do + get "inbox" + get "outbox" + end + end + + post "/user/messages/:id" => "messages#update", :as => :api_message_update + post "gpx/create" => "traces#create" get "gpx/:id" => "traces#show", :as => :api_trace, :id => /\d+/ put "gpx/:id" => "traces#update", :id => /\d+/ delete "gpx/:id" => "traces#destroy", :id => /\d+/ get "gpx/:id/details" => "traces#show", :id => /\d+/ get "gpx/:id/data" => "traces#data", :as => :api_trace_data + end + namespace :api, :path => "api/0.6" do # Map notes API - resources :notes, :except => [:new, :edit, :update], :constraints => { :id => /\d+/ }, :controller => "notes", :as => :api_notes do + resources :notes, :except => [:new, :edit, :update], :id => /\d+/, :controller => "notes" do collection do get "search" get "feed", :defaults => { :format => "rss" } @@ -99,7 +110,7 @@ OpenStreetMap::Application.routes.draw do end end - resources :user_blocks, :only => [:show], :constraints => { :id => /\d+/ }, :controller => "user_blocks", :as => :api_user_blocks + resources :user_blocks, :only => :show, :id => /\d+/, :controller => "user_blocks" end # Data browsing diff --git a/config/settings.yml b/config/settings.yml index fa7207721..71df9ad3d 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -59,6 +59,10 @@ user_block_periods: [0, 1, 3, 6, 12, 24, 48, 96, 168, 336, 731, 4383, 8766, 8766 user_account_deletion_delay: null # Rate limit for message sending max_messages_per_hour: 60 +# Default limit on the number of messages returned by inbox and outbox message api +default_message_query_limit: 100 +# Maximum number of messages returned by inbox and outbox message api +max_message_query_limit: 100 # Rate limit for friending max_friends_per_hour: 60 # Rate limit for changeset comments diff --git a/lib/oauth.rb b/lib/oauth.rb index 88db38eb4..a8f497621 100644 --- a/lib/oauth.rb +++ b/lib/oauth.rb @@ -2,7 +2,7 @@ module Oauth SCOPES = %w[read_prefs write_prefs write_diary write_api read_gpx write_gpx write_notes].freeze PRIVILEGED_SCOPES = %w[read_email skip_authorization].freeze MODERATOR_SCOPES = %w[write_redactions].freeze - OAUTH2_SCOPES = %w[write_redactions openid].freeze + OAUTH2_SCOPES = %w[write_redactions consume_messages send_messages openid].freeze class Scope attr_reader :name diff --git a/lib/rich_text.rb b/lib/rich_text.rb index f19d3d3a9..a439342f7 100644 --- a/lib/rich_text.rb +++ b/lib/rich_text.rb @@ -53,6 +53,10 @@ module RichText nil end + def image_alt + nil + end + protected def simple_format(text) @@ -92,9 +96,13 @@ module RichText end def image - return @image if defined? @image + @image_element = first_image_element(document.root) unless defined? @image_element + @image_element.attr["src"] if @image_element + end - @image = first_image_element(document.root)&.attr&.[]("src") + def image_alt + @image_element = first_image_element(document.root) unless defined? @image_element + @image_element.attr["alt"] if @image_element end private @@ -104,13 +112,17 @@ module RichText end def first_image_element(element) - return element if element.type == :img + return element if image?(element) && element.attr["src"].present? element.children.find do |child| nested_image = first_image_element(child) break nested_image if nested_image end end + + def image?(element) + element.type == :img || (element.type == :html_element && element.value == "img") + end end class Text < Base diff --git a/test/abilities/api_capability_test.rb b/test/abilities/api_capability_test.rb index 10419c0f8..bcfcaf74e 100644 --- a/test/abilities/api_capability_test.rb +++ b/test/abilities/api_capability_test.rb @@ -4,7 +4,7 @@ require "test_helper" class ChangesetCommentApiCapabilityTest < ActiveSupport::TestCase test "as a normal user with permissionless token" do - token = create(:access_token) + token = create(:oauth_access_token) capability = ApiCapability.new token [:create, :destroy, :restore].each do |action| @@ -12,8 +12,8 @@ class ChangesetCommentApiCapabilityTest < ActiveSupport::TestCase end end - test "as a normal user with allow_write_api token" do - token = create(:access_token, :allow_write_api => true) + test "as a normal user with write_api token" do + token = create(:oauth_access_token, :scopes => %w[write_api]) capability = ApiCapability.new token [:destroy, :restore].each do |action| @@ -26,7 +26,7 @@ class ChangesetCommentApiCapabilityTest < ActiveSupport::TestCase end test "as a moderator with permissionless token" do - token = create(:access_token, :user => create(:moderator_user)) + token = create(:oauth_access_token, :resource_owner_id => create(:moderator_user).id) capability = ApiCapability.new token [:create, :destroy, :restore].each do |action| @@ -34,8 +34,8 @@ class ChangesetCommentApiCapabilityTest < ActiveSupport::TestCase end end - test "as a moderator with allow_write_api token" do - token = create(:access_token, :user => create(:moderator_user), :allow_write_api => true) + test "as a moderator with write_api token" do + token = create(:oauth_access_token, :resource_owner_id => create(:moderator_user).id, :scopes => %w[write_api]) capability = ApiCapability.new token [:create, :destroy, :restore].each do |action| @@ -46,7 +46,7 @@ end class NoteApiCapabilityTest < ActiveSupport::TestCase test "as a normal user with permissionless token" do - token = create(:access_token) + token = create(:oauth_access_token) capability = ApiCapability.new token [:create, :comment, :close, :reopen, :destroy].each do |action| @@ -54,8 +54,8 @@ class NoteApiCapabilityTest < ActiveSupport::TestCase end end - test "as a normal user with allow_write_notes token" do - token = create(:access_token, :allow_write_notes => true) + test "as a normal user with write_notes token" do + token = create(:oauth_access_token, :scopes => %w[write_notes]) capability = ApiCapability.new token [:destroy].each do |action| @@ -68,7 +68,7 @@ class NoteApiCapabilityTest < ActiveSupport::TestCase end test "as a moderator with permissionless token" do - token = create(:access_token, :user => create(:moderator_user)) + token = create(:oauth_access_token, :resource_owner_id => create(:moderator_user).id) capability = ApiCapability.new token [:destroy].each do |action| @@ -76,8 +76,8 @@ class NoteApiCapabilityTest < ActiveSupport::TestCase end end - test "as a moderator with allow_write_notes token" do - token = create(:access_token, :user => create(:moderator_user), :allow_write_notes => true) + test "as a moderator with write_notes token" do + token = create(:oauth_access_token, :resource_owner_id => create(:moderator_user).id, :scopes => %w[write_notes]) capability = ApiCapability.new token [:destroy].each do |action| @@ -95,14 +95,14 @@ class UserApiCapabilityTest < ActiveSupport::TestCase end # A user with empty tokens - token = create(:access_token) + token = create(:oauth_access_token) capability = ApiCapability.new token [:index, :show, :update_all, :update, :destroy].each do |act| assert capability.cannot? act, UserPreference end - token = create(:access_token, :allow_read_prefs => true) + token = create(:oauth_access_token, :scopes => %w[read_prefs]) capability = ApiCapability.new token [:update_all, :update, :destroy].each do |act| @@ -113,7 +113,7 @@ class UserApiCapabilityTest < ActiveSupport::TestCase assert capability.can? act, UserPreference end - token = create(:access_token, :allow_write_prefs => true) + token = create(:oauth_access_token, :scopes => %w[write_prefs]) capability = ApiCapability.new token [:index, :show].each do |act| diff --git a/test/controllers/api/changeset_comments_controller_test.rb b/test/controllers/api/changeset_comments_controller_test.rb index e7d8ca209..f479b24b3 100644 --- a/test/controllers/api/changeset_comments_controller_test.rb +++ b/test/controllers/api/changeset_comments_controller_test.rb @@ -46,7 +46,7 @@ module Api assert_difference "ChangesetComment.count", 1 do assert_no_difference "ActionMailer::Base.deliveries.size" do perform_enqueued_jobs do - post changeset_comment_path(:id => private_user_closed_changeset, :text => "This is a comment"), :headers => auth_header + post changeset_comment_path(private_user_closed_changeset, :text => "This is a comment"), :headers => auth_header end end end @@ -61,7 +61,7 @@ module Api assert_difference "ChangesetComment.count", 1 do assert_difference "ActionMailer::Base.deliveries.size", 1 do perform_enqueued_jobs do - post changeset_comment_path(:id => changeset, :text => "This is a comment"), :headers => auth_header + post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header end end end @@ -79,7 +79,7 @@ module Api assert_difference "ChangesetComment.count", 1 do assert_difference "ActionMailer::Base.deliveries.size", 2 do perform_enqueued_jobs do - post changeset_comment_path(:id => changeset, :text => "This is a comment"), :headers => auth_header + post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header end end end @@ -102,32 +102,32 @@ module Api # create comment fail def test_create_comment_fail # unauthorized - post changeset_comment_path(:id => create(:changeset, :closed), :text => "This is a comment") + post changeset_comment_path(create(:changeset, :closed), :text => "This is a comment") assert_response :unauthorized auth_header = basic_authorization_header create(:user).email, "test" # bad changeset id assert_no_difference "ChangesetComment.count" do - post changeset_comment_path(:id => 999111, :text => "This is a comment"), :headers => auth_header + post changeset_comment_path(999111, :text => "This is a comment"), :headers => auth_header end assert_response :not_found # not closed changeset assert_no_difference "ChangesetComment.count" do - post changeset_comment_path(:id => create(:changeset), :text => "This is a comment"), :headers => auth_header + post changeset_comment_path(create(:changeset), :text => "This is a comment"), :headers => auth_header end assert_response :conflict # no text assert_no_difference "ChangesetComment.count" do - post changeset_comment_path(:id => create(:changeset, :closed)), :headers => auth_header + post changeset_comment_path(create(:changeset, :closed)), :headers => auth_header end assert_response :bad_request # empty text assert_no_difference "ChangesetComment.count" do - post changeset_comment_path(:id => create(:changeset, :closed), :text => ""), :headers => auth_header + post changeset_comment_path(create(:changeset, :closed), :text => ""), :headers => auth_header end assert_response :bad_request end @@ -142,13 +142,13 @@ module Api assert_difference "ChangesetComment.count", Settings.initial_changeset_comments_per_hour do 1.upto(Settings.initial_changeset_comments_per_hour) do |count| - post changeset_comment_path(:id => changeset, :text => "Comment #{count}"), :headers => auth_header + post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header assert_response :success end end assert_no_difference "ChangesetComment.count" do - post changeset_comment_path(:id => changeset, :text => "One comment too many"), :headers => auth_header + post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header assert_response :too_many_requests end end @@ -164,13 +164,13 @@ module Api assert_difference "ChangesetComment.count", Settings.max_changeset_comments_per_hour do 1.upto(Settings.max_changeset_comments_per_hour) do |count| - post changeset_comment_path(:id => changeset, :text => "Comment #{count}"), :headers => auth_header + post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header assert_response :success end end assert_no_difference "ChangesetComment.count" do - post changeset_comment_path(:id => changeset, :text => "One comment too many"), :headers => auth_header + post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header assert_response :too_many_requests end end @@ -186,13 +186,13 @@ module Api assert_difference "ChangesetComment.count", Settings.initial_changeset_comments_per_hour / 2 do 1.upto(Settings.initial_changeset_comments_per_hour / 2) do |count| - post changeset_comment_path(:id => changeset, :text => "Comment #{count}"), :headers => auth_header + post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header assert_response :success end end assert_no_difference "ChangesetComment.count" do - post changeset_comment_path(:id => changeset, :text => "One comment too many"), :headers => auth_header + post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header assert_response :too_many_requests end end @@ -207,13 +207,13 @@ module Api assert_difference "ChangesetComment.count", Settings.moderator_changeset_comments_per_hour do 1.upto(Settings.moderator_changeset_comments_per_hour) do |count| - post changeset_comment_path(:id => changeset, :text => "Comment #{count}"), :headers => auth_header + post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header assert_response :success end end assert_no_difference "ChangesetComment.count" do - post changeset_comment_path(:id => changeset, :text => "One comment too many"), :headers => auth_header + post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header assert_response :too_many_requests end end @@ -303,11 +303,11 @@ module Api # But writing oauth tests is hard, and so it's easier to put in a controller test.) def test_api_write_and_terms_agreed_via_token user = create(:user, :terms_agreed => nil) - token = create(:access_token, :user => user, :allow_write_api => true) + token = create(:oauth_access_token, :resource_owner_id => user.id, :scopes => %w[write_api]) changeset = create(:changeset, :closed) assert_difference "ChangesetComment.count", 0 do - signed_post changeset_comment_path(:id => changeset), :params => { :text => "This is a comment" }, :oauth => { :token => token } + post changeset_comment_path(changeset), :params => { :text => "This is a comment" }, :headers => bearer_authorization_header(token.token) end assert_response :forbidden @@ -316,7 +316,7 @@ module Api user.save! assert_difference "ChangesetComment.count", 1 do - signed_post changeset_comment_path(:id => changeset), :params => { :text => "This is a comment" }, :oauth => { :token => token } + post changeset_comment_path(changeset), :params => { :text => "This is a comment" }, :headers => bearer_authorization_header(token.token) end assert_response :success end @@ -330,7 +330,7 @@ module Api auth_header = basic_authorization_header user.email, "test" assert_difference "ChangesetComment.count", 0 do - post changeset_comment_path(:id => changeset, :text => "This is a comment"), :headers => auth_header + post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header end assert_response :forbidden @@ -339,7 +339,7 @@ module Api user.save! assert_difference "ChangesetComment.count", 1 do - post changeset_comment_path(:id => changeset, :text => "This is a comment"), :headers => auth_header + post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header end assert_response :success end diff --git a/test/controllers/api/changesets_controller_test.rb b/test/controllers/api/changesets_controller_test.rb index 8bb229294..1d7afa035 100644 --- a/test/controllers/api/changesets_controller_test.rb +++ b/test/controllers/api/changesets_controller_test.rb @@ -396,7 +396,7 @@ module Api # check that a changeset that doesn't exist returns an appropriate message def test_show_not_found [0, -32, 233455644, "afg", "213"].each do |id| - get changeset_show_path(:id => id) + get changeset_show_path(id) assert_response :not_found, "should get a not found" rescue ActionController::UrlGenerationError => e assert_match(/No route matches/, e.to_s) @@ -424,7 +424,7 @@ module Api auth_header = basic_authorization_header user.email, "test" cs_id = changeset.id - put changeset_close_path(:id => cs_id), :headers => auth_header + put changeset_close_path(cs_id), :headers => auth_header assert_response :success # test that it really is closed now @@ -470,7 +470,7 @@ module Api # First try to do it with no auth cs_ids.each do |id| - put changeset_close_path(:id => id) + put changeset_close_path(id) assert_response :unauthorized, "Shouldn't be able close the non-existant changeset #{id}, when not authorized" rescue ActionController::UrlGenerationError => e assert_match(/No route matches/, e.to_s) @@ -479,7 +479,7 @@ module Api # Now try with auth auth_header = basic_authorization_header create(:user).email, "test" cs_ids.each do |id| - put changeset_close_path(:id => id), :headers => auth_header + put changeset_close_path(id), :headers => auth_header assert_response :not_found, "The changeset #{id} doesn't exist, so can't be closed" rescue ActionController::UrlGenerationError => e assert_match(/No route matches/, e.to_s) @@ -636,26 +636,27 @@ module Api "can't upload a simple valid creation to changeset: #{@response.body}" # check the returned payload - assert_select "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 - assert_select "diffResult>node", 1 - assert_select "diffResult>way", 1 - assert_select "diffResult>relation", 1 - - # inspect the response to find out what the new element IDs are - doc = XML::Parser.string(@response.body).parse - new_node_id = doc.find("//diffResult/node").first["new_id"].to_i - new_way_id = doc.find("//diffResult/way").first["new_id"].to_i - new_rel_id = doc.find("//diffResult/relation").first["new_id"].to_i - - # check the old IDs are all present and negative one - assert_equal(-1, doc.find("//diffResult/node").first["old_id"].to_i) - assert_equal(-1, doc.find("//diffResult/way").first["old_id"].to_i) - assert_equal(-1, doc.find("//diffResult/relation").first["old_id"].to_i) - - # check the versions are present and equal one - assert_equal 1, doc.find("//diffResult/node").first["new_version"].to_i - assert_equal 1, doc.find("//diffResult/way").first["new_version"].to_i - assert_equal 1, doc.find("//diffResult/relation").first["new_version"].to_i + new_node_id, new_way_id, new_rel_id = nil + assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do + # inspect the response to find out what the new element IDs are + # check the old IDs are all present and negative one + # check the versions are present and equal one + assert_dom "> node", 1 do |(node_el)| + new_node_id = node_el["new_id"].to_i + assert_dom "> @old_id", "-1" + assert_dom "> @new_version", "1" + end + assert_dom "> way", 1 do |(way_el)| + new_way_id = way_el["new_id"].to_i + assert_dom "> @old_id", "-1" + assert_dom "> @new_version", "1" + end + assert_dom "> relation", 1 do |(rel_el)| + new_rel_id = rel_el["new_id"].to_i + assert_dom "> @old_id", "-1" + assert_dom "> @new_version", "1" + end + end # check that the changes made it into the database assert_equal 2, Node.find(new_node_id).tags.size, "new node should have two tags" @@ -788,7 +789,7 @@ module Api # upload it, which used to cause an error like "PGError: ERROR: # integer out of range" (bug #2152). but shouldn't any more. - post changeset_upload_path(:id => changeset_id), :params => diff, :headers => auth_header + post changeset_upload_path(changeset_id), :params => diff, :headers => auth_header assert_response :success, "can't upload a spatially-large diff to changeset: #{@response.body}" @@ -878,28 +879,26 @@ module Api "can't do a conditional delete of in use objects: #{@response.body}" # check the returned payload - assert_select "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 - assert_select "diffResult>node", 1 - assert_select "diffResult>way", 1 - assert_select "diffResult>relation", 1 - - # parse the response - doc = XML::Parser.string(@response.body).parse - - # check the old IDs are all present and what we expect - assert_equal used_node.id, doc.find("//diffResult/node").first["old_id"].to_i - assert_equal used_way.id, doc.find("//diffResult/way").first["old_id"].to_i - assert_equal used_relation.id, doc.find("//diffResult/relation").first["old_id"].to_i - - # check the new IDs are all present and unchanged - assert_equal used_node.id, doc.find("//diffResult/node").first["new_id"].to_i - assert_equal used_way.id, doc.find("//diffResult/way").first["new_id"].to_i - assert_equal used_relation.id, doc.find("//diffResult/relation").first["new_id"].to_i - - # check the new versions are all present and unchanged - assert_equal used_node.version, doc.find("//diffResult/node").first["new_version"].to_i - assert_equal used_way.version, doc.find("//diffResult/way").first["new_version"].to_i - assert_equal used_relation.version, doc.find("//diffResult/relation").first["new_version"].to_i + assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do + # check the old IDs are all present and what we expect + # check the new IDs are all present and unchanged + # check the new versions are all present and unchanged + assert_dom "> node", 1 do + assert_dom "> @old_id", used_node.id.to_s + assert_dom "> @new_id", used_node.id.to_s + assert_dom "> @new_version", used_node.version.to_s + end + assert_dom "> way", 1 do + assert_dom "> @old_id", used_way.id.to_s + assert_dom "> @new_id", used_way.id.to_s + assert_dom "> @new_version", used_way.version.to_s + end + assert_dom "> relation", 1 do + assert_dom "> @old_id", used_relation.id.to_s + assert_dom "> @new_id", used_relation.id.to_s + assert_dom "> @new_version", used_relation.version.to_s + end + end # check that nothing was, in fact, deleted assert Node.find(used_node.id).visible @@ -973,14 +972,14 @@ module Api "can't upload a complex diff to changeset: #{@response.body}" # check the returned payload - assert_select "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 - assert_select "diffResult>node", 1 - assert_select "diffResult>way", 1 - assert_select "diffResult>relation", 1 - - # inspect the response to find out what the new element IDs are - doc = XML::Parser.string(@response.body).parse - new_node_id = doc.find("//diffResult/node").first["new_id"].to_i + new_node_id = nil + assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do + assert_dom "> node", 1 do |(node_el)| + new_node_id = node_el["new_id"].to_i + end + assert_dom "> way", 1 + assert_dom "> relation", 1 + end # check that the changes made it into the database assert_equal 2, Node.find(new_node_id).tags.size, "new node should have two tags" @@ -1457,7 +1456,7 @@ module Api diff.root << modify # upload it - post changeset_upload_path(:id => changeset_id), :params => diff.to_s, :headers => auth_header + post changeset_upload_path(changeset_id), :params => diff.to_s, :headers => auth_header assert_response :success, "diff should have uploaded OK" @@ -1496,7 +1495,7 @@ module Api diff.root << modify # upload it - post changeset_upload_path(:id => changeset_id), :params => diff.to_s, :headers => auth_header + post changeset_upload_path(changeset_id), :params => diff.to_s, :headers => auth_header assert_response :success, "diff should have uploaded OK" @@ -1911,11 +1910,11 @@ module Api CHANGESET # upload it - post changeset_upload_path(:id => changeset_id), :params => diff, :headers => auth_header + post changeset_upload_path(changeset_id), :params => diff, :headers => auth_header assert_response :success, "can't upload multiple versions of an element in a diff: #{@response.body}" - get changeset_download_path(:id => changeset_id) + get changeset_download_path(changeset_id) assert_response :success assert_select "osmChange", 1 @@ -1969,11 +1968,11 @@ module Api OSMFILE # upload it - post changeset_upload_path(:id => changeset_id), :params => diff, :headers => auth_header + post changeset_upload_path(changeset_id), :params => diff, :headers => auth_header assert_response :success, "can't upload a diff from JOSM: #{@response.body}" - get changeset_download_path(:id => changeset_id) + get changeset_download_path(changeset_id) assert_response :success assert_select "osmChange", 1 @@ -2024,11 +2023,11 @@ module Api CHANGESET # upload it - post changeset_upload_path(:id => changeset_id), :params => diff, :headers => auth_header + post changeset_upload_path(changeset_id), :params => diff, :headers => auth_header assert_response :success, "can't upload multiple versions of an element in a diff: #{@response.body}" - get changeset_download_path(:id => changeset_id) + get changeset_download_path(changeset_id) assert_response :success assert_select "osmChange", 1 @@ -2121,7 +2120,7 @@ module Api end # get the bounding box back from the changeset - get changeset_show_path(:id => changeset_id) + get changeset_show_path(changeset_id) assert_response :success, "Couldn't read back changeset." assert_select "osm>changeset[min_lon='0.1000000']", 1 assert_select "osm>changeset[max_lon='0.1000000']", 1 @@ -2136,7 +2135,7 @@ module Api end # get the bounding box back from the changeset - get changeset_show_path(:id => changeset_id) + get changeset_show_path(changeset_id) assert_response :success, "Couldn't read back changeset for the second time." assert_select "osm>changeset[min_lon='0.1000000']", 1 assert_select "osm>changeset[max_lon='0.2000000']", 1 @@ -2151,7 +2150,7 @@ module Api end # get the bounding box back from the changeset - get changeset_show_path(:id => changeset_id) + get changeset_show_path(changeset_id) assert_response :success, "Couldn't read back changeset for the third time." assert_select "osm>changeset[min_lon='0.1000000']", 1 assert_select "osm>changeset[max_lon='0.3000000']", 1 @@ -2173,11 +2172,11 @@ module Api get changesets_path(:bbox => "-10,-10, 10, 10") assert_response :success, "can't get changesets in bbox" - assert_changesets [changeset2, changeset3] + assert_changesets_in_order [changeset3, changeset2] get changesets_path(:bbox => "4.5,4.5,4.6,4.6") assert_response :success, "can't get changesets in bbox" - assert_changesets [changeset3] + assert_changesets_in_order [changeset3] # not found when looking for changesets of non-existing users get changesets_path(:user => User.maximum(:id) + 1) @@ -2197,11 +2196,11 @@ module Api auth_header = basic_authorization_header private_user.email, "test" get changesets_path(:user => private_user.id), :headers => auth_header assert_response :success, "can't get changesets by user ID" - assert_changesets [private_user_changeset, private_user_closed_changeset] + assert_changesets_in_order [private_user_changeset, private_user_closed_changeset] get changesets_path(:display_name => private_user.display_name), :headers => auth_header assert_response :success, "can't get changesets by user name" - assert_changesets [private_user_changeset, private_user_closed_changeset] + assert_changesets_in_order [private_user_changeset, private_user_closed_changeset] # test json endpoint get changesets_path(:display_name => private_user.display_name), :headers => auth_header, :params => { :format => "json" } @@ -2221,39 +2220,39 @@ module Api get changesets_path(:user => private_user.id, :open => true), :headers => auth_header assert_response :success, "can't get changesets by user and open" - assert_changesets [private_user_changeset] + assert_changesets_in_order [private_user_changeset] get changesets_path(:time => "2007-12-31"), :headers => auth_header assert_response :success, "can't get changesets by time-since" - assert_changesets [private_user_changeset, private_user_closed_changeset, changeset, closed_changeset, changeset2, changeset3] + assert_changesets_in_order [changeset3, changeset2, changeset, private_user_changeset, private_user_closed_changeset, closed_changeset] get changesets_path(:time => "2008-01-01T12:34Z"), :headers => auth_header assert_response :success, "can't get changesets by time-since with hour" - assert_changesets [private_user_changeset, private_user_closed_changeset, changeset, closed_changeset, changeset2, changeset3] + assert_changesets_in_order [changeset3, changeset2, changeset, private_user_changeset, private_user_closed_changeset, closed_changeset] get changesets_path(:time => "2007-12-31T23:59Z,2008-01-02T00:01Z"), :headers => auth_header assert_response :success, "can't get changesets by time-range" - assert_changesets [closed_changeset] + assert_changesets_in_order [closed_changeset] get changesets_path(:open => "true"), :headers => auth_header assert_response :success, "can't get changesets by open-ness" - assert_changesets [private_user_changeset, changeset, changeset2, changeset3] + assert_changesets_in_order [changeset3, changeset2, changeset, private_user_changeset] get changesets_path(:closed => "true"), :headers => auth_header assert_response :success, "can't get changesets by closed-ness" - assert_changesets [private_user_closed_changeset, closed_changeset] + assert_changesets_in_order [private_user_closed_changeset, closed_changeset] get changesets_path(:closed => "true", :user => private_user.id), :headers => auth_header assert_response :success, "can't get changesets by closed-ness and user" - assert_changesets [private_user_closed_changeset] + assert_changesets_in_order [private_user_closed_changeset] get changesets_path(:closed => "true", :user => user.id), :headers => auth_header assert_response :success, "can't get changesets by closed-ness and user" - assert_changesets [closed_changeset] + assert_changesets_in_order [closed_changeset] get changesets_path(:changesets => "#{private_user_changeset.id},#{changeset.id},#{closed_changeset.id}"), :headers => auth_header assert_response :success, "can't get changesets by id (as comma-separated string)" - assert_changesets [private_user_changeset, changeset, closed_changeset] + assert_changesets_in_order [changeset, private_user_changeset, closed_changeset] get changesets_path(:changesets => ""), :headers => auth_header assert_response :bad_request, "should be a bad request since changesets is empty" @@ -2642,7 +2641,7 @@ module Api # bad changeset id assert_no_difference "changeset.subscribers.count" do - post api_changeset_unsubscribe_path(:id => 999111), :headers => auth_header + post api_changeset_unsubscribe_path(999111), :headers => auth_header end assert_response :not_found @@ -2683,15 +2682,6 @@ module Api end end - ## - # check that certain changesets exist in the output - def assert_changesets(changesets) - assert_select "osm>changeset", changesets.size - changesets.each do |changeset| - assert_select "osm>changeset[id='#{changeset.id}']", 1 - end - end - ## # check that certain changesets exist in the output in the specified order def assert_changesets_in_order(changesets) diff --git a/test/controllers/api/messages_controller_test.rb b/test/controllers/api/messages_controller_test.rb new file mode 100644 index 000000000..0b54be4dc --- /dev/null +++ b/test/controllers/api/messages_controller_test.rb @@ -0,0 +1,611 @@ +require "test_helper" + +module Api + class MessagesControllerTest < ActionDispatch::IntegrationTest + ## + # test all routes which lead to this controller + def test_routes + assert_routing( + { :path => "/api/0.6/user/messages/inbox", :method => :get }, + { :controller => "api/messages", :action => "inbox" } + ) + assert_routing( + { :path => "/api/0.6/user/messages/inbox.xml", :method => :get }, + { :controller => "api/messages", :action => "inbox", :format => "xml" } + ) + assert_routing( + { :path => "/api/0.6/user/messages/inbox.json", :method => :get }, + { :controller => "api/messages", :action => "inbox", :format => "json" } + ) + assert_routing( + { :path => "/api/0.6/user/messages/outbox", :method => :get }, + { :controller => "api/messages", :action => "outbox" } + ) + assert_routing( + { :path => "/api/0.6/user/messages/outbox.xml", :method => :get }, + { :controller => "api/messages", :action => "outbox", :format => "xml" } + ) + assert_routing( + { :path => "/api/0.6/user/messages/outbox.json", :method => :get }, + { :controller => "api/messages", :action => "outbox", :format => "json" } + ) + assert_routing( + { :path => "/api/0.6/user/messages/1", :method => :get }, + { :controller => "api/messages", :action => "show", :id => "1" } + ) + assert_routing( + { :path => "/api/0.6/user/messages/1.xml", :method => :get }, + { :controller => "api/messages", :action => "show", :id => "1", :format => "xml" } + ) + assert_routing( + { :path => "/api/0.6/user/messages/1.json", :method => :get }, + { :controller => "api/messages", :action => "show", :id => "1", :format => "json" } + ) + assert_routing( + { :path => "/api/0.6/user/messages", :method => :post }, + { :controller => "api/messages", :action => "create" } + ) + assert_routing( + { :path => "/api/0.6/user/messages/1", :method => :post }, + { :controller => "api/messages", :action => "update", :id => "1" } + ) + assert_routing( + { :path => "/api/0.6/user/messages/1", :method => :delete }, + { :controller => "api/messages", :action => "destroy", :id => "1" } + ) + end + + def test_create_success + recipient = create(:user) + sender = create(:user) + + sender_token = create(:oauth_access_token, + :resource_owner_id => sender.id, + :scopes => %w[send_messages consume_messages]) + sender_auth = bearer_authorization_header(sender_token.token) + + msg = build(:message) + + assert_difference "Message.count", 1 do + assert_difference "ActionMailer::Base.deliveries.size", 1 do + perform_enqueued_jobs do + post api_messages_path, + :params => { :title => msg.title, + :recipient_id => recipient.id, + :body => msg.body, + :format => "json" }, + :headers => sender_auth + assert_response :success + end + end + end + + assert_equal "application/json", response.media_type + js = ActiveSupport::JSON.decode(@response.body) + jsm = js["message"] + assert_not_nil jsm + assert_not_nil jsm["id"] + assert_equal sender.id, jsm["from_user_id"] + assert_equal sender.display_name, jsm["from_display_name"] + assert_equal recipient.id, jsm["to_user_id"] + assert_equal recipient.display_name, jsm["to_display_name"] + assert_equal msg.title, jsm["title"] + assert_not_nil jsm["sent_on"] + assert_equal !msg.from_user_visible, jsm["deleted"] + assert_not jsm.key?("message_read") + assert_equal "markdown", jsm["body_format"] + assert_equal msg.body, jsm["body"] + end + + def test_create_fail + recipient = create(:user) + + sender = create(:user) + sender_token = create(:oauth_access_token, + :resource_owner_id => sender.id, + :scopes => %w[send_messages consume_messages]) + sender_auth = bearer_authorization_header(sender_token.token) + + assert_no_difference "Message.count" do + assert_no_difference "ActionMailer::Base.deliveries.size" do + perform_enqueued_jobs do + post api_messages_path, + :params => { :title => "Title", + :recipient_id => recipient.id, + :body => "body" } + end + end + end + assert_response :unauthorized + + assert_no_difference "Message.count" do + assert_no_difference "ActionMailer::Base.deliveries.size" do + perform_enqueued_jobs do + post api_messages_path, + :params => { :recipient_id => recipient.id, + :body => "body" }, + :headers => sender_auth + end + end + end + assert_response :bad_request + + assert_no_difference "Message.count" do + assert_no_difference "ActionMailer::Base.deliveries.size" do + perform_enqueued_jobs do + post api_messages_path, + :params => { :title => "Title", + :body => "body" }, + :headers => sender_auth + end + end + end + assert_response :bad_request + + assert_no_difference "Message.count" do + assert_no_difference "ActionMailer::Base.deliveries.size" do + perform_enqueued_jobs do + post api_messages_path, + :params => { :title => "Title", + :recipient_id => recipient.id }, + :headers => sender_auth + end + end + end + assert_response :bad_request + end + + def test_show + recipient = create(:user) + sender = create(:user) + user3 = create(:user) + + sender_token = create(:oauth_access_token, + :resource_owner_id => sender.id, + :scopes => %w[consume_messages]) + sender_auth = bearer_authorization_header(sender_token.token) + + recipient_token = create(:oauth_access_token, + :resource_owner_id => recipient.id, + :scopes => %w[consume_messages]) + recipient_auth = bearer_authorization_header(recipient_token.token) + + user3_token = create(:oauth_access_token, + :resource_owner_id => user3.id, + :scopes => %w[send_messages consume_messages]) + user3_auth = bearer_authorization_header(user3_token.token) + + msg = create(:message, :unread, :sender => sender, :recipient => recipient) + + # fail if not authorized + get api_message_path(:id => msg.id) + assert_response :unauthorized + + # only recipient and sender can read the message + get api_message_path(:id => msg.id), :headers => user3_auth + assert_response :forbidden + + # message does not exist + get api_message_path(:id => 99999), :headers => user3_auth + assert_response :not_found + + # verify xml output + get api_message_path(:id => msg.id), :headers => recipient_auth + assert_equal "application/xml", response.media_type + assert_select "message", :count => 1 do + assert_select "[id='#{msg.id}']" + assert_select "[from_user_id='#{sender.id}']" + assert_select "[from_display_name='#{sender.display_name}']" + assert_select "[to_user_id='#{recipient.id}']" + assert_select "[to_display_name='#{recipient.display_name}']" + assert_select "[sent_on]" + assert_select "[deleted='#{!msg.to_user_visible}']" + assert_select "[message_read='#{msg.message_read}']" + assert_select "[body_format='markdown']" + assert_select "title", msg.title + assert_select "body", msg.body + end + + # verify json output + get api_message_path(:id => msg.id, :format => "json"), :headers => recipient_auth + assert_equal "application/json", response.media_type + js = ActiveSupport::JSON.decode(@response.body) + jsm = js["message"] + assert_not_nil jsm + assert_equal msg.id, jsm["id"] + assert_equal sender.id, jsm["from_user_id"] + assert_equal sender.display_name, jsm["from_display_name"] + assert_equal recipient.id, jsm["to_user_id"] + assert_equal recipient.display_name, jsm["to_display_name"] + assert_equal msg.title, jsm["title"] + assert_not_nil jsm["sent_on"] + assert_equal msg.message_read, jsm["message_read"] + assert_equal !msg.to_user_visible, jsm["deleted"] + assert_equal "markdown", jsm["body_format"] + assert_equal msg.body, jsm["body"] + + get api_message_path(:id => msg.id), :headers => sender_auth + assert_equal "application/xml", response.media_type + assert_select "message", :count => 1 do + assert_select "[id='#{msg.id}']" + assert_select "[from_user_id='#{sender.id}']" + assert_select "[from_display_name='#{sender.display_name}']" + assert_select "[to_user_id='#{recipient.id}']" + assert_select "[to_display_name='#{recipient.display_name}']" + assert_select "[sent_on]" + assert_select "[deleted='#{!msg.from_user_visible}']" + assert_select "[message_read='#{msg.message_read}']", 0 + assert_select "[body_format='markdown']" + assert_select "title", msg.title + assert_select "body", msg.body + end + + # verify json output + get api_message_path(:id => msg.id, :format => "json"), :headers => sender_auth + assert_equal "application/json", response.media_type + js = ActiveSupport::JSON.decode(@response.body) + jsm = js["message"] + assert_not_nil jsm + assert_equal msg.id, jsm["id"] + assert_equal sender.id, jsm["from_user_id"] + assert_equal sender.display_name, jsm["from_display_name"] + assert_equal recipient.id, jsm["to_user_id"] + assert_equal recipient.display_name, jsm["to_display_name"] + assert_equal msg.title, jsm["title"] + assert_not_nil jsm["sent_on"] + assert_equal !msg.from_user_visible, jsm["deleted"] + assert_not jsm.key?("message_read") + assert_equal "markdown", jsm["body_format"] + assert_equal msg.body, jsm["body"] + end + + def test_update_status + recipient = create(:user) + sender = create(:user) + user3 = create(:user) + + recipient_token = create(:oauth_access_token, + :resource_owner_id => recipient.id, + :scopes => %w[consume_messages]) + recipient_auth = bearer_authorization_header(recipient_token.token) + + user3_token = create(:oauth_access_token, + :resource_owner_id => user3.id, + :scopes => %w[send_messages consume_messages]) + user3_auth = bearer_authorization_header(user3_token.token) + + msg = create(:message, :unread, :sender => sender, :recipient => recipient) + + # attempt to mark message as read by recipient, not authenticated + post api_message_path(:id => msg.id), :params => { :read_status => true } + assert_response :unauthorized + + # attempt to mark message as read by recipient, not allowed + post api_message_path(:id => msg.id), :params => { :read_status => true }, :headers => user3_auth + assert_response :forbidden + + # missing parameter + post api_message_path(:id => msg.id), :headers => recipient_auth + assert_response :bad_request + + # wrong type of parameter + post api_message_path(:id => msg.id), + :params => { :read_status => "not a boolean" }, + :headers => recipient_auth + assert_response :bad_request + + # mark message as read by recipient + post api_message_path(:id => msg.id, :format => "json"), + :params => { :read_status => true }, + :headers => recipient_auth + assert_response :success + assert_equal "application/json", response.media_type + js = ActiveSupport::JSON.decode(@response.body) + jsm = js["message"] + assert_not_nil jsm + assert_equal msg.id, jsm["id"] + assert_equal sender.id, jsm["from_user_id"] + assert_equal sender.display_name, jsm["from_display_name"] + assert_equal recipient.id, jsm["to_user_id"] + assert_equal recipient.display_name, jsm["to_display_name"] + assert_equal msg.title, jsm["title"] + assert_not_nil jsm["sent_on"] + assert jsm["message_read"] + assert_equal !msg.to_user_visible, jsm["deleted"] + assert_equal "markdown", jsm["body_format"] + assert_equal msg.body, jsm["body"] + + # mark message as unread by recipient + post api_message_path(:id => msg.id, :format => "json"), + :params => { :read_status => false }, + :headers => recipient_auth + assert_response :success + assert_equal "application/json", response.media_type + js = ActiveSupport::JSON.decode(@response.body) + jsm = js["message"] + assert_not_nil jsm + assert_equal msg.id, jsm["id"] + assert_equal sender.id, jsm["from_user_id"] + assert_equal sender.display_name, jsm["from_display_name"] + assert_equal recipient.id, jsm["to_user_id"] + assert_equal recipient.display_name, jsm["to_display_name"] + assert_equal msg.title, jsm["title"] + assert_not_nil jsm["sent_on"] + assert_not jsm["message_read"] + assert_equal !msg.to_user_visible, jsm["deleted"] + assert_equal "markdown", jsm["body_format"] + assert_equal msg.body, jsm["body"] + end + + def test_delete + recipient = create(:user) + recipient_token = create(:oauth_access_token, + :resource_owner_id => recipient.id, + :scopes => %w[consume_messages]) + recipient_auth = bearer_authorization_header(recipient_token.token) + + sender = create(:user) + sender_token = create(:oauth_access_token, + :resource_owner_id => sender.id, + :scopes => %w[send_messages consume_messages]) + sender_auth = bearer_authorization_header(sender_token.token) + + user3 = create(:user) + user3_token = create(:oauth_access_token, + :resource_owner_id => user3.id, + :scopes => %w[send_messages consume_messages]) + user3_auth = bearer_authorization_header(user3_token.token) + + msg = create(:message, :read, :sender => sender, :recipient => recipient) + + # attempt to delete message, not authenticated + delete api_message_path(:id => msg.id) + assert_response :unauthorized + + # attempt to delete message, by user3 + delete api_message_path(:id => msg.id), :headers => user3_auth + assert_response :forbidden + + # delete message by recipient + delete api_message_path(:id => msg.id, :format => "json"), :headers => recipient_auth + assert_response :success + assert_equal "application/json", response.media_type + js = ActiveSupport::JSON.decode(@response.body) + jsm = js["message"] + assert_not_nil jsm + assert_equal msg.id, jsm["id"] + assert_equal sender.id, jsm["from_user_id"] + assert_equal sender.display_name, jsm["from_display_name"] + assert_equal recipient.id, jsm["to_user_id"] + assert_equal recipient.display_name, jsm["to_display_name"] + assert_equal msg.title, jsm["title"] + assert_not_nil jsm["sent_on"] + assert_equal msg.message_read, jsm["message_read"] + assert jsm["deleted"] + assert_equal "markdown", jsm["body_format"] + assert_equal msg.body, jsm["body"] + + # delete message by sender + delete api_message_path(:id => msg.id, :format => "json"), :headers => sender_auth + assert_response :success + assert_equal "application/json", response.media_type + js = ActiveSupport::JSON.decode(@response.body) + jsm = js["message"] + assert_not_nil jsm + assert_equal msg.id, jsm["id"] + assert_equal sender.id, jsm["from_user_id"] + assert_equal sender.display_name, jsm["from_display_name"] + assert_equal recipient.id, jsm["to_user_id"] + assert_equal recipient.display_name, jsm["to_display_name"] + assert_equal msg.title, jsm["title"] + assert_not_nil jsm["sent_on"] + assert jsm["deleted"] + assert_not jsm.key?("message_read") + assert_equal "markdown", jsm["body_format"] + assert_equal msg.body, jsm["body"] + end + + def test_list_messages + user1 = create(:user) + user1_token = create(:oauth_access_token, + :resource_owner_id => user1.id, + :scopes => %w[send_messages consume_messages]) + user1_auth = bearer_authorization_header(user1_token.token) + + user2 = create(:user) + user2_token = create(:oauth_access_token, + :resource_owner_id => user2.id, + :scopes => %w[send_messages consume_messages]) + user2_auth = bearer_authorization_header(user2_token.token) + + user3 = create(:user) + user3_token = create(:oauth_access_token, + :resource_owner_id => user3.id, + :scopes => %w[send_messages consume_messages]) + user3_auth = bearer_authorization_header(user3_token.token) + + # create some messages between users + # user | inbox | outbox + # 1 | 0 | 3 + # 2 | 2 | 1 + # 3 | 2 | 0 + create(:message, :unread, :sender => user1, :recipient => user2) + create(:message, :unread, :sender => user1, :recipient => user2) + create(:message, :unread, :sender => user1, :recipient => user3) + create(:message, :unread, :sender => user2, :recipient => user3) + + # only authorized users + get inbox_api_messages_path + assert_response :unauthorized + get outbox_api_messages_path + assert_response :unauthorized + + # no messages in user1.inbox + get inbox_api_messages_path, :headers => user1_auth + assert_response :success + assert_equal "application/xml", response.media_type + assert_select "message", :count => 0 + + # 3 messages in user1.outbox + get outbox_api_messages_path, :headers => user1_auth + assert_response :success + assert_equal "application/xml", response.media_type + assert_select "message", :count => 3 do + assert_select "[from_user_id='#{user1.id}']" + assert_select "[from_display_name='#{user1.display_name}']" + assert_select "[to_user_id]" + assert_select "[to_display_name]" + assert_select "[sent_on]" + assert_select "[message_read]", 0 + assert_select "[deleted='false']" + assert_select "[body_format]" + assert_select "body", false + assert_select "title" + end + + # 2 messages in user2.inbox + get inbox_api_messages_path, :headers => user2_auth + assert_response :success + assert_equal "application/xml", response.media_type + assert_select "message", :count => 2 do + assert_select "[from_user_id]" + assert_select "[from_display_name]" + assert_select "[to_user_id='#{user2.id}']" + assert_select "[to_display_name='#{user2.display_name}']" + assert_select "[sent_on]" + assert_select "[message_read='false']" + assert_select "[deleted='false']" + assert_select "[body_format]" + assert_select "body", false + assert_select "title" + end + + # 1 message in user2.outbox + get outbox_api_messages_path, :headers => user2_auth + assert_response :success + assert_equal "application/xml", response.media_type + assert_select "message", :count => 1 do + assert_select "[from_user_id='#{user2.id}']" + assert_select "[from_display_name='#{user2.display_name}']" + assert_select "[to_user_id]" + assert_select "[to_display_name]" + assert_select "[sent_on]" + assert_select "[deleted='false']" + assert_select "[message_read]", 0 + assert_select "[body_format]" + assert_select "body", false + assert_select "title" + end + + # 2 messages in user3.inbox + get inbox_api_messages_path, :headers => user3_auth + assert_response :success + assert_equal "application/xml", response.media_type + assert_select "message", :count => 2 do + assert_select "[from_user_id]" + assert_select "[from_display_name]" + assert_select "[to_user_id='#{user3.id}']" + assert_select "[to_display_name='#{user3.display_name}']" + assert_select "[sent_on]" + assert_select "[message_read='false']" + assert_select "[deleted='false']" + assert_select "[body_format]" + assert_select "body", false + assert_select "title" + end + + # 0 messages in user3.outbox + get outbox_api_messages_path, :headers => user3_auth + assert_response :success + assert_equal "application/xml", response.media_type + assert_select "message", :count => 0 + end + + def test_paged_list_messages_asc + recipient = create(:user) + recipient_token = create(:oauth_access_token, + :resource_owner_id => recipient.id, + :scopes => %w[consume_messages]) + recipient_auth = bearer_authorization_header(recipient_token.token) + + sender = create(:user) + + create_list(:message, 100, :unread, :sender => sender, :recipient => recipient) + + msgs_read = {} + params = { :order => "oldest", :limit => 20 } + 10.times do + get inbox_api_messages_path(:format => "json"), + :params => params, + :headers => recipient_auth + assert_response :success + assert_equal "application/json", response.media_type + js = ActiveSupport::JSON.decode(@response.body) + jsm = js["messages"] + assert_operator jsm.count, :<=, 20 + + break if jsm.nil? || jsm.count.zero? + + assert_operator(jsm[0]["id"], :>=, params[:from_id]) unless params[:from_id].nil? + # ensure ascending order + (0..jsm.count - 1).each do |i| + assert_operator(jsm[i]["id"], :<, jsm[i + 1]["id"]) unless i == jsm.count - 1 + msgs_read[jsm[i]["id"]] = jsm[i] + end + params[:from_id] = jsm[jsm.count - 1]["id"] + end + assert_equal 100, msgs_read.count + end + + def test_paged_list_messages_desc + recipient = create(:user) + recipient_token = create(:oauth_access_token, + :resource_owner_id => recipient.id, + :scopes => %w[consume_messages]) + recipient_auth = bearer_authorization_header(recipient_token.token) + + sender = create(:user) + + create_list(:message, 100, :unread, :sender => sender, :recipient => recipient) + + real_max_id = -1 + msgs_read = {} + params = { :order => "newest", :limit => 20 } + 10.times do + get inbox_api_messages_path(:format => "json"), + :params => params, + :headers => recipient_auth + assert_response :success + assert_equal "application/json", response.media_type + js = ActiveSupport::JSON.decode(@response.body) + jsm = js["messages"] + assert_operator jsm.count, :<=, 20 + + break if jsm.nil? || jsm.count.zero? + + if params[:from_id].nil? + real_max_id = jsm[0]["id"] + else + assert_operator jsm[0]["id"], :<=, params[:from_id] + end + # ensure descending order + (0..jsm.count - 1).each do |i| + assert_operator(jsm[i]["id"], :>, jsm[i + 1]["id"]) unless i == jsm.count - 1 + msgs_read[jsm[i]["id"]] = jsm[i] + end + params[:from_id] = jsm[jsm.count - 1]["id"] + end + assert_equal 100, msgs_read.count + assert_not_equal(-1, real_max_id) + + # invoke without min_id/max_id parameters, verify that we get the last batch + get inbox_api_messages_path(:format => "json"), :params => { :limit => 20 }, :headers => recipient_auth + assert_response :success + assert_equal "application/json", response.media_type + js = ActiveSupport::JSON.decode(@response.body) + jsm = js["messages"] + assert_not_nil jsm + assert_equal real_max_id, jsm[0]["id"] + end + end +end diff --git a/test/controllers/api/nodes_controller_test.rb b/test/controllers/api/nodes_controller_test.rb index 5fde0277c..d70c92861 100644 --- a/test/controllers/api/nodes_controller_test.rb +++ b/test/controllers/api/nodes_controller_test.rb @@ -297,6 +297,8 @@ module Api # tests whether the API works and prevents incorrect use while trying # to update nodes. def test_update + invalid_attr_values = [["lat", 91.0], ["lat", -91.0], ["lon", 181.0], ["lon", -181.0]] + ## First test with no user credentials # try and update a node without authorisation # first try to delete node without auth @@ -334,21 +336,11 @@ module Api assert_require_public_data "update with changeset=0 should be forbidden, when data isn't public" ## try and submit invalid updates - xml = xml_attr_rewrite(xml_for_node(private_node), "lat", 91.0) - put api_node_path(private_node), :params => xml.to_s, :headers => auth_header - assert_require_public_data "node at lat=91 should be forbidden, when data isn't public" - - xml = xml_attr_rewrite(xml_for_node(private_node), "lat", -91.0) - put api_node_path(private_node), :params => xml.to_s, :headers => auth_header - assert_require_public_data "node at lat=-91 should be forbidden, when data isn't public" - - xml = xml_attr_rewrite(xml_for_node(private_node), "lon", 181.0) - put api_node_path(private_node), :params => xml.to_s, :headers => auth_header - assert_require_public_data "node at lon=181 should be forbidden, when data isn't public" - - xml = xml_attr_rewrite(xml_for_node(private_node), "lon", -181.0) - put api_node_path(private_node), :params => xml.to_s, :headers => auth_header - assert_require_public_data "node at lon=-181 should be forbidden, when data isn't public" + invalid_attr_values.each do |name, value| + xml = xml_attr_rewrite(xml_for_node(private_node), name, value) + put api_node_path(private_node), :params => xml.to_s, :headers => auth_header + assert_require_public_data "node at #{name}=#{value} should be forbidden, when data isn't public" + end ## finally, produce a good request which still won't work xml = xml_for_node(private_node) @@ -386,21 +378,11 @@ module Api assert_response :conflict, "update with changeset=0 should be rejected" ## try and submit invalid updates - xml = xml_attr_rewrite(xml_for_node(node), "lat", 91.0) - put api_node_path(node), :params => xml.to_s, :headers => auth_header - assert_response :bad_request, "node at lat=91 should be rejected" - - xml = xml_attr_rewrite(xml_for_node(node), "lat", -91.0) - put api_node_path(node), :params => xml.to_s, :headers => auth_header - assert_response :bad_request, "node at lat=-91 should be rejected" - - xml = xml_attr_rewrite(xml_for_node(node), "lon", 181.0) - put api_node_path(node), :params => xml.to_s, :headers => auth_header - assert_response :bad_request, "node at lon=181 should be rejected" - - xml = xml_attr_rewrite(xml_for_node(node), "lon", -181.0) - put api_node_path(node), :params => xml.to_s, :headers => auth_header - assert_response :bad_request, "node at lon=-181 should be rejected" + invalid_attr_values.each do |name, value| + xml = xml_attr_rewrite(xml_for_node(node), name, value) + put api_node_path(node), :params => xml.to_s, :headers => auth_header + assert_response :bad_request, "node at #{name}=#{value} should be rejected" + end ## next, attack the versioning current_node_version = node.version diff --git a/test/controllers/api/relations_controller_test.rb b/test/controllers/api/relations_controller_test.rb index 982df1dd7..eba3d255e 100644 --- a/test/controllers/api/relations_controller_test.rb +++ b/test/controllers/api/relations_controller_test.rb @@ -1089,7 +1089,7 @@ module Api # now download the changeset to check its bounding box with_controller(Api::ChangesetsController.new) do - get changeset_show_path(:id => changeset_id) + get changeset_show_path(changeset_id) assert_response :success, "can't re-read changeset for modify test" assert_select "osm>changeset", 1, "Changeset element doesn't exist in #{@response.body}" assert_select "osm>changeset[id='#{changeset_id}']", 1, "Changeset id=#{changeset_id} doesn't exist in #{@response.body}" @@ -1153,7 +1153,7 @@ module Api change << modify modify << doc.import(rel.find("//osm/relation").first) - post changeset_upload_path(:id => cs_id), :params => doc.to_s, :headers => headers + post changeset_upload_path(cs_id), :params => doc.to_s, :headers => headers assert_response :success, "can't upload diff relation: #{@response.body}" version = xml_parse(@response.body).find("//diffResult/relation").first["new_version"].to_i end diff --git a/test/controllers/api/user_preferences_controller_test.rb b/test/controllers/api/user_preferences_controller_test.rb index 4e96d4ce9..41406e1b3 100644 --- a/test/controllers/api/user_preferences_controller_test.rb +++ b/test/controllers/api/user_preferences_controller_test.rb @@ -252,10 +252,10 @@ module Api # read preferences def test_show_using_token user = create(:user) - token = create(:access_token, :user => user, :allow_read_prefs => true) + token = create(:oauth_access_token, :resource_owner_id => user.id, :scopes => %w[read_prefs]) create(:user_preference, :user => user, :k => "key", :v => "value") - signed_get user_preference_path(:preference_key => "key"), :oauth => { :token => token } + get user_preference_path(:preference_key => "key"), :headers => bearer_authorization_header(token.token) assert_response :success end @@ -264,10 +264,10 @@ module Api # by other methods. def test_show_using_token_fail user = create(:user) - token = create(:access_token, :user => user, :allow_read_prefs => false) + token = create(:oauth_access_token, :resource_owner_id => user.id) create(:user_preference, :user => user, :k => "key", :v => "value") - signed_get user_preference_path(:preference_key => "key"), :oauth => { :token => token } + get user_preference_path(:preference_key => "key"), :headers => bearer_authorization_header(token.token) assert_response :forbidden end end diff --git a/test/controllers/diary_entries_controller_test.rb b/test/controllers/diary_entries_controller_test.rb index bb6c25781..e3bbb490d 100644 --- a/test/controllers/diary_entries_controller_test.rb +++ b/test/controllers/diary_entries_controller_test.rb @@ -119,9 +119,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1 assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1 assert_select "input[name=commit][type=submit][value=Publish]", :count => 1 - assert_select "input[name=commit][type=submit][value=Edit]", :count => 1 - assert_select "input[name=commit][type=submit][value=Preview]", :count => 1 - assert_select "input", :count => 6 + assert_select "button[type=button]", :text => "Edit", :count => 1 + assert_select "button[type=button]", :text => "Preview", :count => 1 + assert_select "input", :count => 4 end end end @@ -272,9 +272,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1 assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1 assert_select "input[name=commit][type=submit][value=Update]", :count => 1 - assert_select "input[name=commit][type=submit][value=Edit]", :count => 1 - assert_select "input[name=commit][type=submit][value=Preview]", :count => 1 - assert_select "input", :count => 7 + assert_select "button[type=button]", :text => "Edit", :count => 1 + assert_select "button[type=button]", :text => "Preview", :count => 1 + assert_select "input", :count => 5 end end @@ -657,6 +657,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest assert_dom "head meta[property='og:image']" do assert_dom "> @content", ActionController::Base.helpers.image_url("osm_logo_256.png", :host => root_url) end + assert_dom "head meta[property='og:image:alt']" do + assert_dom "> @content", "OpenStreetMap logo" + end end def test_show_og_image @@ -668,6 +671,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest assert_dom "head meta[property='og:image']" do assert_dom "> @content", "https://example.com/picture.jpg" end + assert_dom "head meta[property='og:image:alt']" do + assert_dom "> @content", "some picture" + end end def test_show_og_image_with_relative_uri @@ -679,6 +685,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest assert_dom "head meta[property='og:image']" do assert_dom "> @content", "#{root_url}picture.jpg" end + assert_dom "head meta[property='og:image:alt']" do + assert_dom "> @content", "some local picture" + end end def test_show_og_image_with_spaces @@ -690,6 +699,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest assert_dom "head meta[property='og:image']" do assert_dom "> @content", "https://example.com/the%20picture.jpg" end + assert_dom "head meta[property='og:image:alt']" do + assert_dom "> @content", "some picture" + end end def test_show_og_image_with_relative_uri_and_spaces @@ -701,6 +713,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest assert_dom "head meta[property='og:image']" do assert_dom "> @content", "#{root_url}the%20picture.jpg" end + assert_dom "head meta[property='og:image:alt']" do + assert_dom "> @content", "some local picture" + end end def test_show_og_image_with_invalid_uri @@ -712,6 +727,21 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest assert_dom "head meta[property='og:image']" do assert_dom "> @content", ActionController::Base.helpers.image_url("osm_logo_256.png", :host => root_url) end + assert_dom "head meta[property='og:image:alt']" do + assert_dom "> @content", "OpenStreetMap logo" + end + end + + def test_show_og_image_without_alt + user = create(:user) + diary_entry = create(:diary_entry, :user => user, :body => "") + + get diary_entry_path(user, diary_entry) + assert_response :success + assert_dom "head meta[property='og:image']" do + assert_dom "> @content", "https://example.com/no_alt.gif" + end + assert_dom "head meta[property='og:image:alt']", :count => 0 end def test_hide diff --git a/test/controllers/issues_controller_test.rb b/test/controllers/issues_controller_test.rb index a988fc909..167bcc7b6 100644 --- a/test/controllers/issues_controller_test.rb +++ b/test/controllers/issues_controller_test.rb @@ -27,22 +27,22 @@ class IssuesControllerTest < ActionDispatch::IntegrationTest issue = create(:issue, :reportable => target_user, :reported_user => target_user, :assigned_role => "moderator") # Access issue without login - get issue_path(:id => issue) + get issue_path(issue) assert_redirected_to login_path(:referer => issue_path(issue)) # Access issue as normal user session_for(create(:user)) - get issue_path(:id => issue) + get issue_path(issue) assert_redirected_to :controller => :errors, :action => :forbidden # Access issue as administrator session_for(create(:administrator_user)) - get issue_path(:id => issue) + get issue_path(issue) assert_redirected_to :controller => :errors, :action => :not_found # Access issue as moderator session_for(create(:moderator_user)) - get issue_path(:id => issue) + get issue_path(issue) assert_response :success end @@ -51,22 +51,22 @@ class IssuesControllerTest < ActionDispatch::IntegrationTest issue = create(:issue, :reportable => target_user, :reported_user => target_user, :assigned_role => "administrator") # Access issue without login - get issue_path(:id => issue) + get issue_path(issue) assert_redirected_to login_path(:referer => issue_path(issue)) # Access issue as normal user session_for(create(:user)) - get issue_path(:id => issue) + get issue_path(issue) assert_redirected_to :controller => :errors, :action => :forbidden # Access issue as moderator session_for(create(:moderator_user)) - get issue_path(:id => issue) + get issue_path(issue) assert_redirected_to :controller => :errors, :action => :not_found # Access issue as administrator session_for(create(:administrator_user)) - get issue_path(:id => issue) + get issue_path(issue) assert_response :success end @@ -75,23 +75,23 @@ class IssuesControllerTest < ActionDispatch::IntegrationTest issue = create(:issue, :reportable => target_user, :reported_user => target_user, :assigned_role => "moderator") # Resolve issue without login - post resolve_issue_path(:id => issue) + post resolve_issue_path(issue) assert_response :forbidden # Resolve issue as normal user session_for(create(:user)) - post resolve_issue_path(:id => issue) + post resolve_issue_path(issue) assert_redirected_to :controller => :errors, :action => :forbidden # Resolve issue as administrator session_for(create(:administrator_user)) - post resolve_issue_path(:id => issue) + post resolve_issue_path(issue) assert_redirected_to :controller => :errors, :action => :not_found - assert_not issue.reload.resolved? + assert_not_predicate issue.reload, :resolved? # Resolve issue as moderator session_for(create(:moderator_user)) - post resolve_issue_path(:id => issue) + post resolve_issue_path(issue) assert_response :redirect assert_predicate issue.reload, :resolved? end @@ -101,23 +101,23 @@ class IssuesControllerTest < ActionDispatch::IntegrationTest issue = create(:issue, :reportable => target_user, :reported_user => target_user, :assigned_role => "administrator") # Resolve issue without login - post resolve_issue_path(:id => issue) + post resolve_issue_path(issue) assert_response :forbidden # Resolve issue as normal user session_for(create(:user)) - post resolve_issue_path(:id => issue) + post resolve_issue_path(issue) assert_redirected_to :controller => :errors, :action => :forbidden # Resolve issue as moderator session_for(create(:moderator_user)) - post resolve_issue_path(:id => issue) + post resolve_issue_path(issue) assert_redirected_to :controller => :errors, :action => :not_found - assert_not issue.reload.resolved? + assert_not_predicate issue.reload, :resolved? # Resolve issue as administrator session_for(create(:administrator_user)) - post resolve_issue_path(:id => issue) + post resolve_issue_path(issue) assert_response :redirect assert_predicate issue.reload, :resolved? end @@ -127,23 +127,23 @@ class IssuesControllerTest < ActionDispatch::IntegrationTest issue = create(:issue, :reportable => target_user, :reported_user => target_user, :assigned_role => "moderator") # Ignore issue without login - post ignore_issue_path(:id => issue) + post ignore_issue_path(issue) assert_response :forbidden # Ignore issue as normal user session_for(create(:user)) - post ignore_issue_path(:id => issue) + post ignore_issue_path(issue) assert_redirected_to :controller => :errors, :action => :forbidden # Ignore issue as administrator session_for(create(:administrator_user)) - post ignore_issue_path(:id => issue) + post ignore_issue_path(issue) assert_redirected_to :controller => :errors, :action => :not_found - assert_not issue.reload.ignored? + assert_not_predicate issue.reload, :ignored? # Ignore issue as moderator session_for(create(:moderator_user)) - post ignore_issue_path(:id => issue) + post ignore_issue_path(issue) assert_response :redirect assert_predicate issue.reload, :ignored? end @@ -153,23 +153,23 @@ class IssuesControllerTest < ActionDispatch::IntegrationTest issue = create(:issue, :reportable => target_user, :reported_user => target_user, :assigned_role => "administrator") # Ignore issue without login - post ignore_issue_path(:id => issue) + post ignore_issue_path(issue) assert_response :forbidden # Ignore issue as normal user session_for(create(:user)) - post ignore_issue_path(:id => issue) + post ignore_issue_path(issue) assert_redirected_to :controller => :errors, :action => :forbidden # Ignore issue as moderator session_for(create(:moderator_user)) - post ignore_issue_path(:id => issue) + post ignore_issue_path(issue) assert_redirected_to :controller => :errors, :action => :not_found - assert_not issue.reload.ignored? + assert_not_predicate issue.reload, :ignored? # Ignore issue as administrator session_for(create(:administrator_user)) - post ignore_issue_path(:id => issue) + post ignore_issue_path(issue) assert_response :redirect assert_predicate issue.reload, :ignored? end @@ -181,23 +181,23 @@ class IssuesControllerTest < ActionDispatch::IntegrationTest issue.resolve! # Reopen issue without login - post reopen_issue_path(:id => issue) + post reopen_issue_path(issue) assert_response :forbidden # Reopen issue as normal user session_for(create(:user)) - post reopen_issue_path(:id => issue) + post reopen_issue_path(issue) assert_redirected_to :controller => :errors, :action => :forbidden # Reopen issue as administrator session_for(create(:administrator_user)) - post reopen_issue_path(:id => issue) + post reopen_issue_path(issue) assert_redirected_to :controller => :errors, :action => :not_found - assert_not issue.reload.open? + assert_not_predicate issue.reload, :open? # Reopen issue as moderator session_for(create(:moderator_user)) - post reopen_issue_path(:id => issue) + post reopen_issue_path(issue) assert_response :redirect assert_predicate issue.reload, :open? end @@ -209,23 +209,23 @@ class IssuesControllerTest < ActionDispatch::IntegrationTest issue.resolve! # Reopen issue without login - post reopen_issue_path(:id => issue) + post reopen_issue_path(issue) assert_response :forbidden # Reopen issue as normal user session_for(create(:user)) - post reopen_issue_path(:id => issue) + post reopen_issue_path(issue) assert_redirected_to :controller => :errors, :action => :forbidden # Reopen issue as moderator session_for(create(:moderator_user)) - post reopen_issue_path(:id => issue) + post reopen_issue_path(issue) assert_redirected_to :controller => :errors, :action => :not_found - assert_not issue.reload.open? + assert_not_predicate issue.reload, :open? # Reopen issue as administrator session_for(create(:administrator_user)) - post reopen_issue_path(:id => issue) + post reopen_issue_path(issue) assert_response :redirect assert_predicate issue.reload, :open? end diff --git a/test/controllers/user_blocks_controller_test.rb b/test/controllers/user_blocks_controller_test.rb index dd0b1287b..2e9d79ef7 100644 --- a/test/controllers/user_blocks_controller_test.rb +++ b/test/controllers/user_blocks_controller_test.rb @@ -212,22 +212,9 @@ class UserBlocksControllerTest < ActionDispatch::IntegrationTest check_block_buttons block, :edit => 1 session_for(revoker_user) - check_block_buttons block - end - - private - - def check_block_buttons(block, edit: 0, revoke: 0) - [user_blocks_path, user_block_path(block)].each do |path| - get path - assert_response :success - assert_select "a[href='#{edit_user_block_path block}']", :count => edit - assert_select "a[href='#{revoke_user_block_path block}']", :count => revoke - end + check_block_buttons block, :edit => 1 end - public - ## # test the new action def test_new @@ -483,23 +470,32 @@ class UserBlocksControllerTest < ActionDispatch::IntegrationTest assert_equal "Original Reason", block.reason session_for(creator_user) + check_block_updates(block) + end + + ## + # test the update action on revoked blocks + def test_update_revoked + creator_user = create(:moderator_user) + revoker_user = create(:moderator_user) + other_moderator_user = create(:moderator_user) + block = create(:user_block, :revoked, :creator => creator_user, :revoker => revoker_user, :reason => "Original Reason") + + session_for(other_moderator_user) put user_block_path(block, :user_block_period => "0", :user_block => { :needs_view => false, :reason => "Updated Reason" }) - assert_redirected_to user_block_path(block) - assert_equal "Block updated.", flash[:notice] + assert_redirected_to edit_user_block_path(block) + assert_equal "Only the moderators who created or revoked this block can edit it.", flash[:error] block.reload - assert_not block.active? - assert_equal "Updated Reason", block.reason + assert_not_predicate block, :active? + assert_equal "Original Reason", block.reason - put user_block_path(block, - :user_block_period => "0", - :user_block => { :needs_view => true, :reason => "Updated Reason 2" }) - assert_redirected_to user_block_path(block) - assert_equal "Block updated.", flash[:notice] - block.reload - assert_predicate block, :active? - assert_equal "Updated Reason 2", block.reason + session_for(creator_user) + check_block_updates(block) + + session_for(revoker_user) + check_block_updates(block) end ## @@ -794,6 +790,35 @@ class UserBlocksControllerTest < ActionDispatch::IntegrationTest private + def check_block_buttons(block, edit: 0, revoke: 0) + [user_blocks_path, user_block_path(block)].each do |path| + get path + assert_response :success + assert_select "a[href='#{edit_user_block_path block}']", :count => edit + assert_select "a[href='#{revoke_user_block_path block}']", :count => revoke + end + end + + def check_block_updates(block) + put user_block_path(block, + :user_block_period => "0", + :user_block => { :needs_view => false, :reason => "Updated Reason" }) + assert_redirected_to user_block_path(block) + assert_equal "Block updated.", flash[:notice] + block.reload + assert_not_predicate block, :active? + assert_equal "Updated Reason", block.reason + + put user_block_path(block, + :user_block_period => "0", + :user_block => { :needs_view => true, :reason => "Updated Reason 2" }) + assert_redirected_to user_block_path(block) + assert_equal "Block updated.", flash[:notice] + block.reload + assert_predicate block, :active? + assert_equal "Updated Reason 2", block.reason + end + def check_user_blocks_table(user_blocks) assert_dom "table#block_list tbody tr" do |rows| assert_equal user_blocks.count, rows.count, "unexpected number of rows in user blocks table" diff --git a/test/factories/oauth_access_token.rb b/test/factories/oauth_access_token.rb index 3f862fbca..6a8b62f6c 100644 --- a/test/factories/oauth_access_token.rb +++ b/test/factories/oauth_access_token.rb @@ -1,5 +1,7 @@ FactoryBot.define do factory :oauth_access_token, :class => "Doorkeeper::AccessToken" do application :factory => :oauth_application + + resource_owner_id { create(:user).id } end end diff --git a/test/lib/rich_text_test.rb b/test/lib/rich_text_test.rb index 8dc9e49b1..e0b315276 100644 --- a/test/lib/rich_text_test.rb +++ b/test/lib/rich_text_test.rb @@ -253,26 +253,79 @@ class RichTextTest < ActiveSupport::TestCase def test_text_no_image r = RichText.new("text", "foo https://example.com/ bar") assert_nil r.image + assert_nil r.image_alt end def test_html_no_image r = RichText.new("html", "foo bar baz") assert_nil r.image + assert_nil r.image_alt end def test_markdown_no_image r = RichText.new("markdown", "foo [bar](https://example.com/) baz") assert_nil r.image + assert_nil r.image_alt end def test_markdown_image r = RichText.new("markdown", "foo ![bar](https://example.com/image.jpg) baz") assert_equal "https://example.com/image.jpg", r.image + assert_equal "bar", r.image_alt end def test_markdown_first_image r = RichText.new("markdown", "foo ![bar1](https://example.com/image1.jpg) baz\nfoo ![bar2](https://example.com/image2.jpg) baz") assert_equal "https://example.com/image1.jpg", r.image + assert_equal "bar1", r.image_alt + end + + def test_markdown_image_with_empty_src + r = RichText.new("markdown", "![invalid]()") + assert_nil r.image + assert_nil r.image_alt + end + + def test_markdown_skip_image_with_empty_src + r = RichText.new("markdown", "![invalid]() ![valid](https://example.com/valid.gif)") + assert_equal "https://example.com/valid.gif", r.image + assert_equal "valid", r.image_alt + end + + def test_markdown_html_image + r = RichText.new("markdown", "alt text here") + assert_equal "https://example.com/img_element.png", r.image + assert_equal "alt text here", r.image_alt + end + + def test_markdown_html_image_without_alt + r = RichText.new("markdown", "") + assert_equal "https://example.com/img_element.png", r.image + assert_nil r.image_alt + end + + def test_markdown_html_image_with_empty_src + r = RichText.new("markdown", "forgot src") + assert_nil r.image + assert_nil r.image_alt + end + + def test_markdown_skip_html_image_with_empty_src + r = RichText.new("markdown", "forgot src have src") + assert_equal "https://example.com/next_img_element.png", r.image + assert_equal "have src", r.image_alt + end + + def test_markdown_html_image_without_src + r = RichText.new("markdown", "totally forgot src") + assert_nil r.image + assert_nil r.image_alt + end + + def test_markdown_skip_html_image_without_src + r = RichText.new("markdown", "totally forgot src have src") + assert_equal "https://example.com/next_img_element.png", r.image + assert_equal "have src", r.image_alt end private diff --git a/test/mailers/user_mailer_test.rb b/test/mailers/user_mailer_test.rb index 25123b392..2a547e752 100644 --- a/test/mailers/user_mailer_test.rb +++ b/test/mailers/user_mailer_test.rb @@ -10,39 +10,43 @@ class UserMailerTest < ActionMailer::TestCase def test_gpx_description_tags trace = create(:trace) do |t| create(:tracetag, :trace => t, :tag => "one") - create(:tracetag, :trace => t, :tag => "two") - create(:tracetag, :trace => t, :tag => "three") + create(:tracetag, :trace => t, :tag => "two&three") + create(:tracetag, :trace => t, :tag => "fourone, two, three", email.html_part.body.to_s) + assert_match("one, two&three, four<five", email.html_part.body.to_s) + assert_match("one, two&three, four "traces", :action => "mine", :host => Settings.server_url, :protocol => Settings.server_protocol) - assert_select body, "a[href='#{url}']" + + assert_select Rails::Dom::Testing.html_document_fragment.parse(email.html_part.body), + "a[href='#{url}']" + assert_includes email.text_part.body, url end def test_gpx_success_trace_link trace = create(:trace) email = UserMailer.gpx_success(trace, 100) - body = Rails::Dom::Testing.html_document_fragment.parse(email.html_part.body) - url = Rails.application.routes.url_helpers.show_trace_url(trace.user, trace, :host => Settings.server_url, :protocol => Settings.server_protocol) - assert_select body, "a[href='#{url}']", :text => trace.name + + assert_select Rails::Dom::Testing.html_document_fragment.parse(email.html_part.body), + "a[href='#{url}']", :text => trace.name + assert_includes email.text_part.body, url end def test_gpx_failure_no_trace_link trace = create(:trace) email = UserMailer.gpx_failure(trace, "some error") - body = Rails::Dom::Testing.html_document_fragment.parse(email.html_part.body) - url = Rails.application.routes.url_helpers.show_trace_url(trace.user, trace, :host => Settings.server_url, :protocol => Settings.server_protocol) - assert_select body, "a[href='#{url}']", :count => 0 + + assert_select Rails::Dom::Testing.html_document_fragment.parse(email.html_part.body), + "a[href='#{url}']", :count => 0 + assert_not_includes email.text_part.body, url end def test_html_encoding diff --git a/test/models/user_test.rb b/test/models/user_test.rb index 92e7d419c..10fd3d97e 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -111,10 +111,10 @@ class UserTest < ActiveSupport::TestCase user = build(:user) user.display_name = "user_#{existing_user.id}" - assert_not user.valid?, "user_ name is valid for existing user id when it shouldn't be" + assert_not_predicate user, :valid?, "user_ name is valid for existing user id when it shouldn't be" user.display_name = "user_#{existing_user.id + 1}" - assert_not user.valid?, "user_ name is valid for new user id when it shouldn't be" + assert_not_predicate user, :valid?, "user_ name is valid for new user id when it shouldn't be" end def test_display_name_user_id_rename @@ -122,7 +122,7 @@ class UserTest < ActiveSupport::TestCase user = create(:user) user.display_name = "user_#{existing_user.id}" - assert_not user.valid?, "user_ name is valid for existing user id when it shouldn't be" + assert_not_predicate user, :valid?, "user_ name is valid for existing user id when it shouldn't be" user.display_name = "user_#{user.id}" assert_predicate user, :valid?, "user_ name is invalid for own id, when it should be" diff --git a/yarn.lock b/yarn.lock index df127bc8c..290ff527c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19,10 +19,10 @@ resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae" integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== -"@eslint/config-array@^0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.17.0.tgz#ff305e1ee618a00e6e5d0485454c8d92d94a860d" - integrity sha512-A68TBu6/1mHHuc5YJL0U0VVeGNiklLAL6rRmhTCP2B5XjWLMnrX+HkO+IAXyHvks5cyyY1jjK5ITPQ1HGS2EVA== +"@eslint/config-array@^0.17.1": + version "0.17.1" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.17.1.tgz#d9b8b8b6b946f47388f32bedfd3adf29ca8f8910" + integrity sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA== dependencies: "@eslint/object-schema" "^2.1.4" debug "^4.3.1" @@ -43,10 +43,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.7.0": - version "9.7.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.7.0.tgz#b712d802582f02b11cfdf83a85040a296afec3f0" - integrity sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng== +"@eslint/js@9.8.0": + version "9.8.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.8.0.tgz#ae9bc14bb839713c5056f5018bcefa955556d3a4" + integrity sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA== "@eslint/object-schema@^2.1.4": version "2.1.4" @@ -246,15 +246,15 @@ eslint-visitor-keys@^4.0.0: integrity sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw== eslint@^9.0.0: - version "9.7.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.7.0.tgz#bedb48e1cdc2362a0caaa106a4c6ed943e8b09e4" - integrity sha512-FzJ9D/0nGiCGBf8UXO/IGLTgLVzIxze1zpfA8Ton2mjLovXdAPlYDv+MQDcqj3TmrhAGYfOpz9RfR+ent0AgAw== + version "9.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.8.0.tgz#a4f4a090c8ea2d10864d89a6603e02ce9f649f0f" + integrity sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.11.0" - "@eslint/config-array" "^0.17.0" + "@eslint/config-array" "^0.17.1" "@eslint/eslintrc" "^3.1.0" - "@eslint/js" "9.7.0" + "@eslint/js" "9.8.0" "@humanwhocodes/module-importer" "^1.0.1" "@humanwhocodes/retry" "^0.3.0" "@nodelib/fs.walk" "^1.2.8" @@ -624,9 +624,9 @@ punycode@^2.1.0: integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== qs@^6.9.4: - version "6.12.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.3.tgz#e43ce03c8521b9c7fd7f1f13e514e5ca37727754" - integrity sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ== + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== dependencies: side-channel "^1.0.6"