]> git.openstreetmap.org Git - rails.git/commitdiff
Merge 17067 from trunk.
authorTom Hughes <tom@compton.nu>
Tue, 13 Oct 2009 20:16:03 +0000 (20:16 +0000)
committerTom Hughes <tom@compton.nu>
Tue, 13 Oct 2009 20:16:03 +0000 (20:16 +0000)
318 files changed:
app/controllers/amf_controller.rb
app/controllers/application_controller.rb
app/controllers/changeset_controller.rb
app/controllers/diary_entry_controller.rb
app/controllers/geocoder_controller.rb
app/controllers/node_controller.rb
app/controllers/oauth_clients_controller.rb [new file with mode: 0644]
app/controllers/oauth_controller.rb [new file with mode: 0644]
app/controllers/relation_controller.rb
app/controllers/trace_controller.rb
app/controllers/user_blocks_controller.rb [new file with mode: 0644]
app/controllers/user_controller.rb
app/controllers/user_preference_controller.rb
app/controllers/user_roles_controller.rb [new file with mode: 0644]
app/controllers/way_controller.rb
app/helpers/application_helper.rb
app/helpers/browse_helper.rb
app/helpers/geocoder_helper.rb
app/helpers/oauth_clients_helper.rb [new file with mode: 0644]
app/helpers/oauth_helper.rb [new file with mode: 0644]
app/helpers/user_blocks_helper.rb [new file with mode: 0644]
app/models/access_token.rb [new file with mode: 0644]
app/models/client_application.rb [new file with mode: 0644]
app/models/language.rb
app/models/oauth_nonce.rb [new file with mode: 0644]
app/models/oauth_token.rb [new file with mode: 0644]
app/models/request_token.rb [new file with mode: 0644]
app/models/trace.rb
app/models/user.rb
app/models/user_block.rb [new file with mode: 0644]
app/models/user_role.rb [new file with mode: 0644]
app/views/browse/_common_details.html.erb
app/views/browse/_tag.html.erb
app/views/browse/not_found.html.erb
app/views/browse/start.rjs
app/views/changeset/_changeset.html.erb
app/views/changeset/_changeset_paging_nav.html.erb
app/views/changeset/list.atom.builder
app/views/layouts/site.html.erb
app/views/message/new.html.erb
app/views/message/outbox.html.erb
app/views/oauth/authorize_failure.html.erb [new file with mode: 0644]
app/views/oauth/authorize_success.html.erb [new file with mode: 0644]
app/views/oauth/oauthorize.html.erb [new file with mode: 0644]
app/views/oauth_clients/_form.html.erb [new file with mode: 0644]
app/views/oauth_clients/edit.html.erb [new file with mode: 0644]
app/views/oauth_clients/index.html.erb [new file with mode: 0644]
app/views/oauth_clients/new.html.erb [new file with mode: 0644]
app/views/oauth_clients/not_found.erb [new file with mode: 0644]
app/views/oauth_clients/show.html.erb [new file with mode: 0644]
app/views/site/edit.html.erb
app/views/user/_friend_map.html.erb
app/views/user/account.html.erb
app/views/user/api_details.builder [new file with mode: 0644]
app/views/user/login.html.erb
app/views/user/new.html.erb
app/views/user/view.html.erb
app/views/user_blocks/_block.html.erb [new file with mode: 0644]
app/views/user_blocks/_blocks.html.erb [new file with mode: 0644]
app/views/user_blocks/blocks_by.html.erb [new file with mode: 0644]
app/views/user_blocks/blocks_on.html.erb [new file with mode: 0644]
app/views/user_blocks/edit.html.erb [new file with mode: 0644]
app/views/user_blocks/index.html.erb [new file with mode: 0644]
app/views/user_blocks/new.html.erb [new file with mode: 0644]
app/views/user_blocks/not_found.html.erb [new file with mode: 0644]
app/views/user_blocks/revoke.html.erb [new file with mode: 0644]
app/views/user_blocks/show.html.erb [new file with mode: 0644]
app/views/user_roles/grant.html.erb [new file with mode: 0644]
app/views/user_roles/revoke.html.erb [new file with mode: 0644]
config/application.yml
config/environment.rb
config/languages.yml
config/locales/af.yml [new file with mode: 0644]
config/locales/ar.yml [new file with mode: 0644]
config/locales/be-TARASK.yml [new file with mode: 0644]
config/locales/be.yml
config/locales/bg.yml [new file with mode: 0644]
config/locales/br.yml [new file with mode: 0644]
config/locales/bs.yml [new file with mode: 0644]
config/locales/ca.yml
config/locales/cs.yml [new file with mode: 0644]
config/locales/da.yml [new file with mode: 0644]
config/locales/de.yml
config/locales/dsb.yml [new file with mode: 0644]
config/locales/el.yml
config/locales/en.yml
config/locales/eo.yml [new file with mode: 0644]
config/locales/es.yml
config/locales/eu.yml [new file with mode: 0644]
config/locales/fi.yml [new file with mode: 0644]
config/locales/fr.yml
config/locales/fur.yml [new file with mode: 0644]
config/locales/gcf.yml [new file with mode: 0644]
config/locales/gl.yml [new file with mode: 0644]
config/locales/gsw.yml [new file with mode: 0644]
config/locales/he.yml
config/locales/hi.yml
config/locales/hr.yml [new file with mode: 0644]
config/locales/hsb.yml [new file with mode: 0644]
config/locales/hu.yml
config/locales/ia.yml [new file with mode: 0644]
config/locales/is.yml
config/locales/it.yml
config/locales/ja.yml
config/locales/ka.yml [new file with mode: 0644]
config/locales/km.yml [new file with mode: 0644]
config/locales/ko.yml
config/locales/ksh.yml [new file with mode: 0644]
config/locales/lt.yml [new file with mode: 0644]
config/locales/lv.yml [new file with mode: 0644]
config/locales/nds.yml [new file with mode: 0644]
config/locales/nl.yml
config/locales/nn.yml [new file with mode: 0644]
config/locales/no.yml [new file with mode: 0644]
config/locales/pl.yml
config/locales/ps.yml [new file with mode: 0644]
config/locales/pt-BR.yml
config/locales/pt.yml [new file with mode: 0644]
config/locales/ro.yml
config/locales/ru.yml
config/locales/sk.yml [new file with mode: 0644]
config/locales/sl.yml
config/locales/sr-EC.yml [new file with mode: 0644]
config/locales/sv.yml [new file with mode: 0644]
config/locales/te.yml [new file with mode: 0644]
config/locales/tr.yml [new file with mode: 0644]
config/locales/vi.yml
config/locales/yi.yml [new file with mode: 0644]
config/locales/yo.yml
config/locales/zh-CN.yml
config/locales/zh-TW.yml
config/potlatch/autocomplete.txt
config/potlatch/colours.txt
config/potlatch/locales/af.yml [new file with mode: 0644]
config/potlatch/locales/br.yml [new file with mode: 0644]
config/potlatch/locales/cs.yml [new file with mode: 0644]
config/potlatch/locales/da.yml [new file with mode: 0644]
config/potlatch/locales/de.yml [new file with mode: 0644]
config/potlatch/locales/en.yml [new file with mode: 0644]
config/potlatch/locales/eo.yml [new file with mode: 0644]
config/potlatch/locales/es.yml [new file with mode: 0644]
config/potlatch/locales/fi.yml [new file with mode: 0644]
config/potlatch/locales/fr.yml [new file with mode: 0644]
config/potlatch/locales/gl.yml [new file with mode: 0644]
config/potlatch/locales/hsb.yml [new file with mode: 0644]
config/potlatch/locales/hu.yml [new file with mode: 0644]
config/potlatch/locales/id.yml [new file with mode: 0644]
config/potlatch/locales/is.yml [new file with mode: 0644]
config/potlatch/locales/it.yml [new file with mode: 0644]
config/potlatch/locales/ja.yml [new file with mode: 0644]
config/potlatch/locales/ko.yml [new file with mode: 0644]
config/potlatch/locales/lolcat.yml [new file with mode: 0644]
config/potlatch/locales/nl.yml [new file with mode: 0644]
config/potlatch/locales/no.yml [new file with mode: 0644]
config/potlatch/locales/pt-BR.yml [new file with mode: 0644]
config/potlatch/locales/ro.yml [new file with mode: 0644]
config/potlatch/locales/ru.yml [new file with mode: 0644]
config/potlatch/locales/sr-EC.yml [new file with mode: 0644]
config/potlatch/locales/sv.yml [new file with mode: 0644]
config/potlatch/locales/tr.yml [new file with mode: 0644]
config/potlatch/locales/vi.yml [new file with mode: 0644]
config/potlatch/locales/zh-HANT.yml [new file with mode: 0644]
config/potlatch/localised/cz/localised.yaml [deleted file]
config/potlatch/localised/da/localised.yaml [deleted file]
config/potlatch/localised/de/localised.yaml [deleted file]
config/potlatch/localised/en/help.html [deleted file]
config/potlatch/localised/es/localised.yaml [deleted file]
config/potlatch/localised/fi/localised.yaml [deleted file]
config/potlatch/localised/fr/localised.yaml [deleted file]
config/potlatch/localised/hu/localised.yaml [deleted file]
config/potlatch/localised/it/localised.yaml [deleted file]
config/potlatch/localised/ja/localised.yaml [deleted file]
config/potlatch/localised/ko/localised.yaml [deleted file]
config/potlatch/localised/lolcat/localised.yaml [deleted file]
config/potlatch/localised/nl/localised.yaml [deleted file]
config/potlatch/localised/no/localised.yaml [deleted file]
config/potlatch/localised/pt-BR/localised.yaml [deleted file]
config/potlatch/localised/ro/localised.yaml [deleted file]
config/potlatch/localised/ru/localised.yaml [deleted file]
config/potlatch/localised/sv/localised.yaml [deleted file]
config/potlatch/localised/tr/localised.yaml [deleted file]
config/potlatch/localised/vi/localised.yaml [deleted file]
config/potlatch/localised/zh-HANS/localised.yaml [deleted file]
config/potlatch/localised/zh-HANT/localised.yaml [deleted file]
config/potlatch/presets.txt
config/potlatch/relation_colours.txt
config/routes.rb
db/functions/Makefile
db/functions/xid_to_int4.c [new file with mode: 0644]
db/migrate/034_create_languages.rb
db/migrate/040_create_oauth_tables.rb [new file with mode: 0644]
db/migrate/041_add_fine_o_auth_permissions.rb [new file with mode: 0644]
db/migrate/042_add_foreign_keys_to_oauth_tables.rb [new file with mode: 0644]
db/migrate/043_add_referer_to_user_token.rb [new file with mode: 0644]
db/migrate/044_create_user_roles.rb [new file with mode: 0644]
db/migrate/045_create_user_blocks.rb [new file with mode: 0644]
db/migrate/046_alter_user_roles_and_blocks.rb [new file with mode: 0644]
public/403.html [new file with mode: 0644]
public/api/crossdomain.xml
public/htaccess.example [moved from public/.htaccess with 100% similarity]
public/images/cc_button.png
public/images/donate.png [deleted file]
public/images/roles/administrator.png [new file with mode: 0644]
public/images/roles/blank_administrator.png [new file with mode: 0644]
public/images/roles/blank_moderator.png [new file with mode: 0644]
public/images/roles/moderator.png [new file with mode: 0644]
public/javascripts/map.js
public/javascripts/site.js
public/oauth/crossdomain.xml [new file with mode: 0644]
public/openlayers/OpenLayers.js
public/potlatch/potlatch.swf
public/stylesheets/common.css [new file with mode: 0644]
public/stylesheets/site-sml.css [new file with mode: 0644]
public/stylesheets/site.css
script/locale/diff
script/locale/merge-from-translatewiki [new file with mode: 0644]
script/locale/reload-languages [new file with mode: 0755]
script/locale/update-languages [new file with mode: 0755]
test/fixtures/client_applications.yml [new file with mode: 0644]
test/fixtures/current_way_nodes.yml
test/fixtures/current_ways.yml
test/fixtures/languages.yml
test/fixtures/user_roles.yml [new file with mode: 0644]
test/fixtures/users.yml
test/fixtures/way_nodes.yml
test/fixtures/ways.yml
test/functional/changeset_controller_test.rb
test/functional/diary_entry_controller_test.rb
test/functional/way_controller_test.rb
test/integration/client_application_test.rb [new file with mode: 0644]
test/integration/short_link_test.rb
test/integration/user_blocks_test.rb [new file with mode: 0644]
test/integration/user_creation_test.rb
test/integration/user_roles_test.rb [new file with mode: 0644]
test/test_helper.rb
test/unit/language_test.rb
test/unit/oauth_nonce_test.rb [new file with mode: 0644]
test/unit/oauth_token_test.rb [new file with mode: 0644]
test/unit/way_node_test.rb
test/unit/way_test.rb
vendor/plugins/file_column/lib/file_column_helper.rb
vendor/plugins/http_accept_language/lib/http_accept_language.rb
vendor/plugins/oauth-plugin/.gitignore [new file with mode: 0644]
vendor/plugins/oauth-plugin/CHANGELOG [new file with mode: 0644]
vendor/plugins/oauth-plugin/MIT-LICENSE [new file with mode: 0644]
vendor/plugins/oauth-plugin/README.rdoc [new file with mode: 0644]
vendor/plugins/oauth-plugin/Rakefile [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/USAGE [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/oauth_provider_generator.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/_form.html.erb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/access_token.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/authorize.html.erb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/authorize_failure.html.erb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/authorize_success.html.erb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/client_application.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/client_application_spec.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/client_application_test.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/client_applications.yml [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/clients_controller.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/clients_controller_spec.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/clients_controller_test.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/clients_helper.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/controller.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/controller_spec.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/controller_spec_helper.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/controller_test.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/controller_test_helper.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/edit.html.erb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/helper.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/index.html.erb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/migration.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/new.html.erb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/oauth_nonce.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/oauth_nonce_spec.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/oauth_nonce_test.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/oauth_nonces.yml [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/oauth_token.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/oauth_token_spec.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/oauth_token_test.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/oauth_tokens.yml [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/request_token.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/generators/oauth_provider/templates/show.html.erb [new file with mode: 0644]
vendor/plugins/oauth-plugin/init.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/install.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/lib/oauth/rails/controller_methods.rb [new file with mode: 0644]
vendor/plugins/oauth-plugin/tasks/oauth_tasks.rake [new file with mode: 0644]
vendor/plugins/oauth-plugin/uninstall.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/bg.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/bn-IN.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/ca-ES.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/de-AT.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/de.yml
vendor/plugins/rails-i18n/locale/es-AR.rb [deleted file]
vendor/plugins/rails-i18n/locale/es-AR.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/es-MX.yml
vendor/plugins/rails-i18n/locale/es.yml
vendor/plugins/rails-i18n/locale/et.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/fi.yml
vendor/plugins/rails-i18n/locale/fr-CH.yml
vendor/plugins/rails-i18n/locale/fr.yml
vendor/plugins/rails-i18n/locale/is.yml
vendor/plugins/rails-i18n/locale/it.yml
vendor/plugins/rails-i18n/locale/ja.yml
vendor/plugins/rails-i18n/locale/ko.yml
vendor/plugins/rails-i18n/locale/lv.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/nl.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/pl.yml
vendor/plugins/rails-i18n/locale/pt-BR.yml
vendor/plugins/rails-i18n/locale/pt-PT.yml
vendor/plugins/rails-i18n/locale/rm.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/ru.yml
vendor/plugins/rails-i18n/locale/sk.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/sw.yml
vendor/plugins/rails-i18n/locale/th.rb
vendor/plugins/rails-i18n/locale/uk.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/vi.yml
vendor/plugins/rails-i18n/locale/zh-CN.yml
vendor/plugins/rails-i18n/locale/zh-TW.yml

index 1e87e47c23d8ce7e5551276da6b4dae2d466ba78..b9c344771ba88fe36e34152f2e6b16f85004af17 100644 (file)
@@ -178,6 +178,7 @@ class AmfController < ApplicationController
     amf_handle_error("'startchangeset'",nil,nil) do
       user = getuser(usertoken)
       if !user then return -1,"You are not logged in, so Potlatch can't write any changes to the database." end
+      unless user.active_blocks.empty? then return -1,t('application.setup_user_auth.blocked') end
 
       # close previous changeset and add comment
       if closeid
@@ -221,23 +222,43 @@ class AmfController < ApplicationController
     end
 
     lang = request.compatible_language_from(getlocales)
+    (real_lang, localised) = getlocalized(lang)
 
-    begin
-      # if not, try the browser language
-      localised = YAML::load(File.open("#{RAILS_ROOT}/config/potlatch/localised/#{lang}/localised.yaml"))
-    rescue
-      # fall back to hardcoded English text
-      localised = ""
-    end
+    # Tell Potlatch what language it's using
+    localised["__potlatch_locale"] = real_lang
+
+    # Get help from i18n but delete it so we won't pass it around
+    # twice for nothing
+    help = localised["help_html"]
+    localised.delete("help_html")
 
-    begin
-      help = File.read("#{RAILS_ROOT}/config/potlatch/localised/#{lang}/help.html")
-    rescue
-      help = File.read("#{RAILS_ROOT}/config/potlatch/localised/en/help.html")
-    end
     return POTLATCH_PRESETS+[localised,help]
   end
 
+  def getlocalized(lang)
+    # What we end up actually using. Reported in Potlatch's created_by=* string
+    loaded_lang = 'en'
+
+    # Load English defaults
+    en = YAML::load(File.open("#{RAILS_ROOT}/config/potlatch/locales/en.yml"))["en"]
+
+    if lang == 'en'
+      return [real_lang, en]
+    else
+      # Use English as a fallback
+      begin
+        other = YAML::load(File.open("#{RAILS_ROOT}/config/potlatch/locales/#{lang}.yml"))[lang]
+        loaded_lang = lang
+      rescue
+        other = en
+      end
+
+      # We have to return a flat list and some of the keys won't be
+      # translated (probably)
+      return [loaded_lang, en.merge(other)]
+    end
+  end
+
   ##
   # Find all the ways, POI nodes (i.e. not part of ways), and relations
   # in a given bounding box. Nodes are returned in full; ways and relations 
@@ -460,7 +481,8 @@ class AmfController < ApplicationController
   def findgpx(searchterm, usertoken)
     amf_handle_error_with_timeout("'findgpx'" ,nil,nil) do
       user = getuser(usertoken)
-      if !uid then return -1,"You must be logged in to search for GPX traces.",[] end
+      if !user then return -1,"You must be logged in to search for GPX traces.",[] end
+      unless user.active_blocks.empty? then return -1,t('application.setup_user_auth.blocked'),[] end
 
       gpxs = []
       if searchterm.to_i>0 then
@@ -526,6 +548,7 @@ class AmfController < ApplicationController
     amf_handle_error("'putrelation' #{relid}" ,'relation',relid)  do
       user = getuser(usertoken)
       if !user then return -1,"You are not logged in, so the relation could not be saved." end
+      unless user.active_blocks.empty? then return -1,t('application.setup_user_auth.blocked') end
       if !tags_ok(tags) then return -1,"One of the tags is invalid. Please pester Adobe to fix Flash on Linux." end
       tags = strip_non_xml_chars tags
 
@@ -613,6 +636,7 @@ class AmfController < ApplicationController
        
       user = getuser(usertoken)
       if !user then return -1,"You are not logged in, so the way could not be saved." end
+      unless user.active_blocks.empty? then return -1,t('application.setup_user_auth.blocked') end
       if pointlist.length < 2 then return -2,"Server error - way is only #{points.length} points long." end
       if !tags_ok(attributes) then return -1,"One of the tags is invalid. Please pester Adobe to fix Flash on Linux." end
       attributes = strip_non_xml_chars attributes
@@ -717,6 +741,7 @@ class AmfController < ApplicationController
     amf_handle_error("'putpoi' #{id}", 'node',id) do
       user = getuser(usertoken)
       if !user then return -1,"You are not logged in, so the point could not be saved." end
+      unless user.active_blocks.empty? then return -1,t('application.setup_user_auth.blocked') end
       if !tags_ok(tags) then return -1,"One of the tags is invalid. Please pester Adobe to fix Flash on Linux." end
       tags = strip_non_xml_chars tags
 
@@ -799,6 +824,7 @@ class AmfController < ApplicationController
     amf_handle_error("'deleteway' #{way_id}" ,'way',id) do
       user = getuser(usertoken)
       unless user then return -1,"You are not logged in, so the way could not be deleted." end
+      unless user.active_blocks.empty? then return -1,t('application.setup_user_auth.blocked') end
       
       way_id = way_id.to_i
       nodeversions = {}
@@ -871,7 +897,7 @@ class AmfController < ApplicationController
   end
 
   def getlocales
-    Dir.glob("#{RAILS_ROOT}/config/potlatch/localised/*").collect { |f| File.basename(f) }
+    Dir.glob("#{RAILS_ROOT}/config/potlatch/locales/*").collect { |f| File.basename(f, ".yml") }
   end
   
   ##
index 3eefa4a9142d4d760b959799b33fb5fad0803b4a..e36c9842ba6c55eea2e652d453b60d16732bc86e 100644 (file)
@@ -22,19 +22,80 @@ class ApplicationController < ActionController::Base
     redirect_to :controller => 'user', :action => 'login', :referer => request.request_uri unless @user
   end
 
+  ##
+  # requires the user to be logged in by the token or HTTP methods, or have an 
+  # OAuth token with the right capability. this method is a bit of a pain to call 
+  # directly, since it's cumbersome to call filters with arguments in rails. to
+  # make it easier to read and write the code, there are some utility methods
+  # below.
+  def require_capability(cap)
+    # when the current token is nil, it means the user logged in with a different
+    # method, otherwise an OAuth token was used, which has to be checked.
+    unless current_token.nil?
+      unless current_token.read_attribute(cap)
+        render :text => "OAuth token doesn't have that capability.", :status => :forbidden
+        return false
+      end
+    end
+  end
+
+  ##
+  # require the user to have cookies enabled in their browser
+  def require_cookies
+    if request.cookies["_osm_session"].to_s == ""
+      if params[:cookie_test].nil?
+        redirect_to params.merge(:cookie_test => "true")
+        return false
+      else
+        @notice = t 'application.require_cookies.cookies_needed'
+      end
+    end
+  end
+
+  # Utility methods to make the controller filter methods easier to read and write.
+  def require_allow_read_prefs
+    require_capability(:allow_read_prefs)
+  end
+  def require_allow_write_prefs
+    require_capability(:allow_write_prefs)
+  end
+  def require_allow_write_diary
+    require_capability(:allow_write_diary)
+  end
+  def require_allow_write_api
+    require_capability(:allow_write_api)
+  end
+  def require_allow_read_gpx
+    require_capability(:allow_read_gpx)
+  end
+  def require_allow_write_gpx
+    require_capability(:allow_write_gpx)
+  end
+
   ##
   # sets up the @user object for use by other methods. this is mostly called
   # from the authorize method, but can be called elsewhere if authorisation
   # is optional.
   def setup_user_auth
-    username, passwd = get_auth_data # parse from headers
-    # authenticate per-scheme
-    if username.nil?
-      @user = nil # no authentication provided - perhaps first connect (client should retry after 401)
-    elsif username == 'token' 
-      @user = User.authenticate(:token => passwd) # preferred - random token for user from db, passed in basic auth
+    # try and setup using OAuth
+    if oauthenticate
+      @user = current_token.user
     else
-      @user = User.authenticate(:username => username, :password => passwd) # basic auth
+      username, passwd = get_auth_data # parse from headers
+      # authenticate per-scheme
+      if username.nil?
+        @user = nil # no authentication provided - perhaps first connect (client should retry after 401)
+      elsif username == 'token'
+        @user = User.authenticate(:token => passwd) # preferred - random token for user from db, passed in basic auth
+      else
+        @user = User.authenticate(:username => username, :password => passwd) # basic auth
+      end
+    end
+
+    # check if the user has been banned
+    unless @user.nil? or @user.active_blocks.empty?
+      # NOTE: need slightly more helpful message than this.
+      render :text => t('application.setup_user_auth.blocked'), :status => :forbidden
     end
   end
 
index e451f6d04904f80467620e16f612db6ac1cadc39..7573a1803f52e54a3da136212ddc2f03113d1ad0 100644 (file)
@@ -7,6 +7,7 @@ class ChangesetController < ApplicationController
   before_filter :authorize_web, :only => [:list, :list_user, :list_bbox]
   before_filter :set_locale, :only => [:list, :list_user, :list_bbox]
   before_filter :authorize, :only => [:create, :update, :delete, :upload, :include, :close]
+  before_filter :require_allow_write_api, :only => [:create, :update, :delete, :upload, :include, :close]
   before_filter :require_public_data, :only => [:create, :update, :delete, :upload, :include, :close]
   before_filter :check_api_writable, :only => [:create, :update, :delete, :upload, :include]
   before_filter :check_api_readable, :except => [:create, :update, :delete, :upload, :download, :query]
@@ -205,7 +206,7 @@ class ChangesetController < ApplicationController
     # create the conditions that the user asked for. some or all of
     # these may be nil.
     conditions = conditions_bbox(params['bbox'])
-    conditions = cond_merge conditions, conditions_user(params['user'])
+    conditions = cond_merge conditions, conditions_user(params['user'], params['display_name'])
     conditions = cond_merge conditions, conditions_time(params['time'])
     conditions = cond_merge conditions, conditions_open(params['open'])
     conditions = cond_merge conditions, conditions_closed(params['closed'])
@@ -351,12 +352,23 @@ private
 
   ##
   # restrict changesets to those by a particular user
-  def conditions_user(user)
-    unless user.nil?
-      # user input checking, we don't have any UIDs < 1
-      raise OSM::APIBadUserInput.new("invalid user ID") if user.to_i < 1
+  def conditions_user(user, name)
+    unless user.nil? and name.nil?
+      # shouldn't provide both name and UID
+      raise OSM::APIBadUserInput.new("provide either the user ID or display name, but not both") if user and name
+
+      # use either the name or the UID to find the user which we're selecting on.
+      u = if name.nil?
+            # user input checking, we don't have any UIDs < 1
+            raise OSM::APIBadUserInput.new("invalid user ID") if user.to_i < 1
+            u = User.find(user.to_i)
+          else
+            u = User.find_by_display_name(name)
+          end
+
+      # make sure we found a user
+      raise OSM::APINotFoundError.new if u.nil?
 
-      u = User.find(user.to_i)
       # should be able to get changesets of public users only, or 
       # our own changesets regardless of public-ness.
       unless u.data_public?
index 52e287b9a1d9fe65ad55038e6f6542a5c6276b39..690b4292b746e0a2aea89cfa7c12478f60b82c12 100644 (file)
@@ -103,7 +103,7 @@ class DiaryEntryController < ApplicationController
 
       if user
         @entries = DiaryEntry.find(:all, :conditions => ['user_id = ?', user.id], :order => 'created_at DESC', :limit => 20)
-        @title = I18n.t('diary_entry.feed.user.title', :user => user.display_name, :locale => I18n.locale)
+        @title = I18n.t('diary_entry.feed.user.title', :user => user.display_name)
         @description = I18n.t('diary_entry.feed.user.description', :user => user.display_name)
         @link = "http://#{SERVER_URL}/user/#{user.display_name}/diary"
       else
@@ -113,8 +113,8 @@ class DiaryEntryController < ApplicationController
       @entries = DiaryEntry.find(:all, :include => :user,
         :conditions => ["users.visible = ? AND diary_entries.language_code = ?", true, params[:language]],
         :order => 'created_at DESC', :limit => 20)
-      @title = I18n.t('diary_entry.feed.language.title', Language.find(params[:language]).english_name)
-      @description = I18n.t('diary_entry.feed.language.description', Language.find(params[:language]).english_name)
+      @title = I18n.t('diary_entry.feed.language.title', :language_name => Language.find(params[:language]).english_name)
+      @description = I18n.t('diary_entry.feed.language.description', :language_name => Language.find(params[:language]).english_name)
       @link = "http://#{SERVER_URL}/diary/#{params[:language]}"
     else
       @entries = DiaryEntry.find(:all, :include => :user,
index 8195b0d473c511bb7a9d6de108d2283bcff99a18..556cfb36ad4ae53bf04fbadd3097cbdc9bb31dbd 100644 (file)
@@ -77,7 +77,7 @@ class GeocoderController < ApplicationController
       data = response.split(/\s*,\s+/) # lat,long,town,state,zip
       @results.push({:lat => data[0], :lon => data[1],
                      :zoom => APP_CONFIG['postcode_zoom'],
-                     :prefix => "#{data[2]}, #{data[3]}, ",
+                     :prefix => "#{data[2]}, #{data[3]},",
                      :name => data[4]})
     end
 
index eb6d0182326506d83d3e4c362560d362abd7921c..33e0ed3ee876f358c77c3e93dada13bd753ae716 100644 (file)
@@ -4,6 +4,7 @@ class NodeController < ApplicationController
   require 'xml/libxml'
 
   before_filter :authorize, :only => [:create, :update, :delete]
+  before_filter :require_allow_write_api, :only => [:create, :update, :delete]
   before_filter :require_public_data, :only => [:create, :update, :delete]
   before_filter :check_api_writable, :only => [:create, :update, :delete]
   before_filter :check_api_readable, :except => [:create, :update, :delete]
diff --git a/app/controllers/oauth_clients_controller.rb b/app/controllers/oauth_clients_controller.rb
new file mode 100644 (file)
index 0000000..f903028
--- /dev/null
@@ -0,0 +1,54 @@
+class OauthClientsController < ApplicationController
+  layout 'site'
+
+  before_filter :authorize_web
+  before_filter :set_locale
+  before_filter :require_user
+
+  def index
+    @client_applications = @user.client_applications
+    @tokens = @user.oauth_tokens.find :all, :conditions => 'oauth_tokens.invalidated_at is null and oauth_tokens.authorized_at is not null'
+  end
+
+  def new
+    @client_application = ClientApplication.new
+  end
+
+  def create
+    @client_application = @user.client_applications.build(params[:client_application])
+    if @client_application.save
+      flash[:notice] = t'oauth_clients.create.flash'
+      redirect_to :action => "show", :id => @client_application.id
+    else
+      render :action => "new"
+    end
+  end
+
+  def show
+    @client_application = @user.client_applications.find(params[:id])
+  rescue ActiveRecord::RecordNotFound
+    @type = "client application"
+    render :action => "not_found", :status => :not_found
+  end
+
+  def edit
+    @client_application = @user.client_applications.find(params[:id])
+  end
+
+  def update
+    @client_application = @user.client_applications.find(params[:id])
+    if @client_application.update_attributes(params[:client_application])
+      flash[:notice] = t'oauth_clients.update.flash'
+      redirect_to :action => "show", :id => @client_application.id
+    else
+      render :action => "edit"
+    end
+  end
+
+  def destroy
+    @client_application = @user.client_applications.find(params[:id])
+    @client_application.destroy
+    flash[:notice] = t'oauth_clients.destroy.flash'
+    redirect_to :action => "index"
+  end
+end
diff --git a/app/controllers/oauth_controller.rb b/app/controllers/oauth_controller.rb
new file mode 100644 (file)
index 0000000..4b539b1
--- /dev/null
@@ -0,0 +1,79 @@
+class OauthController < ApplicationController
+  layout 'site'
+
+  before_filter :authorize_web, :only => [:oauthorize, :revoke]
+  before_filter :set_locale, :only => [:oauthorize, :revoke]
+  before_filter :require_user, :only => [:oauthorize]
+  before_filter :verify_oauth_consumer_signature, :only => [:request_token]
+  before_filter :verify_oauth_request_token, :only => [:access_token]
+  # Uncomment the following if you are using restful_open_id_authentication
+  # skip_before_filter :verify_authenticity_token
+
+  def request_token
+    @token = current_client_application.create_request_token
+
+    if @token
+      logger.info "request token params: #{params.inspect}"
+      # request tokens indicate what permissions the client *wants*, not
+      # necessarily the same as those which the user allows.
+      current_client_application.permissions.each do |pref|
+        @token.write_attribute(pref, true)
+      end
+      @token.save!
+
+      render :text => @token.to_query
+    else
+      render :nothing => true, :status => 401
+    end
+  end
+
+  def access_token
+    @token = current_token && current_token.exchange!
+    if @token
+      render :text => @token.to_query
+    else
+      render :nothing => true, :status => 401
+    end
+  end
+
+  def oauthorize
+    @token = RequestToken.find_by_token params[:oauth_token]
+    unless @token.nil? or @token.invalidated? 
+      if request.post?
+        any_auth = false
+        @token.client_application.permissions.each do |pref|
+          if params[pref]
+            @token.write_attribute(pref, true)
+            any_auth ||= true
+          else
+            @token.write_attribute(pref, false)
+          end
+        end
+
+        if any_auth
+          @token.authorize!(@user)
+          redirect_url = params[:oauth_callback] || @token.client_application.callback_url
+          if redirect_url
+            redirect_to "#{redirect_url}?oauth_token=#{@token.token}"
+          else
+            render :action => "authorize_success"
+          end
+        else
+          @token.invalidate!
+          render :action => "authorize_failure"
+        end
+      end
+    else
+      render :action => "authorize_failure"
+    end
+  end
+
+  def revoke
+    @token = @user.oauth_tokens.find_by_token params[:token]
+    if @token
+      @token.invalidate!
+      flash[:notice] = t('oauth.revoke.flash', :application => @token.client_application.name)
+    end
+    redirect_to :controller => 'oauth_clients', :action => 'index'
+  end
+end
index 4f8e2d0b52a344af8cda070bf6db60df938c51c8..390806f80a3268f8d53ce7f694aaa0c1de2ee046 100644 (file)
@@ -2,6 +2,7 @@ class RelationController < ApplicationController
   require 'xml/libxml'
 
   before_filter :authorize, :only => [:create, :update, :delete]
+  before_filter :require_allow_write_api, :only => [:create, :update, :delete]
   before_filter :require_public_data, :only => [:create, :update, :delete]
   before_filter :check_api_writable, :only => [:create, :update, :delete]
   before_filter :check_api_readable, :except => [:create, :update, :delete]
index 1dee0b9248ee539549e7e5ff898350db28c87b6a..c90558269a6b0b497c7a8a37275846924494753c 100644 (file)
@@ -9,7 +9,10 @@ class TraceController < ApplicationController
   before_filter :check_database_writable, :only => [:create, :edit, :delete]
   before_filter :check_api_readable, :only => [:api_details, :api_data]
   before_filter :check_api_writable, :only => [:api_create]
+  before_filter :require_allow_read_gpx, :only => [:api_details, :api_data]
+  before_filter :require_allow_write_gpx, :only => [:api_create]
+  around_filter :api_call_handle_error, :only => [:api_details, :api_data, :api_create]
+
   # Counts and selects pages of GPX traces for various criteria (by user, tags, public etc.).
   #  target_user - if set, specifies the user to fetch traces for.  if not set will fetch all traces
   def list(target_user = nil, action = "list")
@@ -43,15 +46,15 @@ class TraceController < ApplicationController
     # 4 - user's traces, not logged in as that user = all user's public traces
     if target_user.nil? # all traces
       if @user
-        conditions = ["(gpx_files.visibility in ('public', 'identifiable') OR gpx_files.user_id = ?)", @user.id] #1
+        conditions = ["(gpx_files.visibility <> 'private' OR gpx_files.user_id = ?)", @user.id] #1
       else
-        conditions  = ["gpx_files.visibility in ('public', 'identifiable')"] #2
+        conditions  = ["gpx_files.visibility <> 'private'"] #2
       end
     else
       if @user and @user == target_user
         conditions = ["gpx_files.user_id = ?", @user.id] #3 (check vs user id, so no join + can't pick up non-public traces by changing name)
       else
-        conditions = ["gpx_files.visibility in ('public', 'identifiable') AND gpx_files.user_id = ?", target_user.id] #4
+        conditions = ["gpx_files.public <> 'private' AND gpx_files.user_id = ?", target_user.id] #4
       end
     end
     
@@ -126,8 +129,11 @@ class TraceController < ApplicationController
     if params[:trace]
       logger.info(params[:trace][:gpx_file].class.name)
       if params[:trace][:gpx_file].respond_to?(:read)
-        do_create(params[:trace][:gpx_file], params[:trace][:tagstring],
-                  params[:trace][:description], params[:trace][:visibility])
+        begin
+          do_create(params[:trace][:gpx_file], params[:trace][:tagstring],
+                    params[:trace][:description], params[:trace][:visibility])
+        rescue
+        end
 
         if @trace.id
           logger.info("id is #{@trace.id}")
@@ -205,7 +211,7 @@ class TraceController < ApplicationController
   end
 
   def georss
-    conditions = ["gpx_files.visibility in ('public', 'identifiable')"]
+    conditions = ["gpx_files.visibility <> 'private'"]
 
     if params[:display_name]
       conditions[0] += " AND users.display_name = ?"
@@ -291,12 +297,16 @@ class TraceController < ApplicationController
     if request.post?
       tags = params[:tags] || ""
       description = params[:description] || ""
-      visibility = params[:visibility] || false
+      visibility = params[:visibility]
 
-      if params[:public] && !visibility
-        visibility = "public"
+      if visibility.nil?
+        if params[:public] && params[:public].to_i.nonzero?
+          visibility = "public"
+        else
+          visibility = "private"
+        end
       end
-      
+
       if params[:file].respond_to?(:read)
         do_create(params[:file], tags, description, visibility)
 
@@ -339,20 +349,35 @@ private
       :timestamp => Time.now.getutc
     })
 
-    # Save the trace object
-    if @trace.save
-      # Rename the temporary file to the final name
-      FileUtils.mv(filename, @trace.trace_name)
+    Trace.transaction do
+      begin
+        # Save the trace object
+        @trace.save!
 
-      # Clear the inserted flag to make the import daemon load the trace
-      @trace.inserted = false
-      @trace.save!
-    else
-      # Remove the file as we have failed to update the database
-      FileUtils.rm_f(filename)
+        # Rename the temporary file to the final name
+        FileUtils.mv(filename, @trace.trace_name)
+      rescue Exception => ex
+        # Remove the file as we have failed to update the database
+        FileUtils.rm_f(filename)
+
+        # Pass the exception on
+        raise
+      end
+
+      begin
+        # Clear the inserted flag to make the import daemon load the trace
+        @trace.inserted = false
+        @trace.save!
+      rescue Exception => ex
+        # Remove the file as we have failed to update the database
+        FileUtils.rm_f(@trace.trace_name)
+
+        # Pass the exception on
+        raise
+      end
     end
-    
-    # Finally save the user's preferred previacy level
+
+    # Finally save the user's preferred privacy level
     if pref = @user.preferences.find(:first, :conditions => {:k => "gps.trace.visibility"})
       pref.v = visibility
       pref.save
diff --git a/app/controllers/user_blocks_controller.rb b/app/controllers/user_blocks_controller.rb
new file mode 100644 (file)
index 0000000..fd9f03c
--- /dev/null
@@ -0,0 +1,156 @@
+class UserBlocksController < ApplicationController
+  layout 'site'
+
+  before_filter :authorize_web
+  before_filter :set_locale
+  before_filter :require_user, :only => [:new, :create, :edit, :update, :revoke]
+  before_filter :require_moderator, :only => [:create, :update, :revoke]
+  before_filter :lookup_this_user, :only => [:new, :create, :blocks_on, :blocks_by]
+  before_filter :lookup_user_block, :only => [:show, :edit, :update, :revoke]
+  before_filter :require_valid_params, :only => [:create, :update]
+  before_filter :check_database_readable
+  before_filter :check_database_writable, :only => [:create, :update, :revoke]
+
+  def index
+    @user_blocks_pages, @user_blocks = paginate(:user_blocks,
+                                                :include => [:user, :creator, :revoker],
+                                                :order => "user_blocks.ends_at DESC",
+                                                :per_page => 20)
+  end
+
+  def show
+    if @user and @user.id == @user_block.user_id
+      @user_block.needs_view = false
+      @user_block.save!
+    end
+  end
+
+  def new
+    @user_block = UserBlock.new
+  end
+
+  def edit
+    params[:user_block_period] = ((@user_block.ends_at - Time.now.getutc) / 1.hour).ceil.to_s
+  end
+
+  def create
+    unless @valid_params 
+      redirect_to :action => "new"
+      return
+    end
+
+    @user_block = UserBlock.new(:user_id => @this_user.id,
+                                :creator_id => @user.id,
+                                :reason => params[:user_block][:reason],
+                                :ends_at => Time.now.getutc() + @block_period.hours,
+                                :needs_view => params[:user_block][:needs_view])
+    
+    if @user_block.save
+      flash[:notice] = t('user_block.create.flash', :name => @this_user.display_name)
+      redirect_to @user_block
+    else
+      render :action => "new"
+    end
+  end
+
+  def update  
+    unless @valid_params 
+      redirect_to :action => "edit"
+      return
+    end
+
+    if @user_block.creator_id != @user.id
+      flash[:notice] = t('user_block.update.only_creator_can_edit')
+      redirect_to :action => "edit"
+      return
+    end
+      
+    if @user_block.update_attributes({ :ends_at => Time.now.getutc() + @block_period.hours,
+                                       :reason => params[:user_block][:reason],
+                                       :needs_view => params[:user_block][:needs_view] })
+      flash[:notice] = t('user_block.update.success')
+      redirect_to(@user_block)
+    else
+      render :action => "edit"
+    end
+  end
+
+  ##
+  # revokes the block, setting the end_time to now
+  def revoke
+    if params[:confirm]
+      if @user_block.revoke! @user
+        flash[:notice] = t'user_block.revoke.flash'
+        redirect_to(@user_block)
+      end
+    end
+  end
+
+  ##
+  # shows a list of all the blocks on the given user
+  def blocks_on
+    @user_blocks_pages, @user_blocks = paginate(:user_blocks,
+                                                :include => [:user, :creator, :revoker],
+                                                :conditions => {:user_id => @this_user.id},
+                                                :order => "user_blocks.ends_at DESC",
+                                                :per_page => 20)
+  end
+
+  ##
+  # shows a list of all the blocks by the given user.
+  def blocks_by
+    @user_blocks_pages, @user_blocks = paginate(:user_blocks,
+                                                :include => [:user, :creator, :revoker],
+                                                :conditions => {:creator_id => @this_user.id},
+                                                :order => "user_blocks.ends_at DESC",
+                                                :per_page => 20)
+  end
+
+  private
+  ##
+  # require that the user is a moderator, or fill out a helpful error message
+  # and return them to the blocks index.
+  def require_moderator
+    unless @user.moderator?
+      flash[:notice] = t('user_block.filter.not_a_moderator')
+      redirect_to :action => 'index'
+    end
+  end
+
+  ##
+  # ensure that there is a "this_user" instance variable
+  def lookup_this_user
+    @this_user = User.find_by_display_name(params[:display_name])
+  rescue ActiveRecord::RecordNotFound
+    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] unless @this_user
+  end
+
+  ##
+  # ensure that there is a "user_block" instance variable
+  def lookup_user_block
+    @user_block = UserBlock.find(params[:id])
+  rescue ActiveRecord::RecordNotFound
+    render :action => "not_found", :status => :not_found
+  end
+
+  ##
+  # check that the input parameters are valid, setting an instance
+  # variable if not. note that this doesn't do any redirection, as it's
+  # called before two different actions, each of which should redirect
+  # to a different place.
+  def require_valid_params
+    @block_period = params[:user_block_period].to_i
+    @valid_params = false
+
+    if !UserBlock::PERIODS.include?(@block_period)
+      flash[:notice] = t('user_block.filter.block_period')
+      
+    elsif @user_block and !@user_block.active?
+      flash[:notice] = t('user_block.filter.block_expired')
+      
+    else
+      @valid_params = true
+    end
+  end
+
+end
index f4ff7fb7098bad18bf7dd28f293ffd4c7d6102ec..df6ca164c4a43c50925587b16db68d6ecfee7ef5 100644 (file)
@@ -1,5 +1,5 @@
 class UserController < ApplicationController
-  layout 'site'
+  layout 'site', :except => :api_details
 
   before_filter :authorize, :only => [:api_details, :api_gpx_files]
   before_filter :authorize_web, :except => [:api_details, :api_gpx_files]
@@ -8,6 +8,11 @@ class UserController < ApplicationController
   before_filter :check_database_readable, :except => [:api_details, :api_gpx_files]
   before_filter :check_database_writable, :only => [:login, :new, :set_home, :account, :go_public, :make_friend, :remove_friend, :upload_image, :delete_image]
   before_filter :check_api_readable, :only => [:api_details, :api_gpx_files]
+  before_filter :require_allow_read_prefs, :only => [:api_details]
+  before_filter :require_allow_read_gpx, :only => [:api_gpx_files]
+  before_filter :require_cookies, :only => [:login, :confirm]
+  before_filter :require_administrator, :only => [:activate, :deactivate, :hide, :unhide, :delete]
+  before_filter :lookup_this_user, :only => [:activate, :deactivate, :hide, :unhide, :delete]
 
   filter_parameter_logging :password, :pass_crypt, :pass_crypt_confirmation
 
@@ -27,7 +32,7 @@ class UserController < ApplicationController
 
       if @user.save
         flash[:notice] = t 'user.new.flash create success message'
-        Notifier.deliver_signup_confirm(@user, @user.tokens.create)
+        Notifier.deliver_signup_confirm(@user, @user.tokens.create(:referer => params[:referer]))
         redirect_to :action => 'login'
       else
         render :action => 'new'
@@ -37,6 +42,7 @@ class UserController < ApplicationController
 
   def account
     @title = t 'user.account.title'
+    @tokens = @user.oauth_tokens.find :all, :conditions => 'oauth_tokens.invalidated_at is null and oauth_tokens.authorized_at is not null'
 
     if params[:user] and params[:user][:display_name] and params[:user][:description]
       if params[:user][:email] != @user.email
@@ -139,36 +145,36 @@ class UserController < ApplicationController
   end
 
   def login
-    if session[:user]
-      # The user is logged in already, if the referer param exists, redirect them to that
-      if params[:referer]
-        redirect_to params[:referer]
-      else
-        redirect_to :controller => 'site', :action => 'index'
-      end
-      return
-    end
-
-    @title = t 'user.login.title'
-
-    if params[:user]
+    if params[:user] and session[:user].nil?
       email_or_display_name = params[:user][:email]
       pass = params[:user][:password]
       user = User.authenticate(:username => email_or_display_name, :password => pass)
       if user
         session[:user] = user.id
-        if params[:referer]
-          redirect_to params[:referer]
-        else
-          redirect_to :controller => 'site', :action => 'index'
-        end
-        return
       elsif User.authenticate(:username => email_or_display_name, :password => pass, :inactive => true)
         @notice = t 'user.login.account not active'
       else
         @notice = t 'user.login.auth failure'
       end
     end
+
+    if session[:user]
+      # The user is logged in, if the referer param exists, redirect them to that
+      # unless they've also got a block on them, in which case redirect them to
+      # the block so they can clear it.
+      user = User.find(session[:user])
+      block = user.blocked_on_view
+      if block
+        redirect_to block, :referrer => params[:referrer]
+      elsif params[:referer]
+        redirect_to params[:referer]
+      else
+        redirect_to :controller => 'site', :action => 'index'
+      end
+      return
+    end
+
+    @title = t 'user.login.title'
   end
 
   def logout
@@ -195,10 +201,15 @@ class UserController < ApplicationController
         @user.active = true
         @user.email_valid = true
         @user.save!
+        referer = token.referer
         token.destroy
         flash[:notice] = t 'user.confirm.success'
         session[:user] = @user.id
-        redirect_to :action => 'account', :display_name => @user.display_name
+        unless referer.nil?
+          redirect_to referer
+        else
+          redirect_to :action => 'account', :display_name => @user.display_name
+        end
       else
         @notice = t 'user.confirm.failure'
       end
@@ -237,10 +248,6 @@ class UserController < ApplicationController
     redirect_to :controller => 'user', :action => 'view', :display_name => @user.display_name
   end
 
-  def api_details
-    render :text => @user.to_xml.to_s, :content_type => "text/xml"
-  end
-
   def api_gpx_files
     doc = OSM::API.new.get_xml_doc
     @user.traces.each do |trace|
@@ -250,9 +257,10 @@ class UserController < ApplicationController
   end
 
   def view
-    @this_user = User.find_by_display_name(params[:display_name], :conditions => {:visible => true})
+    @this_user = User.find_by_display_name(params[:display_name])
 
-    if @this_user
+    if @this_user and
+       (@this_user.visible? or (@user and @user.administrator?))
       @title = @this_user.display_name
     else
       @title = t 'user.no_such_user.title'
@@ -262,7 +270,7 @@ class UserController < ApplicationController
   end
 
   def make_friend
-    if params[:display_name]     
+    if params[:display_name]
       name = params[:display_name]
       new_friend = User.find_by_display_name(name, :conditions => {:visible => true})
       friend = Friend.new
@@ -284,7 +292,7 @@ class UserController < ApplicationController
   end
 
   def remove_friend
-    if params[:display_name]     
+    if params[:display_name]
       name = params[:display_name]
       friend = User.find_by_display_name(name, :conditions => {:visible => true})
       if @user.is_friends_with?(friend)
@@ -297,4 +305,57 @@ class UserController < ApplicationController
       redirect_to :controller => 'user', :action => 'view'
     end
   end
+
+  ##
+  # activate a user, allowing them to log in
+  def activate
+    @this_user.update_attributes(:active => true)
+    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
+  end
+
+  ##
+  # deactivate a user, preventing them from logging in
+  def deactivate
+    @this_user.update_attributes(:active => false)
+    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
+  end
+
+  ##
+  # hide a user, marking them as logically deleted
+  def hide
+    @this_user.update_attributes(:visible => false)
+    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
+  end
+
+  ##
+  # unhide a user, clearing the logically deleted flag
+  def unhide
+    @this_user.update_attributes(:visible => true)
+    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
+  end
+
+  ##
+  # delete a user, marking them as deleted and removing personal data
+  def delete
+    @this_user.delete
+    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
+  end
+private
+  ##
+  # require that the user is a administrator, or fill out a helpful error message
+  # and return them to the user page.
+  def require_administrator
+    unless @user.administrator?
+      flash[:notice] = t('user.filter.not_an_administrator')
+      redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
+    end
+  end
+
+  ##
+  # ensure that there is a "this_user" instance variable
+  def lookup_this_user
+    @this_user = User.find_by_display_name(params[:display_name])
+  rescue ActiveRecord::RecordNotFound
+    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] unless @this_user
+  end
 end
index 59573047acc3591e22621f1fb041b99abe3f95d9..d02313497ef61408eb1667852c95abaa4e386366 100644 (file)
@@ -1,6 +1,8 @@
 # Update and read user preferences, which are arbitrayr key/val pairs
 class UserPreferenceController < ApplicationController
   before_filter :authorize
+  before_filter :require_allow_read_prefs, :only => [:read_one, :read]
+  before_filter :require_allow_write_prefs, :except => [:read_one, :read]
 
   def read_one
     pref = UserPreference.find(@user.id, params[:preference_key])
diff --git a/app/controllers/user_roles_controller.rb b/app/controllers/user_roles_controller.rb
new file mode 100644 (file)
index 0000000..ee4de7c
--- /dev/null
@@ -0,0 +1,83 @@
+class UserRolesController < ApplicationController
+  layout 'site'
+
+  before_filter :authorize_web
+  before_filter :require_user
+  before_filter :lookup_this_user
+  before_filter :require_administrator
+  before_filter :require_valid_role
+  before_filter :not_in_role, :only => [:grant]
+  before_filter :in_role, :only => [:revoke]
+  around_filter :setup_nonce
+
+  def grant
+    @this_user.roles.create(:role => @role, :granter_id => @user.id)
+    redirect_to :controller => 'user', :action => 'view', :display_name => @this_user.display_name
+  end
+
+  def revoke
+    UserRole.delete_all({:user_id => @this_user.id, :role => @role})
+    redirect_to :controller => 'user', :action => 'view', :display_name => @this_user.display_name
+  end
+
+  private
+  def require_administrator
+    unless @user.administrator?
+      flash[:notice] = t'user_role.filter.not_an_administrator'
+      redirect_to :controller => 'user', :action => 'view', :display_name => @this_user.display_name
+    end
+  end
+
+  ##
+  # ensure that there is a "this_user" instance variable
+  def lookup_this_user
+    @this_user = User.find_by_display_name(params[:display_name])
+  rescue ActiveRecord::RecordNotFound
+    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] unless @this_user
+  end
+
+  ##
+  # the random nonce here which isn't predictable, making an CSRF 
+  # procedure much, much more difficult. setup the nonce. if the given
+  # nonce matches the session nonce then yield into the actual method.
+  # otherwise, just sets up the nonce for the form.
+  def setup_nonce
+    if params[:nonce] and params[:nonce] == session[:nonce]
+      @nonce = params[:nonce]
+      yield
+    else
+      @nonce = OAuth::Helper.generate_nonce
+      session[:nonce] = @nonce
+      render
+    end
+  end    
+
+  ##
+  # require that the given role is valid. the role is a URL 
+  # parameter, so should always be present.
+  def require_valid_role
+    @role = params[:role]
+    unless UserRole::ALL_ROLES.include?(@role)
+      flash[:notice] = t('user_role.filter.not_a_role', :role => @role)
+      redirect_to :controller => 'user', :action => 'view', :display_name => @this_user.display_name
+    end
+  end
+
+  ##
+  # checks that the user doesn't already have this role
+  def not_in_role
+    if @this_user.has_role? @role
+      flash[:notice] = t('user_role.filter.already_has_role', :role => @role)
+      redirect_to :controller => 'user', :action => 'view', :display_name => @this_user.display_name
+    end
+  end
+
+  ##
+  # checks that the user already has this role
+  def in_role
+    unless @this_user.has_role? @role
+      flash[:notice] = t('user_role.filter.doesnt_have_role', :role => @role)
+      redirect_to :controller => 'user', :action => 'view', :display_name => @this_user.display_name
+    end
+  end
+end
index 4d345e06382b99dd37db07bbf874c153a5100bbe..f2cda21bca0da9e77938daca4a7e6f33d349c167 100644 (file)
@@ -2,6 +2,7 @@ class WayController < ApplicationController
   require 'xml/libxml'
 
   before_filter :authorize, :only => [:create, :update, :delete]
+  before_filter :require_allow_write_api, :only => [:create, :update, :delete]
   before_filter :require_public_data, :only => [:create, :update, :delete]
   before_filter :check_api_writable, :only => [:create, :update, :delete]
   before_filter :check_api_readable, :except => [:create, :update, :delete]
@@ -66,7 +67,7 @@ class WayController < ApplicationController
       user_display_name_cache = {}
 
       doc = OSM::API.new.get_xml_doc
-      way.nodes.each do |node|
+      way.nodes.uniq.each do |node|
         if node.visible
           doc.root << node.to_xml_node(changeset_cache, user_display_name_cache)
         end
index b28ab7c1a6eca2dabe18a38d1b90e694bc9e5f6d..bee4f9ce2f4dc5a6ec30ab8fb90b816675da3860 100644 (file)
@@ -10,4 +10,32 @@ module ApplicationHelper
   def atom_link_to(*args)
     return link_to(image_tag("RSS.gif", :size => "16x16", :border => 0), Hash[*args], { :class => "rsssmall" });
   end
+
+  def javascript_strings
+    js = ""
+
+    js << "<script type='text/javascript'>\n"
+    js << "i18n_strings = new Array();\n"
+    js << javascript_strings_for_key("javascripts")
+    js << "</script>\n"
+
+    return js
+  end
+
+private
+
+  def javascript_strings_for_key(key)
+    js = ""
+    value = t(key, :locale => "en")
+
+    if value.is_a?(String)
+      js << "i18n_strings['#{key}'] = '" << escape_javascript(t(key)) << "';\n"
+    else
+      value.each_key do |k|
+        js << javascript_strings_for_key("#{key}.#{k}")
+      end
+    end
+
+    return js
+  end
 end
index 879d516eff7b5643f4bd79ca4383ad7088a7c967..aed0c518f4ce46255f0597d47b1f8772abfd7472 100644 (file)
@@ -8,7 +8,9 @@ module BrowseHelper
     if version
       name = t 'printable_name.with_version', :id => name, :version => object.version.to_s
     end
-    if object.tags.include? 'name'
+    if object.tags.include? "name:#{I18n.locale}"
+      name = t 'printable_name.with_name',  :name => object.tags["name:#{I18n.locale}"].to_s, :id => name
+    elsif object.tags.include? 'name'
       name = t 'printable_name.with_name',  :name => object.tags['name'].to_s, :id => name
     end
     return name
index f1b4e01dd713c2b5d9ffb9364d570e3761cad6b4..e7d0ddf6c1d9cc8c27610ecc8d395a249036c6ca 100644 (file)
@@ -5,6 +5,7 @@ module GeocoderHelper
     html_options[:href] = "?mlat=#{result[:lat]}&mlon=#{result[:lon]}&zoom=#{result[:zoom]}"
     html = ""
     html << result[:prefix] if result[:prefix]
+    html << " " if result[:prefix] and result[:name]
     html << link_to_function(result[:name],"setPosition(#{result[:lat]}, #{result[:lon]}, #{result[:zoom]})", html_options)  if result[:name]
     html << result[:suffix] if result[:suffix]
     return html
diff --git a/app/helpers/oauth_clients_helper.rb b/app/helpers/oauth_clients_helper.rb
new file mode 100644 (file)
index 0000000..3b909aa
--- /dev/null
@@ -0,0 +1,2 @@
+module OauthClientsHelper
+end
\ No newline at end of file
diff --git a/app/helpers/oauth_helper.rb b/app/helpers/oauth_helper.rb
new file mode 100644 (file)
index 0000000..010cf9f
--- /dev/null
@@ -0,0 +1,2 @@
+module OauthHelper
+end
diff --git a/app/helpers/user_blocks_helper.rb b/app/helpers/user_blocks_helper.rb
new file mode 100644 (file)
index 0000000..3cd9373
--- /dev/null
@@ -0,0 +1,20 @@
+module UserBlocksHelper
+  ##
+  # returns a translated string representing the status of the 
+  # user block (i.e: whether it's active, what the expiry time is)
+  def block_status(block)
+    if block.active?
+      if block.needs_view?
+        I18n.t('user_block.helper.until_login')
+      else
+        I18n.t('user_block.helper.time_future', :time => distance_of_time_in_words_to_now(block.ends_at))
+      end
+    else
+      # the max of the last update time or the ends_at time is when this block finished
+      # either because the user viewed the block (updated_at) or it expired or was 
+      # revoked (ends_at)
+      last_time = [block.ends_at, block.updated_at].max
+      I18n.t('user_block.helper.time_past', :time => distance_of_time_in_words_to_now(last_time))
+    end
+  end
+end
diff --git a/app/models/access_token.rb b/app/models/access_token.rb
new file mode 100644 (file)
index 0000000..b773310
--- /dev/null
@@ -0,0 +1,10 @@
+class AccessToken<OauthToken
+  validates_presence_of :user
+  before_create :set_authorized_at
+  
+protected 
+  
+  def set_authorized_at
+    self.authorized_at = Time.now
+  end
+end
\ No newline at end of file
diff --git a/app/models/client_application.rb b/app/models/client_application.rb
new file mode 100644 (file)
index 0000000..d3799ab
--- /dev/null
@@ -0,0 +1,59 @@
+require 'oauth'
+class ClientApplication < ActiveRecord::Base
+  belongs_to :user
+  has_many :tokens, :class_name => "OauthToken"
+  validates_presence_of :name, :url, :key, :secret
+  validates_uniqueness_of :key
+  before_validation_on_create :generate_keys
+  
+  def self.verify_request(request, options = {}, &block)
+    begin
+      signature = OAuth::Signature.build(request, options, &block)
+      logger.info "Signature Base String: #{signature.signature_base_string}"
+      logger.info "Consumer: #{signature.send :consumer_key}"
+      logger.info "Token: #{signature.send :token}"
+      return false unless OauthNonce.remember(signature.request.nonce, signature.request.timestamp)
+      value = signature.verify
+      logger.info "Signature verification returned: #{value.to_s}"
+      value
+    rescue OAuth::Signature::UnknownSignatureMethod => e
+      logger.info "ERROR"+e.to_s
+      false
+    end
+  end
+  
+  def self.all_permissions
+    PERMISSIONS
+  end
+
+  def oauth_server
+    @oauth_server ||= OAuth::Server.new("http://" + SERVER_URL)
+  end
+  
+  def credentials
+    @oauth_client ||= OAuth::Consumer.new(key, secret)
+  end
+    
+  def create_request_token
+    RequestToken.create :client_application => self
+  end
+
+  # the permissions that this client would like from the user
+  def permissions
+    ClientApplication.all_permissions.select { |p| self[p] }
+  end
+
+protected
+  
+  # this is the set of permissions that the client can ask for. clients
+  # have to say up-front what permissions they want and when users sign up they
+  # can agree or not agree to each of them.
+  PERMISSIONS = [:allow_read_prefs, :allow_write_prefs, :allow_write_diary,
+                 :allow_write_api, :allow_read_gpx, :allow_write_gpx ]
+
+  def generate_keys
+    @oauth_client = oauth_server.generate_consumer_credentials
+    self.key = @oauth_client.key
+    self.secret = @oauth_client.secret
+  end
+end
index a33c76081c786ae594fe86cffea721da6406e812..7bb0b6e771a7e692aad56464ec969758524cab27 100644 (file)
@@ -3,6 +3,22 @@ class Language < ActiveRecord::Base
 
   has_many :diary_entries, :foreign_key => 'language'
 
+  def self.load(file)
+    Language.transaction do
+      YAML.load(File.read(file)).each do |k,v|
+        begin
+          Language.update(k, :english_name => v["english"], :native_name => v["native"])
+        rescue ActiveRecord::RecordNotFound
+          Language.create do |l|
+            l.code = k
+            l.english_name = v["english"]
+            l.native_name = v["native"]
+          end
+        end
+      end
+    end
+  end
+
   def name
     name = english_name
     name += " (#{native_name})" unless native_name.nil?
diff --git a/app/models/oauth_nonce.rb b/app/models/oauth_nonce.rb
new file mode 100644 (file)
index 0000000..075351b
--- /dev/null
@@ -0,0 +1,13 @@
+# Simple store of nonces. The OAuth Spec requires that any given pair of nonce and timestamps are unique.
+# Thus you can use the same nonce with a different timestamp and viceversa.
+class OauthNonce < ActiveRecord::Base
+  validates_presence_of :nonce, :timestamp
+  validates_uniqueness_of :nonce, :scope => :timestamp
+  
+  # Remembers a nonce and it's associated timestamp. It returns false if it has already been used
+  def self.remember(nonce, timestamp)
+    oauth_nonce = OauthNonce.create(:nonce => nonce, :timestamp => timestamp)
+    return false if oauth_nonce.new_record?
+    oauth_nonce
+  end
+end
diff --git a/app/models/oauth_token.rb b/app/models/oauth_token.rb
new file mode 100644 (file)
index 0000000..f64ec53
--- /dev/null
@@ -0,0 +1,41 @@
+class OauthToken < ActiveRecord::Base
+  belongs_to :client_application
+  belongs_to :user
+  validates_uniqueness_of :token
+  validates_presence_of :client_application, :token, :secret
+  before_validation_on_create :generate_keys
+  
+  def self.find_token(token_key)
+    token = OauthToken.find_by_token(token_key, :include => :client_application)
+    if token && token.authorized?
+      logger.info "Loaded #{token.token} which was authorized by (user_id=#{token.user_id}) on the #{token.authorized_at}"
+      token
+    else
+      nil
+    end
+  end
+  
+  def invalidated?
+    invalidated_at != nil
+  end
+  
+  def invalidate!
+    update_attribute(:invalidated_at, Time.now)
+  end
+  
+  def authorized?
+    authorized_at != nil && !invalidated?
+  end
+  
+  def to_query
+    "oauth_token=#{token}&oauth_token_secret=#{secret}"
+  end
+    
+protected
+  
+  def generate_keys
+    @oauth_token = client_application.oauth_server.generate_credentials
+    self.token = @oauth_token[0]
+    self.secret = @oauth_token[1]
+  end
+end
diff --git a/app/models/request_token.rb b/app/models/request_token.rb
new file mode 100644 (file)
index 0000000..d66fe6c
--- /dev/null
@@ -0,0 +1,23 @@
+class RequestToken < OauthToken
+  def authorize!(user)
+    return false if authorized?
+    self.user = user
+    self.authorized_at = Time.now
+    self.save
+  end
+  
+  def exchange!
+    return false unless authorized?
+    RequestToken.transaction do
+      params = { :user => user, :client_application => client_application }
+      # copy the permissions from the authorised request token to the access token
+      client_application.permissions.each { |p| 
+        params[p] = read_attribute(p)
+      }
+
+      access_token = AccessToken.create(params)
+      invalidate!
+      access_token
+    end
+  end
+end
index cbfd68996ff5a7944ecb5df197a01163fd670575..24f93236a7367200d6c50f8aa4eccbfdce9a32ec 100644 (file)
@@ -26,7 +26,7 @@ class Trace < ActiveRecord::Base
 
   def tagstring=(s)
     if s.include? ','
-      self.tags = s.split(/\s*,\s*/).collect {|tag|
+      self.tags = s.split(/\s*,\s*/).select {|tag| tag !~ /^\s*$/}.collect {|tag|
         tt = Tracetag.new
         tt.tag = tag
         tt
index 9d135a3a1ae4aa97e14202f9ea0bba1abd61d0e2..54b3fa371c4acc3674a0a303dea79d93a9ffa02b 100644 (file)
@@ -11,6 +11,12 @@ class User < ActiveRecord::Base
   has_many :preferences, :class_name => "UserPreference"
   has_many :changesets
 
+  has_many :client_applications
+  has_many :oauth_tokens, :class_name => "OauthToken", :order => "authorized_at desc", :include => [:client_application]
+
+  has_many :active_blocks, :class_name => "UserBlock", :conditions => ['user_blocks.ends_at > \'#{Time.now.getutc.xmlschema(5)}\' or user_blocks.needs_view']
+  has_many :roles, :class_name => "UserRole"
+
   validates_presence_of :email, :display_name
   validates_confirmation_of :email#, :message => ' addresses must match'
   validates_confirmation_of :pass_crypt#, :message => ' must match the confirmation password'
@@ -30,7 +36,7 @@ class User < ActiveRecord::Base
   file_column :image, :magick => { :geometry => "100x100>" }
 
   def after_initialize
-    self.creation_time = Time.now.getutc if self.creation_time.nil?
+    self.creation_time = Time.now.getutc unless self.attribute_present?(:creation_time)
   end
 
   def encrypt_password
@@ -122,6 +128,31 @@ class User < ActiveRecord::Base
     return false
   end
 
+  ##
+  # returns true if the user has the moderator role, false otherwise
+  def moderator?
+    has_role? 'moderator'
+  end
+
+  ##
+  # returns true if the user has the administrator role, false otherwise
+  def administrator?
+    has_role? 'administrator'
+  end
+
+  ##
+  # returns true if the user has the requested role
+  def has_role?(role)
+    roles.any? { |r| r.role == role }
+  end
+
+  ##
+  # returns the first active block which would require users to view 
+  # a message, or nil if there are none.
+  def blocked_on_view
+    active_blocks.detect { |b| b.needs_view? }
+  end
+
   def delete
     self.active = false
     self.display_name = "user_#{self.id}"
diff --git a/app/models/user_block.rb b/app/models/user_block.rb
new file mode 100644 (file)
index 0000000..23e1bca
--- /dev/null
@@ -0,0 +1,35 @@
+class UserBlock < ActiveRecord::Base
+  validate :moderator_permissions
+
+  belongs_to :user, :class_name => "User", :foreign_key => :user_id
+  belongs_to :creator, :class_name => "User", :foreign_key => :creator_id
+  belongs_to :revoker, :class_name => "User", :foreign_key => :revoker_id
+  
+  PERIODS = APP_CONFIG['user_block_periods']
+
+  ##
+  # returns true if the block is currently active (i.e: the user can't
+  # use the API).
+  def active?
+    needs_view or ends_at > Time.now.getutc
+  end
+
+  ##
+  # revokes the block, allowing the user to use the API again. the argument
+  # is the user object who is revoking the ban.
+  def revoke!(revoker)
+    update_attributes({ :ends_at => Time.now.getutc(),
+                        :revoker_id => revoker.id,
+                        :needs_view => false })
+  end
+
+  private
+  ##
+  # validate that only moderators are allowed to change the
+  # block. this should be caught and dealt with in the controller,
+  # but i've also included it here just in case.
+  def moderator_permissions
+    errors.add_to_base(I18n.t('user_block.model.non_moderator_update')) if creator_id_changed? and !creator.moderator?
+    errors.add_to_base(I18n.t('user_block.model.non_moderator_revoke')) unless revoker_id.nil? or revoker.moderator?
+  end
+end
diff --git a/app/models/user_role.rb b/app/models/user_role.rb
new file mode 100644 (file)
index 0000000..fb78328
--- /dev/null
@@ -0,0 +1,8 @@
+class UserRole < ActiveRecord::Base
+  belongs_to :user
+
+  ALL_ROLES = ['administrator', 'moderator']
+
+  validates_inclusion_of :role, :in => ALL_ROLES
+  validates_uniqueness_of :role, :scope => :user_id
+end
index 179b22f60813add46ec6a752d627e7bc404b46e9..0c486e0a716c789d94116e44282d52689d7294f0 100644 (file)
   <td><%= link_to common_details.changeset_id, :action => :changeset, :id => common_details.changeset_id %></td>
 </tr>
 
+<% if common_details.changeset.tags['comment'] %>
+  <tr>
+    <th><%= t 'browse.common_details.changeset_comment' %></th>
+    <td><%= auto_link(h(common_details.changeset.tags['comment'])) %></td>
+  </tr>
+<% end %>
+
 <%= render :partial => "tag_details", :object => common_details %>
index a9a122e6da6cbf9f49a6f6467323659f15e92535..5724b064611c396db2c38ccd6bef22b00155b9e5 100644 (file)
@@ -1,3 +1,3 @@
 <tr>
-  <td><%= h(tag[0]) %> = <%= sanitize(auto_link(tag[1])) %></td>
+  <td><%= h(tag[0]) %> = <%= auto_link(h(tag[1])) %></td>
 </tr> 
index 743ab0c8e0bb6543e427a1c99065b1f63c218649..f536ef9ffea74b30bf766c51d28d7aa0dcf51c9e 100644 (file)
@@ -3,6 +3,7 @@
     'node' => I18n.t('browse.not_found.type.node'),
     'way' => I18n.t('browse.not_found.type.way'),
     'relation' => I18n.t('browse.not_found.type.relation'),
+    'changeset' => I18n.t('browse.not_found.type.changeset'),
   };
 %>
 <p><%= t'browse.not_found.sorry', :type=> browse_not_found_type[@type] , :id => params[:id] %></p>
index 70705452680be75283919966e5f718660f570423..220295663f8c9753e083c3738e504ba05f0c9798 100644 (file)
@@ -262,7 +262,7 @@ page << <<EOJ
         // Link, for viewing in the tab
         var link = document.createElement("a");
         link.href =  "/browse/" + type + "/" + feature.osm_id; 
-        var name = feature.attributes.name || feature.osm_id;
+        var name = featureName(feature);
         link.appendChild(document.createTextNode(name));
         link.feature = feature;
         link.onclick = OpenLayers.Function.bind(viewFeatureLink, link);   
@@ -466,8 +466,20 @@ page << <<EOJ
     }
   }
 
+  function featureName(feature) {
+    if (feature.attributes['name:#{I18n.locale}']) {
+      return feature.attributes['name:#{I18n.locale}'];
+    } else if (feature.attributes.name) {
+      return feature.attributes.name;
+    } else {
+      return feature.osm_id;
+    }
+  }
+
   function featureNameSelect(feature) {
-    if (feature.attributes.name) {
+    if (feature.attributes['name:#{I18n.locale}']) {
+      return feature.attributes['name:#{I18n.locale}'];
+    } else if (feature.attributes.name) {
       return feature.attributes.name;
     } else if (featureType(feature) == "node") {
       return i18n("#{I18n.t('browse.start_rjs.object_list.selected.type.node')}", { id: feature.osm_id });
@@ -477,7 +489,9 @@ page << <<EOJ
   }
 
   function featureNameHistory(feature) {
-    if (feature.attributes.name) {
+    if (feature.attributes['name:#{I18n.locale}']) {
+      return feature.attributes['name:#{I18n.locale}'];
+    } else if (feature.attributes.name) {
       return feature.attributes.name;
     } else if (featureType(feature) == "node") {
       return i18n("#{I18n.t('browse.start_rjs.object_list.history.type.node')}", { id: feature.osm_id });
index b682f1b4bd68a95a29d1e5b1e252cb48a662c194..650030688eb82d431faf084cc47f5e1063a94243 100644 (file)
@@ -12,7 +12,7 @@
 
   <td class="<%= cl %> date">
     <% if changeset.closed_at > DateTime.now %> <%= t'changeset.changeset.still_editing' %>
-    <% else %><%= l changeset.closed_at, :format => :short %><% end %>
+    <% else %><%= l changeset.closed_at, :format => :long %><% end %>
   </td>
 
     
@@ -28,7 +28,7 @@
     
   <td class="<%= cl %> comment">
     <% if changeset.tags['comment'] %>
-      <%= h(changeset.tags['comment']) %>
+      <%= auto_link(h(changeset.tags['comment'])) %>
     <% else %>
       <%= t'changeset.changeset.no_comment' %>
     <% end %>
index 27bc30981b24b896f0ab35c91d80aebd1e2000c5..5a5d94f05d89a670a739111f0180517926dc5e18 100644 (file)
@@ -7,5 +7,7 @@ if (current_page.first_item < current_page.last_item) # if more than 1 changeset
   %>-<%= current_page.last_item %><% 
 end %>
 <%= t'changeset.changeset_paging_nav.of'%> <%= @edit_pages.item_count %>)
- | <%= pagination_links_each(@edit_pages, {}) { |n| link_to(n, params.merge({ :page => n })) }  %>
+<% if @edit_pages.page_count > 1 %>
+ | <%= pagination_links_each(@edit_pages, {}) { |n| link_to(n, params.merge({ :page => n })) } %>
+<% end %>
 </p>
index 6dcdd4f1d78f80f331b12389efcefd959f46ec04..d9d53593c2dd8f047c25999e2eb1e7338c5d30d7 100644 (file)
@@ -68,7 +68,7 @@ atom_feed(:language => I18n.locale, :schema_date => 2009,
                 td.table :cellpadding => "0" do |table|
                   changeset.tags.sort.each do |tag|
                     table.tr do |tr|
-                      tr.td "#{h(tag[0])} = #{sanitize(auto_link(tag[1]))}"
+                      tr.td << "#{h(tag[0])} = #{auto_link(h(tag[1]))}"
                     end
                   end
                 end
index 59b7c304bd94e573c030e057f750b802dd782dcd..d1983a9f0ba2e4cb72c62517bfe7406fd5b9b9a1 100644 (file)
@@ -1,10 +1,15 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= I18n.locale %>" lang="<%= I18n.locale %>" dir="<%= t'html.dir' %>">
   <head>
+    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
+    <%= javascript_strings %>
     <%= javascript_include_tag 'prototype' %>
     <%= javascript_include_tag 'site' %>
     <!--[if lt IE 7]><%= javascript_include_tag 'pngfix' %><![endif]--> <!-- thanks, microsoft! -->
-    <%= stylesheet_link_tag 'site' %>
+    <%= stylesheet_link_tag 'common' %>
+    <!--[if IE]><%= stylesheet_link_tag 'site', :media => "screen" %><![endif]--> <!-- IE is totally broken with CSS media queries -->
+    <%= stylesheet_link_tag 'site-sml', :media => "only screen and (max-width: 481px)" %>
+    <%= stylesheet_link_tag 'site', :media => "screen and (min-width: 482px)" %> 
     <%= stylesheet_link_tag 'print', :media => "print" %>
     <%= tag("link", { :rel => "search", :type => "application/opensearchdescription+xml", :title => "OpenStreetMap Search", :href => "/opensearch/osm.xml" }) %>
     <%= tag("meta", { :name => "description", :content => "OpenStreetMap is the free wiki world map." }) %>
@@ -22,7 +27,8 @@
 
     <span id="greeting">
       <% if @user and @user.id %>
-        <%= t 'layouts.welcome_user', :user_link => (link_to h(@user.display_name), {:controller => 'user', :action => 'view', :display_name => @user.display_name}, :title => t('layouts.welcome_user_link_tooltip')) %> | 
+        <span id="full-greeting"><%= t 'layouts.welcome_user', :user_link => (link_to h(@user.display_name), {:controller => 'user', :action => 'view', :display_name => @user.display_name}, :title => t('layouts.welcome_user_link_tooltip')) %></span> 
+        <span id="small-greeting"><%= link_to t('layouts.welcome_user_link_tooltip'), {:controller => 'user', :action => 'view', :display_name => @user.display_name} %></span> | 
         <%= yield :greeting %>
         <%
         inbox_attributes = {}
       <%= yield :optionals %>
 
       <center>
-        <div class="button" style="width: 115px">
-          <a href="http://donate.openstreetmap.org/"><img src="/images/donate.png" border="0" alt="<%= t 'layouts.alt_donation' %>" title="<%= t 'layouts.alt_donation' %>" /></a>
+        <div class="donate">
+          <a href="http://donate.openstreetmap.org/" title="<%= h(t('layouts.make_a_donation.title')) %>"><%= h(t('layouts.make_a_donation.text')) %></a>
         </div>
 
         <div id="cclogo" class="button" style="width: 88px">
-          <%= link_to image_tag("cc_button.png", :alt => "CC by-sa 2.0", :border => "0"), "http://creativecommons.org/licenses/by-sa/2.0/" %>
+          <%= link_to(
+                  image_tag("cc_button.png",
+                      :alt => t('layouts.license.alt'),
+                      :border => 0,
+                      :width => 88,
+                      :height => 31,
+                      :title => t('layouts.license.title')),
+                  "http://creativecommons.org/licenses/by-sa/2.0/",
+                  { :rel => "license" }) %>
         </div>
       </center>
     </div>
index 9ae756f833d6daa5f22d5420112bd6e9cf47a5fe..151cd275936ab6fd25c4e7ae6de4bec6ac6ceb6b 100644 (file)
@@ -1,4 +1,4 @@
-<h2><%= t'message.new.send_message_to', :name => h(@to_user.display_name) %></h2>
+<h2><%= t'message.new.send_message_to', :name => link_to(h(@to_user.display_name), {:controller => 'user', :action => 'view', :display_name => @to_user.display_name}) %></h2>
 
 <%= error_messages_for 'message' %>
 
index f1f9ddea73a5523b6d7ccc96babd876bf3c547a6..afd1d2fc530b96d1624d3a1d855fff5f4a289e5b 100644 (file)
@@ -1,6 +1,6 @@
 <h2><%= t'message.outbox.my_inbox', :inbox_link => link_to(t('message.outbox.inbox'), url_for(:controller => "user", :action => "inbox", :id => @user.display_name)) %>/<%= t'message.outbox.outbox' %></h2>
 
-<p><%= t'message.outbox.you_have_sent_messages', :sent_count => @user.sent_messages.size %>
+<p><%= t'message.outbox.you_have_sent_messages', :count => @user.sent_messages.size %>
 
 <% if @user.sent_messages.size > 0 %>
   <div id="messages">
diff --git a/app/views/oauth/authorize_failure.html.erb b/app/views/oauth/authorize_failure.html.erb
new file mode 100644 (file)
index 0000000..d8110c9
--- /dev/null
@@ -0,0 +1 @@
+<h1>You have disallowed this request</h1>
diff --git a/app/views/oauth/authorize_success.html.erb b/app/views/oauth/authorize_success.html.erb
new file mode 100644 (file)
index 0000000..effe24a
--- /dev/null
@@ -0,0 +1 @@
+<h1>You have allowed this request</h1>
\ No newline at end of file
diff --git a/app/views/oauth/oauthorize.html.erb b/app/views/oauth/oauthorize.html.erb
new file mode 100644 (file)
index 0000000..844a86d
--- /dev/null
@@ -0,0 +1,15 @@
+<h1>Authorize access to your account</h1>
+<p><%= t('oauth.oauthorize.request_access', :app_name => link_to(@token.client_application.name,@token.client_application.url)) %></p>
+<% form_tag authorize_url do %>
+  <%= hidden_field_tag "oauth_token", @token.token %>
+  <%- if params[:oauth_callback] -%>
+    <%= hidden_field_tag "oauth_callback", params[:oauth_callback] %>
+  <%- end -%>
+  <p><%= t 'oauth.oauthorize.allow_to' %></p>
+  <ul style="list-style:none">
+  <% @token.client_application.permissions.each do |perm| %>
+    <li><%= check_box_tag perm.to_s, "yes", @token.read_attribute(perm) %><%= t "oauth.oauthorize.#{perm}" %></li>
+  <% end %>
+  </ul>
+  <p><%= submit_tag %></p>
+<% end %>
diff --git a/app/views/oauth_clients/_form.html.erb b/app/views/oauth_clients/_form.html.erb
new file mode 100644 (file)
index 0000000..dc8f8e3
--- /dev/null
@@ -0,0 +1,23 @@
+<div class="field">
+  <label for="client_application_name"><%= t'oauth_clients.form.name' %> (<%= t'oauth_clients.form.required' %>)</label><br/>
+  <%= f.text_field :name %>
+</div>
+<div class="field">
+  <label for="client_application_url"><%= t'oauth_clients.form.url' %> (<%= t'oauth_clients.form.required' %>)</label><br/>
+  <%= f.text_field :url %>
+</div>
+<div class="field">
+  <label for="client_application_callback_url"><%= t'oauth_clients.form.callback_url' %></label><br/>
+  <%= f.text_field :callback_url %>
+</div>
+<div class="field">
+  <label for="client_application_support_url"><%= t'oauth_clients.form.support_url' %></label><br/>
+  <%= f.text_field :support_url %>
+</div>
+<p><%= t'oauth_clients.form.requests' %></p>
+<% ClientApplication.all_permissions.each do |perm| %>
+<div class="field">
+  <%= f.check_box perm %>
+  <label for="client_application_<%= perm.to_s %>"><%= t('oauth_clients.form.' + perm.to_s) %></label><br/>
+</div>
+<% end %>
diff --git a/app/views/oauth_clients/edit.html.erb b/app/views/oauth_clients/edit.html.erb
new file mode 100644 (file)
index 0000000..085ddef
--- /dev/null
@@ -0,0 +1,6 @@
+<h1><%= t'oauth_clients.edit.title' %></h1>
+<% form_for :client_application, @client_application, :url => oauth_client_path(@client_application.user.display_name, @client_application), :html => { :method => :put } do |f| %>
+  <%= render :partial => "form", :locals => { :f => f } %>
+  <br/>
+  <%= submit_tag t'oauth_clients.edit.submit' %>
+<% end %>
diff --git a/app/views/oauth_clients/index.html.erb b/app/views/oauth_clients/index.html.erb
new file mode 100644 (file)
index 0000000..d95c68b
--- /dev/null
@@ -0,0 +1,33 @@
+<h1><%= t'oauth_clients.index.title' %></h1>
+<% unless @tokens.empty? %>
+<h3><%= t'oauth_clients.index.my_tokens' %></h3>
+<p><%= t'oauth_clients.index.list_tokens' %></p>
+<table>
+  <tr><th><%= t'oauth_clients.index.application' %></th>
+    <th><%= t'oauth_clients.index.issued_at' %></th><th>&nbsp;</th></tr>
+  <% @tokens.each do |token|%>
+    <% content_tag_for :tr, token do %>
+      <td><%= link_to token.client_application.name, token.client_application.url %></td>
+      <td><%= token.authorized_at %></td>
+      <td>
+       <% form_tag :controller => 'oauth', :action => 'revoke' do %>
+       <%= hidden_field_tag 'token', token.token %>
+       <%= submit_tag t('oauth_clients.index.revoke') %>
+       <% end %>
+      </td>
+    <% end %>
+  <% end %>    
+</table>
+<% end %>
+<h3><%= t'oauth_clients.index.my_apps' %></h3>
+<% if @client_applications.empty? %>
+<p><%= t('oauth_clients.index.no_apps', :oauth => "<a href=\"http://oauth.net\">OAuth</a>") %></p>
+<% else %>
+<p><%= t'oauth_clients.index.registered_apps' %></p>
+<% @client_applications.each do |client|%>
+  <% div_for client do %>
+    <%= link_to client.name, :action => :show, :id => client.id %>
+  <% end %>
+<% end %>
+<% end %>
+<h3><%= link_to t('oauth_clients.index.register_new'), :action => :new %></h3>
diff --git a/app/views/oauth_clients/new.html.erb b/app/views/oauth_clients/new.html.erb
new file mode 100644 (file)
index 0000000..292c53f
--- /dev/null
@@ -0,0 +1,6 @@
+<h1><%= t'oauth_clients.new.title' %></h1>
+<% form_for :client_application, :url => { :action => :create } do |f| %>
+   <%= render :partial => "form", :locals => { :f => f } %>
+   <br />
+   <%= submit_tag t('oauth_clients.new.submit') %>
+<% end %>
diff --git a/app/views/oauth_clients/not_found.erb b/app/views/oauth_clients/not_found.erb
new file mode 100644 (file)
index 0000000..d5c6ca7
--- /dev/null
@@ -0,0 +1 @@
+<p><%= t('oauth_clients.not_found.sorry', :type => @type) %></p>
diff --git a/app/views/oauth_clients/show.html.erb b/app/views/oauth_clients/show.html.erb
new file mode 100644 (file)
index 0000000..2769fcd
--- /dev/null
@@ -0,0 +1,27 @@
+<h1><%= t('oauth_clients.show.title', :app_name => @client_application.name) %></h1>
+<p>
+  <b><%= t'oauth_clients.show.key' %></b> <%=@client_application.key %>
+</p>
+<p>
+  <b><%= t'oauth_clients.show.secret' %></b> <%=@client_application.secret %>
+</p>
+<p>
+  <b><%= t'oauth_clients.show.url' %></b> http<%='s' if request.ssl? %>://<%= request.host_with_port %><%=@client_application.oauth_server.request_token_path %>
+</p>
+<p>
+  <b><%= t'oauth_clients.show.access_url' %></b> http<%='s' if request.ssl? %>://<%= request.host_with_port %><%=@client_application.oauth_server.access_token_path %>
+</p>
+<p>
+  <b><%= t'oauth_clients.show.authorize_url' %></b> http<%='s' if request.ssl? %>://<%= request.host_with_port %><%=@client_application.oauth_server.authorize_path %>
+</p>
+
+<p><%= t'oauth_clients.show.requests' %></p>
+<ul><% @client_application.permissions.each do |perm| %>
+<div class="field">
+  <li><%= t('oauth_clients.form.' + perm.to_s) %></li>
+</div>
+<% end %></ul>
+
+<p><%= t'oauth_clients.show.support_notice' %></p>
+
+<p><%= link_to t('oauth_clients.show.edit'), edit_oauth_client_url(@client_application.user.display_name, @client_application) %></p>
index 142d7a3f312f1678b2a890c49bd7ab4144a1658e..51389afc16181b34c6348146cfb8bbefe6da57ca 100644 (file)
@@ -65,7 +65,7 @@ zoom='14' if zoom.nil?
   
   window.onbeforeunload=function() {
     if (!changesaved) {
-      return "<%= t 'site.edit.potlatch_unsaved_changes' %>";
+      return '<%= escape_javascript(t('site.edit.potlatch_unsaved_changes')) %>';
     }
   }
 
@@ -78,9 +78,10 @@ zoom='14' if zoom.nil?
     fo.addVariable('token','<%= session[:token] %>');
     if (lat) { fo.addVariable('lat',lat); }
     if (lon) { fo.addVariable('long',lon); }
-    <% if params['gpx']  %>fo.addVariable('gpx' ,'<%= h(params['gpx'] ) %>');<% end %>
-    <% if params['way']  %>fo.addVariable('way' ,'<%= h(params['way'] ) %>');<% end %>
-    <% if params['node'] %>fo.addVariable('node','<%= h(params['node']) %>');<% end %>
+    <% if params['gpx']     %>fo.addVariable('gpx'     ,'<%= h(params['gpx']    ) %>');<% end %>
+    <% if params['way']     %>fo.addVariable('way'     ,'<%= h(params['way']    ) %>');<% end %>
+    <% if params['node']    %>fo.addVariable('node'    ,'<%= h(params['node']   ) %>');<% end %>
+    <% if params['tileurl'] %>fo.addVariable('custombg','<%= h(params['tileurl']) %>');<% end %>
     fo.write("map");
   }
 
index 75303f10d349b3e6fdd1288c2501a449114efb86..a73bb53b8250a5bad816f6e624d52b8bea8e3520 100644 (file)
@@ -54,7 +54,7 @@
     near_icon.url = OpenLayers.Util.getImagesLocation() + "marker-green.png";;
     var i = nearest.length;
     while( i-- ) {
-      var description = '<%= t 'user.friend_map.nearby mapper'%><a href="/user/'+nearest[i].display_name+'">'+nearest[i].display_name+'</a>'
+      var description = i18n('<%= t 'user.friend_map.nearby mapper'%>', { nearby_user: '<a href="/user/'+nearest[i].display_name+'">'+nearest[i].display_name+'</a>' });
       var nearmarker = addMarkerToMap(new OpenLayers.LonLat(nearest[i].home_lon, nearest[i].home_lat), near_icon.clone(), description);
     }
 
index 15a8f6827054cd2d50a4cbf371a578ac10264c26..45a129077563145ca47ed20e7c2542be4f54b0a9 100644 (file)
@@ -29,7 +29,7 @@
   <div id="map" style="border:1px solid black; position:relative; width:500px; height:400px;"></div>
   </td></tr>
   
-  <tr><td></td><td align=right><br/></br><%= submit_tag t('user.account.save changes button') %></td></tr>
+  <tr><td></td><td align=right><br/><%= submit_tag t('user.account.save changes button') %></td></tr>
 </table>
 <br/>
 
diff --git a/app/views/user/api_details.builder b/app/views/user/api_details.builder
new file mode 100644 (file)
index 0000000..d70c65f
--- /dev/null
@@ -0,0 +1,23 @@
+xml.instruct! :xml, :version => "1.0"
+xml.osm("version" => API_VERSION, "generator" => GENERATOR) do
+  xml.tag! "user", :id => @user.id,
+                   :display_name => @user.display_name,
+                   :account_created => @user.creation_time.xmlschema do
+    if @user.description
+      xml.tag! "description", @user.description
+    end
+    if @user.home_lat and @user.home_lon
+      xml.tag! "home", :lat => @user.home_lat,
+                       :lon => @user.home_lon,
+                       :zoom => @user.home_zoom
+    end    
+    if @user.image
+      xml.tag! "img", :href => (url_for_file_column(@user, "image", :absolute => true))
+    end
+    if @user.languages
+      xml.tag! "languages" do
+        @user.languages.split(",") { |lang| xml.tag! "lang", lang }
+      end
+    end
+  end
+end
index dc10011172a41a32598bff8a36852667ed3d3065..77294e62fae34c98cef92b7bd979a3980b88fe58 100644 (file)
@@ -1,13 +1,13 @@
 <h1><%= t 'user.login.heading' %></h1>
 
-<p><%= t 'user.login.please login', :create_user_link => link_to(t('user.login.create_account'), :controller => 'user', :action => 'new') %></p>
+<p><%= t 'user.login.please login', :create_user_link => link_to(t('user.login.create_account'), :controller => 'user', :action => 'new', :referer => params[:referer]) %></p>
 
 <% form_tag :action => 'login' do %>
 <%= hidden_field_tag('referer', h(params[:referer])) %>
 <table>
-  <tr><td class="fieldName"><%= t 'user.login.email or username' %></td><td><%= text_field('user', 'email',{:size => 50, :maxlength => 255, :tabindex => 1}) %></td></tr>
+  <tr><td class="fieldName"><%= t 'user.login.email or username' %></td><td><%= text_field('user', 'email',{:size => 28, :maxlength => 255, :tabindex => 1}) %></td></tr>
   <tr><td class="fieldName"><%= t 'user.login.password' %></td><td><%= password_field('user', 'password',{:size => 28, :maxlength => 255, :tabindex => 2}) %> <span class="minorNote">(<%= link_to t('user.login.lost password link'), :controller => 'user', :action => 'lost_password' %>)</span></td></tr>
   <tr><td colspan=2>&nbsp;<!--vertical spacer--></td></tr>
-  <tr><td></td><td align="right"><%= submit_tag t('user.login.login_button'), :tabindex => 3 %></td></tr>
+  <tr><td></td><td align="left"><%= submit_tag t('user.login.login_button'), :tabindex => 3 %></td></tr>
 </table>
 <% end %>
index 6ac85560d3720b78fef0829d49c1574502b4c6fd..8b1dab5bedd153ccab5452fa9c442c0811dc199d 100644 (file)
@@ -19,6 +19,7 @@
 <%= error_messages_for 'user' %>
 
 <% form_tag :action => 'save' do %>
+<%= hidden_field_tag('referer', h(params[:referer])) unless params[:referer].nil? %>
 <table id="loginForm">
   <tr><td class="fieldName"><%= t 'user.new.email address' %></td><td><%= text_field('user', 'email',{:size => 50, :maxlength => 255, :tabindex => 1}) %></td></tr>
   <tr><td class="fieldName"><%= t 'user.new.confirm email address' %></td><td><%= text_field('user', 'email_confirmation',{:size => 50, :maxlength => 255, :tabindex => 2}) %></td></tr>
index ff349858c9229fd42916982fd0786c5fed3207f1..f05b262208c2dedef904dc80368c1c70965587a7 100644 (file)
@@ -1,4 +1,15 @@
-<h2><%= h(@this_user.display_name) %></h2>
+<h2><%= h(@this_user.display_name) %>
+<% UserRole::ALL_ROLES.each do |role| %>
+<% if @user and @user.administrator? %>
+<% if @this_user.has_role? role %>
+<%= link_to(image_tag("roles/#{role}.png", :size => "20x20", :border => 0, :alt => t("user.view.role.revoke.#{role}"), :title => t("user.view.role.revoke.#{role}")), :controller => 'user_roles', :action => 'revoke', :display_name => @this_user.display_name, :role => role) %>
+<% else %>
+<%= link_to(image_tag("roles/blank_#{role}.png", :size => "20x20", :border => 0, :alt => t("user.view.role.grant.#{role}"), :title => t("user.view.role.grant.#{role}")), :controller => 'user_roles', :action => 'grant', :display_name => @this_user.display_name, :role => role) %>
+<% end %>
+<% elsif @this_user.has_role? role %>
+<%= image_tag("roles/#{role}.png", :size => "20x20", :border => 0, :alt => t("user.view.role.#{role}"), :title => t("user.view.role.#{role}")) %>
+<% end %>
+<% end %></h2>
 <div id="userinformation">
 <% if @user and @this_user.id == @user.id %>
 <!-- Displaying user's own profile page -->
@@ -7,6 +18,10 @@
 | <%= link_to t('user.view.my edits'), :controller => 'changeset', :action => 'list', :display_name => @user.display_name %>
 | <%= link_to t('user.view.my traces'), :controller => 'trace', :action=>'mine' %>
 | <%= link_to t('user.view.my settings'), :controller => 'user', :action => 'account', :display_name => @user.display_name %>
+| <%= link_to t('user.view.blocks on me'), :controller => 'user_blocks', :action => 'blocks_on', :display_name => @user.display_name %>
+<% if @user and @user.moderator? %>
+| <%= link_to t('user.view.blocks by me'), :controller => 'user_blocks', :action => 'blocks_by', :display_name => @user.display_name %>
+<% end %>
 <% else %>
 <!-- Displaying another user's profile page -->
 <%= link_to t('user.view.send message'), :controller => 'message', :action => 'new', :display_name => @this_user.display_name %>
 <% else %>
   <%= link_to t('user.view.add as friend'), :controller => 'user', :action => 'make_friend', :display_name => @this_user.display_name %>
 <% end %>
+| <%= link_to t('user.view.block_history'), :controller => 'user_blocks', :action => 'blocks_on', :display_name => @this_user.display_name %>
+<% if @this_user.moderator? %>
+| <%= link_to t('user.view.moderator_history'), :controller => 'user_blocks', :action => 'blocks_by', :display_name => @this_user.display_name %>
+<% end %>
+<% if @user and @user.moderator? %>
+| <%= link_to t('user.view.create_block'), :controller => 'user_blocks', :action => 'new', :display_name => @this_user.display_name %>
+<% end %>
+<% end %>
+<% if @user and @user.administrator? %>
+<br/>
+<% if @this_user.active? %>
+<%= link_to t('user.view.deactivate_user'), {:controller => 'user', :action => 'deactivate', :display_name => @this_user.display_name}, {:confirm => t('user.view.confirm')} %>
+<% else %>
+<%= link_to t('user.view.activate_user'), {:controller => 'user', :action => 'activate', :display_name => @this_user.display_name}, {:confirm => t('user.view.confirm')} %>
+<% end %>
+<% if @this_user.visible? %>
+| <%= link_to t('user.view.hide_user'), {:controller => 'user', :action => 'hide', :display_name => @this_user.display_name}, {:confirm => t('user.view.confirm')} %>
+| <%= link_to t('user.view.delete_user'), {:controller => 'user', :action => 'delete', :display_name => @this_user.display_name}, {:confirm => t('user.view.confirm')} %>
+<% else %>
+| <%= link_to t('user.view.unhide_user'), {:controller => 'user', :action => 'unhide', :display_name => @this_user.display_name}, {:confirm => t('user.view.confirm')} %>
+<% end %>
 <% end %>
 </div>
 
-<% if @this_user != nil %>
-<P>
-<b><%= t 'user.view.mapper since' %></b><%= l @this_user.creation_time %> <%= t 'user.view.ago', :time_in_words_ago => time_ago_in_words(@this_user.creation_time) %>
-</P>
+<p><b><%= t 'user.view.mapper since' %></b> <%= l @this_user.creation_time %> <%= t 'user.view.ago', :time_in_words_ago => time_ago_in_words(@this_user.creation_time) %></p>
+
+<% if @user and @user.administrator? %>
+<p><b><%= t 'user.view.email address' %></b> <%= @this_user.email %></p>  
+<p><b><%= t 'user.view.created from' %></b> <%= @this_user.creation_ip %></p>
 <% end %>
-  
+
 <h3><%= t 'user.view.user image heading' %></h3>
 <% if @this_user.image %>
   <%= image_tag url_for_file_column(@this_user, "image") %>
 <br/>
 <% if @user and @this_user.id == @user.id %>
 <%= link_to t('user.view.change your settings'), :controller => 'user', :action => 'account', :display_name => @user.display_name %>
+<br/><br/>
+<%= link_to t('user.view.my_oauth_details'), :controller => 'oauth_clients', :action => 'index' %>
 <% end %>
diff --git a/app/views/user_blocks/_block.html.erb b/app/views/user_blocks/_block.html.erb
new file mode 100644 (file)
index 0000000..0e2b3a2
--- /dev/null
@@ -0,0 +1,24 @@
+<tr>
+  <% c1 = cycle('table0', 'table1') %>
+
+  <% if show_user_name %>
+  <td class="<%= c1 %>"><%= link_to h(block.user.display_name), :controller => 'user', :action => 'view', :display_name => block.user.display_name %></td>
+  <% end %>
+  <% if show_creator_name %>
+  <td class="<%= c1 %>"><%= link_to h(block.creator.display_name), :controller => 'user', :action => 'view', :display_name => block.creator.display_name %></td>
+  <% end %>
+  <td class="<%= c1 %>"><%=h truncate(block.reason) %></td>
+  <td class="<%= c1 %>"><%=h block_status(block) %></td>
+  <td class="<%= c1 %>">
+    <% if block.revoker_id.nil? %>
+      <%= t('user_block.partial.not_revoked') %>
+    <% else %>
+      <%= link_to h(block.revoker.display_name), :controller => 'user', :action => 'view', :display_name => block.revoker.display_name %>
+    <% end %>
+  </td>
+  <td class="<%= c1 %>"><%= link_to t('user_block.partial.show'), block %></td>
+  <td class="<%= c1 %>"><% if @user and @user.id == block.creator_id and block.active? %><%= link_to t('user_block.partial.edit'), edit_user_block_path(block) %><% end %></td>
+  <% if show_revoke_link %>
+  <td class="<%= c1 %>"><% if block.active? %><%= link_to t('user_block.partial.revoke'), block, :confirm => t('user_block.partial.confirm'), :action => :revoke %><% end %></td>
+  <% end %>
+</tr>
diff --git a/app/views/user_blocks/_blocks.html.erb b/app/views/user_blocks/_blocks.html.erb
new file mode 100644 (file)
index 0000000..7127cc2
--- /dev/null
@@ -0,0 +1,19 @@
+<table id="block_list" cellpadding="3">
+  <tr>
+    <% if show_user_name %>
+    <th><%= t'user_block.partial.display_name' %></th>
+    <% end %>
+    <% if show_creator_name %>
+    <th><%= t'user_block.partial.creator_name' %></th>
+    <% end %>
+    <th><%= t'user_block.partial.reason' %></th>
+    <th><%= t'user_block.partial.status' %></th>
+    <th><%= t'user_block.partial.revoker_name' %></th>
+    <th></th>
+    <th></th>
+    <% if show_revoke_link %>
+    <th></th>
+    <% end %>
+  </tr>
+  <%= render :partial => 'block', :locals => {:show_revoke_link => show_revoke_link, :show_user_name => show_user_name, :show_creator_name => show_creator_name }, :collection => @user_blocks %>
+</table>
diff --git a/app/views/user_blocks/blocks_by.html.erb b/app/views/user_blocks/blocks_by.html.erb
new file mode 100644 (file)
index 0000000..c915853
--- /dev/null
@@ -0,0 +1,8 @@
+<% @title = t('user_block.blocks_by.title', :name => h(@this_user.display_name)) %>
+<h1><%= t('user_block.blocks_by.heading', :name => link_to(h(@this_user.display_name), {:controller => 'user', :action => 'view', :display_name => @this_user.display_name})) %></h1>
+
+<% unless @user_blocks.empty? %>
+<%= render :partial => 'blocks', :locals => { :show_revoke_link => (@user and @user.moderator?), :show_user_name => true, :show_creator_name => false } %>
+<% else %>
+<p><%= t "user_block.blocks_by.empty", :name => h(@this_user.display_name) %></p>
+<% end %>
diff --git a/app/views/user_blocks/blocks_on.html.erb b/app/views/user_blocks/blocks_on.html.erb
new file mode 100644 (file)
index 0000000..2074af4
--- /dev/null
@@ -0,0 +1,8 @@
+<% @title = t('user_block.blocks_on.title', :name => h(@this_user.display_name)) %>
+<h1><%= t('user_block.blocks_on.heading', :name => link_to(h(@this_user.display_name), {:controller => 'user', :action => 'view', :display_name => @this_user.display_name})) %></h1>
+
+<% unless @user_blocks.empty? %>
+<%= render :partial => 'blocks', :locals => { :show_revoke_link => (@user and @user.moderator?), :show_user_name => false, :show_creator_name => true } %>
+<% else %>
+<p><%= t "user_block.blocks_on.empty", :name => h(@this_user.display_name) %></p>
+<% end %>
diff --git a/app/views/user_blocks/edit.html.erb b/app/views/user_blocks/edit.html.erb
new file mode 100644 (file)
index 0000000..387335d
--- /dev/null
@@ -0,0 +1,28 @@
+<% @title = t 'user_block.edit.title', :name => h(@user_block.user.display_name) %>
+<h1><%= t('user_block.edit.title',
+          :name => link_to(
+                           h(@user_block.user.display_name),
+                           {:controller => 'user', :action => 'view', :display_name => @user_block.user.display_name})) %></h1>
+
+<% form_for(@user_block) do |f| %>
+  <%= f.error_messages %>
+
+  <p>
+    <%= f.label :reason, t('user_block.edit.reason', :name => h(@user_block.user.display_name)) %><br />
+    <%= f.text_area :reason, :cols => 80, :rows => 5 %>
+  </p>
+  <p>
+    <%= label_tag 'user_block_period', t('user_block.edit.period') %><br />
+    <%= select_tag('user_block_period', options_for_select(UserBlock::PERIODS.collect { |h| [t('user_block.period', :count => h), h.to_s] }, params[:user_block_period])) %>
+  </p>
+  <p>
+    <%= f.check_box :needs_view %>
+    <%= f.label :needs_view, t('user_block.edit.needs_view') %>
+  </p>
+  <p>
+    <%= f.submit t('user_block.edit.submit') %>
+  </p>
+<% end %>
+
+<%= link_to t('user_block.edit.show'), @user_block %> |
+<%= link_to t('user_block.edit.back'), user_blocks_path %>
diff --git a/app/views/user_blocks/index.html.erb b/app/views/user_blocks/index.html.erb
new file mode 100644 (file)
index 0000000..2baf91e
--- /dev/null
@@ -0,0 +1,8 @@
+<% @title = t('user_block.index.title') %>
+<h1><%= t('user_block.index.heading') %></h1>
+
+<% unless @user_blocks.empty? %>
+<%= render :partial => 'blocks', :locals => { :show_revoke_link => (@user and @user.moderator?), :show_user_name => true, :show_creator_name => true } %>
+<% else %>
+<p><%= t "user_block.index.empty" %></p>
+<% end %>
diff --git a/app/views/user_blocks/new.html.erb b/app/views/user_blocks/new.html.erb
new file mode 100644 (file)
index 0000000..3d3e685
--- /dev/null
@@ -0,0 +1,28 @@
+<% @title = t 'user_block.new.title', :name => h(@this_user.display_name) %>
+<h1><%= t('user_block.new.heading',
+          :name => link_to(
+                           h(@this_user.display_name),
+                           {:controller => 'user', :action => 'view', :display_name => @this_user.display_name})) %></h1>
+
+<% form_for(@user_block) do |f| %>
+  <%= f.error_messages %>
+
+  <p>
+    <%= f.label :reason, t('user_block.new.reason', :name => @this_user.display_name) %><br />
+    <%= f.text_area :reason, :cols => 80, :rows => 5 %>
+  </p>
+  <p>
+    <%= label_tag 'user_block_period', t('user_block.new.period') %><br />
+    <%= select_tag('user_block_period', options_for_select(UserBlock::PERIODS.collect { |h| [t('user_block.period', :count => h), h.to_s] }, params[:user_block_period] )) %>
+  </p>
+  <p>
+    <%= f.check_box :needs_view %>
+    <%= f.label :needs_view, t('user_block.new.needs_view') %>
+  </p>
+  <p>
+    <%= hidden_field_tag 'display_name', @this_user.display_name %>
+    <%= f.submit t('user_block.new.submit') %>
+  </p>
+<% end %>
+
+<%= link_to t('user_block.new.back'), user_blocks_path %>
diff --git a/app/views/user_blocks/not_found.html.erb b/app/views/user_blocks/not_found.html.erb
new file mode 100644 (file)
index 0000000..3b5323d
--- /dev/null
@@ -0,0 +1,3 @@
+<p><%= t'user_block.not_found.sorry', :id => params[:id] %></p>
+
+<%= link_to t('user_block.not_found.back'), user_blocks_path %>
diff --git a/app/views/user_blocks/revoke.html.erb b/app/views/user_blocks/revoke.html.erb
new file mode 100644 (file)
index 0000000..9f142c8
--- /dev/null
@@ -0,0 +1,32 @@
+<% @title = t('user_block.revoke.title',
+              :block_on => h(@user_block.user.display_name),
+              :block_by => h(@user_block.creator.display_name)) %>
+<h1><%= t('user_block.revoke.heading',
+          :block_on => link_to(
+                               h(@user_block.user.display_name),
+                               {:controller => 'user', :action => 'view', :display_name => @user_block.user.display_name}),
+          :block_by => link_to(
+                               h(@user_block.creator.display_name),
+                               {:controller => 'user', :action => 'view', :display_name => @user_block.creator.display_name})) %></h1>
+
+<% if @user_block.ends_at > Time.now %>
+<p><b>
+  <%= t('user_block.revoke.time_future', :time => distance_of_time_in_words_to_now(@user_block.ends_at)) %>
+</b></p>
+
+<% form_for :revoke, :url => { :action => "revoke" } do |f| %>
+  <%= f.error_messages %>
+<p>  
+  <%= check_box_tag 'confirm', 'yes' %>
+  <%= label_tag 'confirm', t('user_block.revoke.confirm') %>
+</p>
+<p>
+  <%= submit_tag t('user_block.revoke.revoke') %>
+</p>
+<% end %>
+
+<% else %>
+<p>
+  <%= t('user_block.revoke.past', :time => distance_of_time_in_words_to_now(@user_block.ends_at)) %>
+</p>
+<% end %>
diff --git a/app/views/user_blocks/show.html.erb b/app/views/user_blocks/show.html.erb
new file mode 100644 (file)
index 0000000..24a1d1e
--- /dev/null
@@ -0,0 +1,34 @@
+<% @title = t('user_block.show.title',
+              :block_on => @user_block.user.display_name,
+              :block_by => @user_block.creator.display_name) %>
+<h1><%= t('user_block.show.heading',
+          :block_on => link_to(
+                               h(@user_block.user.display_name),
+                               {:controller => 'user', :action => 'view', :display_name => @user_block.user.display_name}),
+          :block_by => link_to(
+                               h(@user_block.creator.display_name),
+                               {:controller => 'user', :action => 'view', :display_name => @user_block.creator.display_name})) %></h1>
+<% if @user_block.revoker %>
+<p>
+  <b><%= t'user_block.show.revoker' %></b>
+  <%= link_to h(@user_block.revoker.display_name), :controller => 'user', :action => 'view', :display_name => @user_block.revoker.display_name %>
+</p>
+<% end %>
+
+<p><b><%= t'user_block.show.status' %></b>: <%= block_status(@user_block) %></p>
+
+<p>
+  <b><%= t'user_block.show.reason' %></b>
+  <%=h @user_block.reason %>
+</p>
+
+
+<% if @user_block.ends_at > Time.now.getutc %>
+<% if @user and @user.id == @user_block.creator_id %>
+<%= link_to t('user_block.show.edit'), edit_user_block_path(@user_block) %> |
+<% end %>
+<% if @user and @user.moderator? %>
+<%= link_to(t('user_block.show.revoke'),{:controller => 'user_blocks', :action => 'revoke', :id => @user_block.id}) %> |
+<% end %>
+<% end %>
+<%= link_to t('user_block.show.back'), user_blocks_path %>
diff --git a/app/views/user_roles/grant.html.erb b/app/views/user_roles/grant.html.erb
new file mode 100644 (file)
index 0000000..cee4112
--- /dev/null
@@ -0,0 +1,7 @@
+<% form_tag request.request_uri do %>
+<%= hidden_field_tag 'nonce', @nonce %>
+<% @title = t('user_role.grant.heading') %>
+<h1><%= t('user_role.grant.heading') %></h1>
+<p><%= t('user_role.grant.are_you_sure', :name => params[:display_name], :role => params[:role]) %></p>
+<p><%= submit_tag t('user_role.grant.confirm') %></p>
+<% end %>
diff --git a/app/views/user_roles/revoke.html.erb b/app/views/user_roles/revoke.html.erb
new file mode 100644 (file)
index 0000000..e5aadea
--- /dev/null
@@ -0,0 +1,7 @@
+<% form_tag request.request_uri do %>
+<%= hidden_field_tag 'nonce', @nonce %>
+<% @title = t('user_role.revoke.heading') %>
+<h1><%= t('user_role.revoke.heading') %></h1>
+<p><%= t('user_role.revoke.are_you_sure', :name => params[:display_name], :role => params[:role]) %></p>
+<p><%= submit_tag t'user_role.revoke.confirm' %></p>
+<% end %>
index 6241fb621f5379ddda1c1dbce1c83b3ea7d5c301..6a67a51236af20f3c1a9fe234513a54553e360fb 100644 (file)
@@ -13,6 +13,8 @@ standard_settings: &standard_settings
   geonames_zoom: 12
   # Timeout for API calls in seconds
   api_timeout: 300
+  # Periods (in hours) which are allowed for user blocks
+  user_block_periods: [0, 1, 3, 6, 12, 24, 48, 96]
  
 development:
   <<: *standard_settings
index c7fa3c483ea0ca64964edd71d03c09f12024232f..12a8b542404319b3e56a6da7ba62f9e164d947bf 100644 (file)
@@ -5,7 +5,7 @@
 ENV['RAILS_ENV'] ||= 'production'
 
 # Specifies gem version of Rails to use when vendor/rails is not present
-RAILS_GEM_VERSION = '2.3.2' unless defined? RAILS_GEM_VERSION
+RAILS_GEM_VERSION = '2.3.4' unless defined? RAILS_GEM_VERSION
 
 # Set the server URL
 SERVER_URL = ENV['OSM_SERVER_URL'] || 'www.openstreetmap.org'
@@ -49,6 +49,9 @@ Rails::Initializer.run do |config|
   config.gem 'composite_primary_keys', :version => '2.2.2'
   config.gem 'libxml-ruby', :version => '>= 1.1.1', :lib => 'libxml'
   config.gem 'rmagick', :lib => 'RMagick'
+  # note: this should be changed to 0.3.6 as soon as it's released, as this has fixes for
+  # uploading multipart documents.
+  config.gem 'oauth', :version => '>=0.2.1'
 
   # Only load the plugins named here, in the order given. By default, all plugins 
   # in vendor/plugins are loaded in alphabetical order.
index df0a8329a02dcdbaf98d19c39bbd7d12618374f1..df539c9722b3d91906fcf3089f68040df7c9d116 100644 (file)
-aa:
+aa: 
   english: Afar
   native: Afaraf
-
-ab:
+ab: 
   english: Abkhazian
   native: Аҧсуа
-
-ae:
+ae: 
   english: Avestan
   native: avesta
-
-af:
+af: 
   english: Afrikaans
   native: Afrikaans
-
-ak:
+ak: 
   english: Akan
   native: Akan
-
-am:
+am: 
   english: Amharic
   native: አማርኛ
-
-an:
+an: 
   english: Aragonese
   native: Aragonés
-
-ar:
+ar: 
   english: Arabic
   native: العربية
-
-as:
+as: 
   english: Assamese
   native: অসমীয়া
-
-av:
+av: 
   english: Avaric
-  native: авар мацӀ; магӀарул мацӀ
-
-ay:
+  native: Авар
+ay: 
   english: Aymara
-  native: aymar aru
-
-az:
+  native: Aymar aru
+az: 
   english: Azerbaijani
-  native: azərbaycan dili
-
-ba:
+  native: Azərbaycan
+ba: 
   english: Bashkir
-  native: башҡорт теле
-
-be:
+  native: Башҡорт
+be: 
   english: Belarusian
   native: Беларуская
-
-bg:
+bg: 
   english: Bulgarian
-  native: български език
-
-bh:
+  native: Български
+bh: 
   english: Bihari
   native: भोजपुरी
-
-bi:
+bi: 
   english: Bislama
   native: Bislama
-
-bm:
+bm: 
   english: Bambara
-  native: bamanankan
-
-bn:
+  native: Bamanankan
+bn: 
   english: Bengali
   native: বাংলা
-
-bo:
+bo: 
   english: Tibetan
   native: བོད་ཡིག
-
-br:
+br: 
   english: Breton
-  native: brezhoneg
-
-bs:
+  native: Brezhoneg
+bs: 
   english: Bosnian
-  native: bosanski jezik
-
-ca:
+  native: Bosanski
+ca: 
   english: Catalan
   native: Català
-
-ce:
+ce: 
   english: Chechen
-  native: нохчийн мотт
-
-ch:
+  native: Нохчийн
+ch: 
   english: Chamorro
   native: Chamoru
-
-co:
+co: 
   english: Corsican
-  native: corsu; lingua corsa
-
-cr:
+  native: Corsu
+cr: 
   english: Cree
   native: ᓀᐦᐃᔭᐍᐏᐣ
-
-cs:
+cs: 
   english: Czech
-  native: česky; čeština
-
-cu:
+  native: Česky
+cu: 
   english: Church Slavic
-  native: ѩзыкъ словѣньскъ
-
-cv:
+  native: Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ
+cv: 
   english: Chuvash
-  native: чӑваш чӗлхи
-
-cy:
+  native: Чӑвашла
+cy: 
   english: Welsh
   native: Cymraeg
-
-da:
+da: 
   english: Danish
-  native: dansk
-
-de:
+  native: Dansk
+de: 
   english: German
   native: Deutsch
-
-dv:
+dv: 
   english: Divehi
-  native: ދިވެހި
-
-dz:
+  native: ދިވެހިބަސް
+dz: 
   english: Dzongkha
-  native: རྫོང་ཁ
-
-ee:
+  native: ཇོང་ཁ
+ee: 
   english: Ewe
-  native: Ɛʋɛgbɛ
-
-el:
+  native: Eʋegbe
+el: 
   english: Greek
   native: Ελληνικά
-
-en:
+en: 
   english: English
   native: English
-
-eo:
+eo: 
   english: Esperanto
   native: Esperanto
-
-es:
+es: 
   english: Spanish
-  native: Español; castellano
-
-et:
+  native: Español
+et: 
   english: Estonian
-  native: eesti; eesti keel
-
-eu:
+  native: Eesti
+eu: 
   english: Basque
-  native: euskara; euskera
-
-fa:
+  native: Euskara
+fa: 
   english: Persian
   native: فارسی
-
-ff:
+ff: 
   english: Fulah
   native: Fulfulde
-
-fi:
+fi: 
   english: Finnish
-  native: suomi; suomen kieli
-
-fj:
+  native: Suomi
+fj: 
   english: Fijian
-  native: vosa Vakaviti
-
-fo:
+  native: Na Vosa Vakaviti
+fo: 
   english: Faroese
   native: Føroyskt
-
-fr:
+fr: 
   english: French
-  native: Français; langue française
-
-fy:
+  native: Français
+fy: 
   english: Western Frisian
   native: Frysk
-
-ga:
+ga: 
   english: Irish
   native: Gaeilge
-
-gd:
+gd: 
   english: Scottish Gaelic
   native: Gàidhlig
-
-gl:
+gl: 
   english: Galician
   native: Galego
-
-gn:
-  english: Guaraní
+gn: 
+  english: Guarani
   native: Avañe'ẽ
-
-gu:
+gsw: 
+  english: Swiss German
+  native: Alemannisch
+gu: 
   english: Gujarati
   native: ગુજરાતી
-
-gv:
+gv: 
   english: Manx
-  native: Gaelg; Gailck
-
-ha:
+  native: Gaelg
+ha: 
   english: Hausa
   native: هَوُسَ
-
-he:
+he: 
   english: Hebrew
   native: עברית
-
-hi:
+hi: 
   english: Hindi
-  native: हिन्दी; हिंदी
-
-ho:
+  native: हिन्दी
+ho: 
   english: Hiri Motu
   native: Hiri Motu
-
-hr:
+hr: 
   english: Croatian
   native: Hrvatski
-
-ht:
+hsb: 
+  english: Upper Sorbian
+  native: Hornjoserbsce
+ht: 
   english: Haitian
   native: Kreyòl ayisyen
-
-hu:
+hu: 
   english: Hungarian
   native: Magyar
-
-hy:
+hy: 
   english: Armenian
   native: Հայերեն
-
-hz:
+hz: 
   english: Herero
   native: Otjiherero
-
-ia:
-  english: Interlingua (International Auxiliary Language Association)
+ia: 
+  english: Interlingua
   native: Interlingua
-
-id:
+id: 
   english: Indonesian
   native: Bahasa Indonesia
-
-ie:
+ie: 
   english: Interlingue
   native: Interlingue
-
-ig:
+ig: 
   english: Igbo
   native: Igbo
-
-ii:
+ii: 
   english: Sichuan Yi
   native: ꆇꉙ
-
-ik:
+ik: 
   english: Inupiaq
-  native: Iñupiaq; Iñupiatun
-
-io:
+  native: Iñupiak
+io: 
   english: Ido
   native: Ido
-
-is:
+is: 
   english: Icelandic
   native: Íslenska
-
-it:
+it: 
   english: Italian
   native: Italiano
-
-iu:
+iu: 
   english: Inuktitut
-  native: ᐃᓄᒃᑎᑐᑦ
-
-ja:
+  native: ᐃᓄᒃᑎᑐᑦ/inuktitut
+ja: 
   english: Japanese
-  native: 日本語 (にほんご/にっぽんご)
-
-jv:
+  native: 日本語
+jv: 
   english: Javanese
-  native: basa Jawa
-
-ka:
+  native: Basa Jawa
+ka: 
   english: Georgian
   native: ქართული
-
-kg:
+kg: 
   english: Kongo
-  native: KiKongo
-
-ki:
+  native: Kongo
+ki: 
   english: Kikuyu
   native: Gĩkũyũ
-
-kj:
+kj: 
   english: Kwanyama
   native: Kuanyama
-
-kk:
+kk: 
   english: Kazakh
-  native: Қазақ тілі
-
-kl:
+  native: Қазақша
+kl: 
   english: Kalaallisut
-  native: kalaallisut; kalaallit oqaasii
-
-km:
+  native: Kalaallisut
+km: 
   english: Khmer
   native: ភាសាខ្មែរ
-
-kn:
+kn: 
   english: Kannada
   native: ಕನ್ನಡ
-
-ko:
+ko: 
   english: Korean
-  native: 한국어 (韓國語); 조선말 (朝鮮語)
-
-kr:
+  native: 한국어
+kr: 
   english: Kanuri
   native: Kanuri
-
-ks:
+ks: 
   english: Kashmiri
-  native: कश्मीरी; كشميري‎
-
-ku:
+  native: (كشميري)
+ksh: 
+  english: Ripoarisch
+  native: Ripoarisch
+ku: 
   english: Kurdish
-  native: Kurdî; كوردی‎
-
-kv:
+  native: Kurdî / كوردی
+kv: 
   english: Komi
-  native: коми кыв
-
-kw:
+  native: Коми
+kw: 
   english: Cornish
-  native: Kernewek
-
-ky:
+  native: Kernowek
+ky: 
   english: Kirghiz
-  native: кыргыз тили
-
-la:
+  native: Кыргызча
+la: 
   english: Latin
-  native: latine; lingua latina
-
-lb:
+  native: Latina
+lb: 
   english: Luxembourgish
   native: Lëtzebuergesch
-
-lg:
+lg: 
   english: Ganda
   native: Luganda
-
-li:
+li: 
   english: Limburgish
   native: Limburgs
-
-ln:
+ln: 
   english: Lingala
   native: Lingála
-
-lo:
+lo: 
   english: Lao
-  native: ພາສາລາວ
-
-lt:
+  native: ລາວ
+lt: 
   english: Lithuanian
-  native: lietuvių kalba
-
-lu:
+  native: Lietuvių
+lu: 
   english: Luba-Katanga
-  native: 
-
-lv:
+  native: ~
+lv: 
   english: Latvian
-  native: latviešu valoda
-
-mg:
+  native: Latviešu
+mg: 
   english: Malagasy
-  native: Malagasy fiteny
-
-mh:
+  native: Malagasy
+mh: 
   english: Marshallese
   native: Kajin M̧ajeļ
-
-mi:
-  english: Māori
-  native: te reo Māori
-
-mk:
+mi: 
+  english: Maori
+  native: Māori
+mk: 
   english: Macedonian
-  native: македонски јазик
-
-ml:
+  native: Македонски
+ml: 
   english: Malayalam
   native: മലയാളം
-
-mn:
+mn: 
   english: Mongolian
   native: Монгол
-
-mr:
+mo: 
+  english: Moldavian
+  native: Молдовеняскэ
+mr: 
   english: Marathi
   native: मराठी
-
-ms:
+ms: 
   english: Malay
-  native: bahasa Melayu; بهاس ملايو‎
-
-mt:
+  native: Bahasa Melayu
+mt: 
   english: Maltese
   native: Malti
-
-my:
+my: 
   english: Burmese
-  native: ဗမာစာ
-
-na:
+  native: မြန်မာဘာသာ
+na: 
   english: Nauru
-  native: Ekakairũ Naoero
-
-nb:
+  native: Dorerin Naoero
+nb: 
   english: Norwegian Bokmål
-  native: Norsk bokmål
-
-nd:
+  native: ‪Norsk (bokmål)‬
+nd: 
   english: North Ndebele
   native: isiNdebele
-
-ne:
+nds: 
+  english: Low German
+  native: Plattdüütsch
+ne: 
   english: Nepali
   native: नेपाली
-
-ng:
+ng: 
   english: Ndonga
   native: Owambo
-
-nl:
+nl: 
   english: Dutch
   native: Nederlands
-
-nn:
+nn: 
   english: Norwegian Nynorsk
-  native: Norsk nynorsk
-
-no:
-  english: Norwegian
-  native: Norsk
-
-nr:
+  native: ‪Norsk (nynorsk)‬
+"no": 
+  english: Norwegian (bokmål)‬
+  native: ‪Norsk (bokmål)‬
+nr: 
   english: South Ndebele
   native: isiNdebele
-
-nv:
+nv: 
   english: Navajo
-  native: Diné bizaad; Dinékʼehǰí
-
-ny:
-  english: Chichewa
-  native: chiCheŵa; chinyanja
-
-oc:
+  native: Diné bizaad
+ny: 
+  english: Nyanja
+  native: Chi-Chewa
+oc: 
   english: Occitan
   native: Occitan
-
-oj:
+oj: 
   english: Ojibwa
   native: ᐊᓂᔑᓈᐯᒧᐎᓐ
-
-om:
+om: 
   english: Oromo
-  native: Afaan Oromoo
-
-or:
+  native: Oromoo
+or: 
   english: Oriya
   native: ଓଡ଼ିଆ
-
-os:
-  english: Ossetian
-  native: Ирон æвзаг
-
-pa:
-  english: Panjabi
-  native: ਪੰਜਾਬੀ; پنجابی‎
-
-pi:
-  english: Pāli
-  native: पाऴि
-
-pl:
+os: 
+  english: Ossetic
+  native: Иронау
+pa: 
+  english: Punjabi
+  native: ਪੰਜਾਬੀ
+pi: 
+  english: Pali
+  native: पािऴ
+pl: 
   english: Polish
-  native: polski
-
-ps:
+  native: Polski
+ps: 
   english: Pashto
   native: پښتو
-
-pt:
+pt: 
   english: Portuguese
   native: Português
-
-qu:
+pt-BR: 
+  english: Brazilian Portuguese
+  native: Português do Brasil
+qu: 
   english: Quechua
-  native: Runa Simi; Kichwa
-
-rm:
-  english: Raeto-Romance
-  native: rumantsch grischun
-
-rn:
+  native: Runa Simi
+rm: 
+  english: Rhaeto-Romance
+  native: Rumantsch
+rn: 
   english: Kirundi
   native: kiRundi
-
-ro:
+ro: 
   english: Romanian
-  native: română
-
-ru:
+  native: Română
+ru: 
   english: Russian
-  native: русский язык
-
-rw:
+  native: Русский
+rw: 
   english: Kinyarwanda
   native: Ikinyarwanda
-
-sa:
+sa: 
   english: Sanskrit
-  native: संस्कृतम्
-
-sc:
+  native: संस्कृत
+sc: 
   english: Sardinian
-  native: sardu
-
-sd:
+  native: Sardu
+sd: 
   english: Sindhi
-  native: सिन्धी; سنڌي، سندھی‎
-
-se:
+  native: سنڌي
+se: 
   english: Northern Sami
-  native: Davvisámegiella
-
-sg:
+  native: Sámegiella
+sg: 
   english: Sango
-  native: yângâ tî sängö
-
-si:
+  native: Sängö
+sh: 
+  english: Serbo-Croatian
+  native: Srpskohrvatski / Српскохрватски
+si: 
   english: Sinhala
   native: සිංහල
-
-sk:
+sk: 
   english: Slovak
-  native: slovenčina
-
-sl:
+  native: Slovenčina
+sl: 
   english: Slovenian
-  native: slovenščina
-
-sm:
+  native: Slovenščina
+sm: 
   english: Samoan
-  native: gagana fa'a Samoa
-
-sn:
+  native: Gagana Samoa
+sn: 
   english: Shona
   native: chiShona
-
-so:
+so: 
   english: Somali
-  native: Soomaaliga; af Soomaali
-
-sq:
+  native: Soomaaliga
+sq: 
   english: Albanian
   native: Shqip
-
-sr:
+sr: 
   english: Serbian
-  native: српски језик
-
-ss:
+  native: Српски / Srpski
+sr-EC: 
+  english: Serbian Cyrillic ekavian
+  native: Српски (ћирилица)
+ss: 
   english: Swati
   native: SiSwati
-
-st:
+st: 
   english: Southern Sotho
   native: Sesotho
-
-su:
+su: 
   english: Sundanese
   native: Basa Sunda
-
-sv:
+sv: 
   english: Swedish
-  native: svenska
-
-sw:
+  native: Svenska
+sw: 
   english: Swahili
   native: Kiswahili
-
-ta:
+ta: 
   english: Tamil
   native: தமிழ்
-
-te:
+te: 
   english: Telugu
   native: తెలుగు
-
-tg:
+tg: 
   english: Tajik
-  native: тоҷикӣ; toğikī; تاجیکی‎
-
-th:
+  native: Тоҷикӣ
+th: 
   english: Thai
   native: ไทย
-
-ti:
+ti: 
   english: Tigrinya
   native: ትግርኛ
-
-tk:
+tk: 
   english: Turkmen
-  native: Türkmen; Түркмен
-
-tl:
+  native: Türkmençe
+tl: 
   english: Tagalog
   native: Tagalog
-
-tn:
+tn: 
   english: Tswana
   native: Setswana
-
-to:
+to: 
   english: Tonga
-  native: faka Tonga
-
-tr:
+  native: lea faka-Tonga
+tr: 
   english: Turkish
   native: Türkçe
-
-ts:
+ts: 
   english: Tsonga
   native: Xitsonga
-
-tt:
+tt: 
   english: Tatar
-  native: татарча; tatarça; تاتارچا‎
-
-tw:
+  native: Татарча/Tatarça
+tw: 
   english: Twi
   native: Twi
-
-ty:
+ty: 
   english: Tahitian
   native: Reo Mā`ohi
-
-ug:
+ug: 
   english: Uighur
-  native: Uyƣurqə; ئۇيغۇرچە‎
-
-uk:
+  native: Uyghurche‎ / ئۇيغۇرچە
+uk: 
   english: Ukrainian
   native: Українська
-
-ur:
+ur: 
   english: Urdu
   native: اردو
-
-uz:
+uz: 
   english: Uzbek
-  native: O'zbek; Ўзбек; أۇزبېك‎
-
-ve:
+  native: O'zbek
+ve: 
   english: Venda
-  native: Tshivenḓa
-
-vi:
+  native: Tshivenda
+vi: 
   english: Vietnamese
   native: Tiếng Việt
-
-vo:
+vo: 
   english: Volapük
   native: Volapük
-
-wa:
+wa: 
   english: Walloon
   native: Walon
-
-wo:
+wo: 
   english: Wolof
-  native: Wollof
-
-xh:
+  native: Wolof
+xh: 
   english: Xhosa
   native: isiXhosa
-
-yi:
+yi: 
   english: Yiddish
   native: ייִדיש
-
-yo:
+yo: 
   english: Yoruba
   native: Yorùbá
-
-za:
+za: 
   english: Zhuang
-  native: Saɯ cueŋƅ; Saw cuengh
-
-zh:
+  native: Vahcuengh
+zh: 
   english: Chinese
-  native: 中文 (Zhōngwén), 汉语, 漢語
-
-zu:
+  native: 中文
+zh-CN: 
+  english: Chinese (China)
+  native: ‪中文(中国大陆)‬
+zh-TW: 
+  english: Chinese (Taiwan)
+  native: ‪中文(台灣)‬
+zu: 
   english: Zulu
   native: isiZulu
diff --git a/config/locales/af.yml b/config/locales/af.yml
new file mode 100644 (file)
index 0000000..5e8bae1
--- /dev/null
@@ -0,0 +1,810 @@
+# Messages for Afrikaans (Afrikaans)
+# Exported from translatewiki.net
+# Export driver: syck
+# Author: Firefishy
+# Author: Naudefj
+# Author: Nroets
+af: 
+  activerecord: 
+    attributes: 
+      diary_comment: 
+        body: Teks
+      diary_entry: 
+        language: Taal
+        latitude: Breedtegraad
+        longitude: Lengtegraad
+        title: Titel
+        user: Gebruiker
+      friend: 
+        friend: Vriend
+        user: Gebruiker
+      message: 
+        body: Teks
+        recipient: Ontvanger
+        sender: Afsender
+        title: Titel
+      trace: 
+        description: Beskrywing
+        latitude: Breedtegraad
+        longitude: Lengtegraad
+        name: Naam
+        public: Openbaar
+        size: Grootte
+        user: Gebruiker
+        visible: Sigbaar
+      user: 
+        active: Aktief
+        description: Beskrywing
+        display_name: Vertoon Naam
+        email: E-pos
+        languages: Tale
+        pass_crypt: Wagwoord
+    models: 
+      acl: Toegangsbeheer
+      changeset: Stel wysigings
+      country: Land
+      diary_comment: Dagboekopmerking
+      diary_entry: Dagboekinskrywing
+      friend: Vriend
+      language: Taal
+      message: Boodskap
+      node: Node
+      notifier: Melding
+      old_node: Ou Node
+      session: Sessie
+      trace: Spoor
+      user: Gebruiker
+      user_preference: Gebruikersvoorkeure
+      way: Weg
+  browse: 
+    changeset_details: 
+      belongs_to: "Behoort aan:"
+      bounding_box: "Seleksieboks:"
+      box: boks
+      closed_at: "Gesluit op:"
+      created_at: "Geskep op:"
+      has_nodes: 
+        one: "Het die volgende node:"
+        other: "Het die volgende {{count}} nodes:"
+      show_area_box: Wys gebied
+    changeset_navigation: 
+      all: 
+        next_tooltip: Volgende stel wysigings
+        prev_tooltip: Vorige stel wysigings
+      user: 
+        name_tooltip: Wys wysigings deur {{user}}
+        next_tooltip: Volgende wysiging deur {{user}}
+        prev_tooltip: Vorige wysiging deur {{user}}
+    common_details: 
+      changeset_comment: "Opmerking:"
+      edited_at: "Gewysig op:"
+      edited_by: "Opgedateer deur:"
+      version: "Weergawe:"
+    containing_relation: 
+      entry: Relasie {{relation_name}}
+      entry_role: Relasie {{relation_name}} (as {{relation_role}})
+    map: 
+      deleted: Uitgevee
+      larger: 
+        area: Besigtig area op groter kaart
+        node: Besigtig node op groter kaart
+        relation: Besigtig relasie op groter kaart
+        way: Besigtig weg op groter kaart
+      loading: Besig om af te laai...
+    node: 
+      download: "{{download_xml_link}}, {{view_history_link}} of {{edit_link}}"
+      download_xml: Laai XML af
+      edit: wysig
+      node: Node
+      node_title: "Node: {{node_name}}"
+      view_history: wys geskiedenis
+    node_details: 
+      coordinates: "Koördinate:"
+      part_of: "Deel af:"
+    node_history: 
+      download: "{{download_xml_link}} of {{view_details_link}}"
+      download_xml: Laai XML af
+      node_history: Nodegeskiedenis
+      node_history_title: "Nodegeskiedenis: {{node_name}}"
+      view_details: besigtig besonderhede
+    not_found: 
+      sorry: Jammer, {{type}} {{id}} kan nie gevind word nie.
+      type: 
+        changeset: Veranderingstel
+        node: node
+        relation: relasie
+        way: weg
+    paging_nav: 
+      of: van
+      showing_page: Bladsy
+    relation: 
+      download: "{{download_xml_link}} of {{view_history_link}}"
+      download_xml: Laai XML af
+      view_history: wys geskiedenis
+    relation_details: 
+      members: "Lede:"
+      part_of: "Deel van:"
+    relation_history: 
+      download: "{{download_xml_link}} of {{view_details_link}}"
+      download_xml: Laai XML af
+      relation_history: Relasiegeskiedenis
+      relation_history_title: "Relasie Geskiedenis: {{relation_name}}"
+      view_details: besigtig besonderhede
+    relation_member: 
+      entry_role: "{{type}} {{name}} as {{role}}"
+      type: 
+        node: Node
+        relation: Relasie
+        way: Weg
+    start: 
+      manually_select: Kies 'n ander gebied handmatig
+      view_data: Wys data vir die huidige kaart
+    start_rjs: 
+      data_frame_title: Gegewens
+      data_layer_name: Data
+      details: Details
+      drag_a_box: Trek 'n boks op die kaart om 'n gebied te kies
+      edited_by_user_at_timestamp: Verander deur [[user]] om [[timestamp]]
+      history_for_feature: Geskiedenis van [[feature]]
+      load_data: Laai data
+      loaded_an_area_with_num_features: Hierdie area het [[num_features]] items. Party webblaaiers mag stadig raak wanneer hulle om soveel data te vertoon. Om nietemin aan te gaan, kies die skakel hier onder.
+      loading: Laai...
+      manually_select: Kies 'n ander gebied handmatig
+      object_list: 
+        api: Verkry die data van hierdie gebied
+        back: Vertoon objeklys
+        details: Besonderhede
+        heading: Objeklys
+        history: 
+          type: 
+            node: Node [[id]]
+            way: Weg [[id]]
+        selected: 
+          type: 
+            node: Node [[id]]
+            way: Weg [[id]]
+        type: 
+          node: Node
+          way: Weg
+      private_user: private gebruiker
+      show_history: Wys Geskiedenis
+      unable_to_load_size: Aflaai van data onmoontlik. Area van grootte [[bbox_size]] is te groot. Moet kleiner as {{max_bbox_size}} wees
+      wait: Wag asseblief...
+      zoom_or_select: Zoom in of kies 'n gebied op die kaart om te besigtig
+    tag_details: 
+      tags: "Etikette:"
+    way: 
+      download: "{{download_xml_link}} of {{view_history_link}}"
+      download_xml: Laai XML af
+      edit: wysig
+      view_history: besigtig geskiedenis
+      way: Weg
+      way_title: "Weg: {{way_name}}"
+    way_details: 
+      also_part_of: 
+        one: ook deel van weg {{related_ways}}
+        other: ook deel van weë {{related_ways}}
+      nodes: "Nodes:"
+      part_of: "Deel van:"
+    way_history: 
+      download: "{{download_xml_link}} of {{view_details_link}}"
+      download_xml: Laai XML af
+      view_details: besigtig besonderhede
+      way_history: Weggeskiedenis
+      way_history_title: "Weggeskiedenis: {{way_name}}"
+  changeset: 
+    changeset: 
+      anonymous: Anoniem
+      big_area: (groot)
+      no_comment: (geen)
+      no_edits: (geen wysigings)
+      still_editing: (steeds besig met wysiging)
+    changeset_paging_nav: 
+      of: van
+      showing_page: Wys bladsy
+    changesets: 
+      area: Gebied
+      comment: Opmerking
+      id: ID
+      saved_at: Gestoor op
+      user: Gebruiker
+    list: 
+      description: Onlangse wysigings
+  diary_entry: 
+    diary_comment: 
+      comment_from: Kommentaar van ((link_user)) op ((comment_created_at))
+    diary_entry: 
+      comment_count: 
+        one: 1 reaksie
+        other: "{{count}} reaksies"
+      comment_link: Lewer kommentaar op hierdie bydrae
+      edit_link: Wysig hierdie inskrywing
+      posted_by: Gepos deur {{link_user}} op {{created}} in die {{language_link}}
+      reply_link: Antwoord op hierdie bydrae
+    edit: 
+      body: "Teks:"
+      language: "Taal:"
+      latitude: "Breedtegraad:"
+      location: "Ligging:"
+      longitude: "Lengtegraad:"
+      marker_text: Ligging van dagboekinskrywing
+      save_button: Stoor
+      subject: "Onderwerp:"
+      title: Wysig dagboekinskrywing
+      use_map_link: gebruik kaart
+    feed: 
+      all: 
+        description: Onlangse dagboekinskrywings van OpenStreetMap-gebruikers
+        title: OpenStreetMap dagboekinskrywings
+      language: 
+        description: Onlangse dagboekinskrywings van OpenStreetMap-gebruikers in {{language_name}}
+        title: OpenStreetMap dagboekinskrywings in {{language_name}}
+      user: 
+        description: Onlangse OpenStreetMap dagboekinskrywings van {{user}}
+        title: OpenStreetMap dagboekinskrywings van {{user}}
+    list: 
+      in_language_title: Dagboekinkrywings in {{language}}
+      new: Nuwe dagboekinskrywing
+      new_title: Plaas nuwe artikel in u dagboek
+      newer_entries: Nuwer inskrywings
+      no_entries: Geen dagboekinskrywings nie
+      older_entries: Ouer inskrywings
+      recent_entries: "Onlangse dagboekinskrywings:"
+      title: Gebruikersdagboeke
+      user_title: Dagboek van {{user}}
+    new: 
+      title: Nuwe dagboekinskrywing
+    no_such_entry: 
+      body: Jammer, daar is geen dagboekinskrywing of kommentaar met die id {{id}} nie. Kontroleer u spelling, of miskien is die skakel waarop u gekliek het verkeerd.
+      heading: Die inskrywing met id {{id}} bestaan nie
+      title: Die opgevraagde dagboekinskrywing bestaan nie
+    no_such_user: 
+      body: Jammer, daar is geen gebruiker met die naam {{user}} nie. Kontroleer u spelling, of miskien is die skakel waarop u gekliek het verkeerd.
+      heading: Die gebruiker {{user}} bestaan nie
+      title: Geen sodanige gebruiker nie
+    view: 
+      leave_a_comment: Los opmerking agter
+      login: Teken in
+      login_to_leave_a_comment: U moet eers {{login_link}} alvorens u kommentaar kan lewer
+      save_button: Stoor
+      title: Gebruikersdagboeke | {{user}}
+      user_title: Dagboek van {{user}}
+  export: 
+    start: 
+      add_marker: Plaas 'n merker op die kaart
+      area_to_export: Area om te eksporteer
+      embeddable_html: HTML-kode
+      export_button: Eksporteer
+      export_details: OpenStreetMap se data is gelisensieer onder die <a href="http://creativecommons.org/licenses/by-sa/2.0/deed.af">Creative Commons Erkenning-Insgelyks Deel 2.0 lisensie</a>.
+      format: Formaat
+      format_to_export: Lêerformaat
+      image_size: Prentgrootte
+      latitude: "Breedte:"
+      licence: Lisensie
+      longitude: "Lengte:"
+      manually_select: Kies 'n ander gebied handmatig
+      max: max
+      options: Voorkeure
+      osm_xml_data: OpenStreetMap XML-data
+      output: Afvoer
+      scale: Skaal
+      zoom: Zoom
+    start_rjs: 
+      add_marker: Plaas 'n merker op die kaart
+      change_marker: Verander posisie van merker
+      click_add_marker: Kliek op die kaart om 'n merker te plaas
+      drag_a_box: Trek 'n boks op die kaart om 'n gebied te kies
+      export: Eksporteer
+      manually_select: Kies 'n ander gebied handmatig
+      view_larger_map: Wys groter kaart
+  geocoder: 
+    description: 
+      title: 
+        geonames: Ligging vanaf <a href="http://www.geonames.org/">GeoNames</a>
+        osm_namefinder: "{{types}} vanaf <a href=\"http://gazetteer.openstreetmap.org/namefinder/\">OpenStreetMap Namefinder</a>"
+      types: 
+        cities: Stede
+        places: Plekke
+        towns: Dorpe
+    description_osm_namefinder: 
+      prefix: "{{distance}} {{direction}} van {{type}}"
+    direction: 
+      east: oos
+      north: noord
+      north_east: noordoos
+      north_west: noordwes
+      south: suid
+      south_east: suid-oos
+      south_west: suidwes
+      west: wes
+    distance: 
+      one: ongeveer 1km
+      other: ongeveer {{count}}km
+      zero: minder as 1km
+    results: 
+      no_results: Geen resultate gevind nie
+    search: 
+      title: 
+        ca_postcode: Resultate vanaf <a href="http://geocoder.ca/">Geocoder.CA</a>
+        geonames: Resultate vanaf <a href="http://www.geonames.org/">GeoNames</a>
+        latlon: Resultate vanaf <a href="http://openstreetmap.org/">intern</a>
+        osm_namefinder: Resultate vanaf <a href="http://gazetteer.openstreetmap.org/namefinder/">OpenStreetMap Namefinder</a>
+        uk_postcode: Resultate vanaf <a href="http://www.npemap.org.uk/">NPEMap / FreeThe Postcode</a>
+        us_postcode: Resultate vanaf <a href="http://geocoder.us/">Geocoder.us</a>
+    search_osm_namefinder: 
+      suffix_parent: "{{suffix}} ({{parentdistance}} {{parentdirection}} van {{parentname}})"
+      suffix_place: ", {{distance}} {{direction}} van {{placename}}"
+  javascripts: 
+    map: 
+      base: 
+        cycle_map: Fietskaart
+        noname: GeenNaam
+    site: 
+      edit_zoom_alert: u moet in zoom om die kaart te wysig
+      history_zoom_alert: U moet in zoom om die kaart se wysigingsgeskiedenis te sien
+  layouts: 
+    donate: Ondersteun OpenStreetMap deur aan die Hardeware Opgradeer-fonds te {{link}}.
+    donate_link_text: skenk
+    edit: Wysig
+    edit_tooltip: Wysig kaarte
+    export: Eksporteer
+    export_tooltip: Eksporteer kaartdata
+    gps_traces: GPS-spore
+    gps_traces_tooltip: Beheer spore
+    help_wiki: Help &amp; Wiki
+    help_wiki_tooltip: Help en wiki vir die projek
+    history: Geskiedenis
+    home: tuis
+    home_tooltip: Gaan na tuisligging
+    inbox: inboks ({{count}})
+    inbox_tooltip: 
+      one: U inboks bevat 1 ongeleesde boodskap
+      other: U inboks bevat {{count}} ongeleesde boodskappe
+      zero: U inboks bevat geen ongelees boodskappe nie
+    intro_1: OpenStreetMap is 'n vry bewerkbare kaart van die hele wêreld. Dit word deur mense soos u geskep.
+    intro_2: Met OpenStreetMap kan u geografiese data van die hele aarde sien, wysig en gebruik.
+    intro_3: OpenStreetMap se webwerf word deur {{ucl}} en {{bytemark}} ondersteun.
+    log_in: Teken in
+    log_in_tooltip: Teken aan met 'n bestaande rekening
+    logo: 
+      alt_text: OpenStreetMap-logo
+    logout: teken uit
+    logout_tooltip: Teken uit
+    make_a_donation: 
+      text: Maak 'n donasie
+      title: Ondersteun OpenStreetMap met'n geldelike donasie
+    news_blog: Nuusjoernale
+    news_blog_tooltip: Nuusjoernaal oor OpenStreetMap, vrye geografiese data, ensovoorts.
+    osm_read_only: Die OpenStreetMap-databasis kan op die oomblik slegs gelees word aangesien noodsaaklik onderhoud tans uitgevoer word.
+    shop: Winkel
+    shop_tooltip: Winkel met OpenStreetMap-produkte
+    sign_up: registreer
+    sign_up_tooltip: Skep 'n rekening vir wysigings
+    sotm: Kom na die 2009 OpenStreetMap-konferensie, die "State of the Map", op 10-12 Julie in Amsterdam!
+    tag_line: Die vrye wiki-wêreldkaart
+    user_diaries: Gebruikersdagboeke
+    user_diaries_tooltip: Wys gebruikersdagboeke
+    view: Wys
+    view_tooltip: Wys kaarte
+    welcome_user: Welkom, {{user_link}}
+    welcome_user_link_tooltip: U gebruikersblad
+  map: 
+    coordinates: "Koördinate:"
+    edit: Wysig
+    view: Wys
+  message: 
+    delete: 
+      deleted: Boodskap is verwyder
+    inbox: 
+      date: Datum
+      from: Vanaf
+      my_inbox: My inboks
+      no_messages_yet: U het nog geen boodskappe nie. Hoekom kontak u nie sommige van die {{people_mapping_nearby_link}} nie?
+      outbox: outboks
+      people_mapping_nearby: nabygeleë karteerders
+      subject: Onderwerp
+      title: Inboks
+      you_have: U het {{new_count}} nuwe boodskappe en {{old_count}} ou boodskappe
+    mark: 
+      as_read: Boodskap gemerk as gelees
+      as_unread: Boodskap gemerk as ongelees
+    message_summary: 
+      delete_button: Verwyder
+      read_button: Merk as gelees
+      reply_button: Antwoord
+      unread_button: Merk as ongelees
+    new: 
+      back_to_inbox: Terug na inboks
+      body: Teks
+      message_sent: Boodskap is gestuur
+      send_button: Stuur
+      send_message_to: Stuur 'n nuwe boodskap aan {{name}}
+      subject: Onderwerp
+      title: Stuur boodskap
+    no_such_user: 
+      body: Jammer, daar is geen gebruiker of boodskap met die naam of id nie
+      heading: Geen sodanige gebruiker of boodskap nie
+      title: Geen sodanige gebruiker of boodskap nie
+    outbox: 
+      date: Datum
+      inbox: inboks
+      my_inbox: My {{inbox_link}}
+      no_sent_messages: U het nog geen boodskappe gestuur nie. Hoekom kontak u nie sommige van die {{people_mapping_nearby_link}} nie?
+      outbox: uitboks
+      people_mapping_nearby: nabygeleë karteerders
+      subject: Onderwerp
+      title: Gestuur
+      to: Aan
+      you_have_sent_messages: U het {{count}} gestuurde boodskappe
+    read: 
+      back_to_inbox: Terug na inboks
+      back_to_outbox: Terug na uitboks
+      date: Datum
+      from: Van
+      reply_button: Antwoord
+      subject: Onderwerp
+      title: Lees boodskap
+      to: Aan
+      unread_button: Merk as ongelees
+    sent_message_summary: 
+      delete_button: Verwyder
+  notifier: 
+    diary_comment_notification: 
+      hi: Hallo {{to_user}},
+      subject: "[OpenStreetMap] {{user}} het kommentaar op u dagboekinskrywing gelewer"
+    email_confirm: 
+      subject: "[OpenStreetMap] Bevestig u e-posadres"
+    email_confirm_html: 
+      click_the_link: As dit u is, kliek op die onderstaande skakel om die verandering te bevestig.
+      greeting: Hallo,
+      hopefully_you: Iemand (hopelik u) wil graag sy e-posadres op {{server_url}} verander na {{new_address}}.
+    email_confirm_plain: 
+      greeting: Hallo,
+      hopefully_you_2: "{{server_url}} na {{new_address}}."
+    friend_notification: 
+      subject: "[OpenStreetMap] {{user}} het u as 'n vriend bygevoeg"
+    gpx_notification: 
+      failure: 
+        more_info_2: "hulle kan gevind word by:"
+      greeting: Hallo,
+      with_description: met die beskrywing
+      your_gpx_file: Dit lyk soos jou GPX-lêer
+    lost_password: 
+      subject: "[OpenStreetMap] Versoek nuwe wagwoord"
+    lost_password_html: 
+      greeting: Hallo,
+    lost_password_plain: 
+      greeting: Hallo,
+    message_notification: 
+      banner1: "*                  Moet asseblief nie op hierdie e-pos reageer nie.                    *"
+      footer1: U kan ook die boodskap by {{readurl}} lees
+      footer2: en u kan antwoord by {{replyurl}}
+      hi: Hallo {{to_user}},
+      subject: "[OpenStreetMap] {{user}} het 'n nuwe boodskap aan u gestuur"
+    signup_confirm: 
+      subject: "[OpenStreetMap] Bevestig u e-posadres"
+    signup_confirm_html: 
+      get_reading: Lees meer oor OpenStreetMap <a href="http://wiki.openstreetmap.org/wiki/Beginners%27_Guide">op die wiki</a> of <a href="http://www.opengeodata.org/">die opengeodata-blog</a> waar u ook na <a href="http://www.opengeodata.org/?cat=13">podgooie</a> kan luister!
+      greeting: Hallo daar!
+      hopefully_you: Iemand (hopelik u) wil graag 'n rekening skep op
+      introductory_video: U kan na 'n {{introductory_video_link}} kyk.
+      more_videos: Daar is {{more_videos_link}}.
+      more_videos_here: meer video's hier
+      video_to_openstreetmap: inleidende video oor OpenStreetMap
+    signup_confirm_plain: 
+      click_the_link_1: As dit u is, welkom! Kliek asseblief op die onderstaande skakel om u rekening te bevestig
+      greeting: Hallo daar!
+      more_videos: "Daar is meer videos hier:"
+      user_wiki_1: Ons beveel aan dat u 'n gebruikersblad op die wiki skep met onder andere
+      user_wiki_2: kategorie-etikette wat aandui waar u woon, soos [[Category:Users_in_Pretoria]].
+      wiki_signup: "U kan ook op die OpenStreetMap-wiki registreer by:"
+  oauth: 
+    oauthorize: 
+      allow_read_prefs: u gebruikersvoorkeure te lees.
+      allow_write_api: die kaart te wysig.
+      allow_write_gpx: Laai GPS-spore op.
+      allow_write_prefs: verander jou gebruikersvoorkeure.
+  oauth_clients: 
+    edit: 
+      submit: Wysig
+      title: Wysig u applikasie
+    form: 
+      allow_read_prefs: lees hulle gebruikersvoorkeure.
+      allow_write_diary: skep dagboekinskrywings, lewer kommentaar en maak vriende.
+      allow_write_prefs: verander hulle gebruikersvoorkeure.
+      name: Naam
+      required: Verplig
+      support_url: Ondersteunings-URL
+      url: Applikasie-URL
+    index: 
+      application: Applikasienaam
+      issued_at: Uitgereik op
+      register_new: Registreer u applikasie
+      revoke: Herroep!
+    new: 
+      submit: Registreer
+      title: Registreer 'n nuwe applikasie
+    not_found: 
+      sorry: Jammer, die {{type}} kon nie gevind word nie.
+    show: 
+      allow_read_prefs: lees hulle gebruikersvoorkeure.
+      allow_write_api: wysig die kaart.
+      allow_write_diary: skep dagboekinskrywings, lewer kommentaar en maak vriende.
+      allow_write_gpx: laai GPS-spore op.
+      authorize_url: "URL vir magtiging:"
+      edit: Wysig details
+  site: 
+    edit: 
+      anon_edits_link_text: Lees waarom dit die geval is.
+      user_page_link: gebruikersbladsy
+    index: 
+      license: 
+        license_name: Creative Commons Naamsvermelding 2.0
+        notice: Gelisensieer onder die {{license_name}} lisensie deur die {{project_name}} en sy bydraers.
+        project_name: OpenStreetMap-projek
+      permalink: Permanente skakel
+      shortlink: Kort skakel
+    key: 
+      map_key: Sleutel
+      table: 
+        entry: 
+          admin: Administratiewe grens
+          apron: 
+            - Lughaweplatform
+            - terminaal
+          bridge: Brug
+          building: Belangrike gebou
+          cable: 
+            - Kabelkar
+          cemetery: Begraafplaas
+          centre: Sport-sentrum
+          commercial: Kommersiële gebied
+          common: 
+            - weide
+            - weide
+          construction: Paaie onder konstruksie
+          cycleway: Fietspad
+          destination: Bestemmingsverkeer
+          farm: Plaas
+          footway: Voetpad
+          forest: Bos
+          golf: Gholfbaan
+          heathland: Heide
+          industrial: Industriële gebied
+          lake: 
+            - Meer
+            - reservoir
+          military: Militêre gebied
+          motorway: Snelweg
+          park: Park
+          permissive: Beperkte toegang
+          pitch: Sportveld
+          primary: Primêre pad
+          private: Privaat toegang
+          rail: Spoorweg
+          reserve: Natuurreservaat
+          resident: Woongebied
+          retail: Winkelgebied
+          runway: 
+            - Lughawe aanloopbaan
+            - taxibaan
+          school: 
+            - Skool
+            - universiteit
+          secondary: Sekondêre pad
+          station: Spoorwegstasie
+          summit: 
+            - Piek
+            - piek
+          tourist: Toerisme-trekpleister
+          track: Spoor
+          tram: 
+            - Ligte spoor
+          trunk: Trokpad
+          tunnel: Tonnel
+          unclassified: Ongeklassifiseerde pad
+          unsurfaced: Grondpad
+          wood: Bos
+        heading: Sleutel vir z{{zoom_level}}
+    search: 
+      search: Soek
+      search_help: "voorbeelde: 'Alkmaar', 'Regent Street, Cambridge', 'CB2 5AQ', or 'post offices near Lünen' <a href='http://wiki.openstreetmap.org/wiki/Search'>meer voorbeelde...</a>"
+      submit_text: OK
+      where_am_i: Waar is ek?
+    sidebar: 
+      close: Sluit
+      search_results: Soekresultate
+  trace: 
+    create: 
+      upload_trace: Laai GPS-spore op
+    delete: 
+      scheduled_for_deletion: Spoor is geskeduleer vir verwydering
+    edit: 
+      description: "Beskrywing:"
+      download: aflaai
+      edit: wysig
+      filename: "Lêernaam:"
+      heading: Wysig spoor {{name}}
+      map: kaart
+      owner: "Eienaar:"
+      points: "Punte:"
+      save_button: Stoor wysigings
+      start_coord: "Beginkoördinaat:"
+      tags: "Etikette:"
+      tags_help: met kommas geskei
+      title: Wysig spoor {{name}}
+      uploaded_at: "Opgelaai op:"
+      visibility: "Sigbaarheid:"
+      visibility_help: wat beteken dit?
+    list: 
+      public_traces: Openbare GPS-spore
+      public_traces_from: Openbare GPS-spore van {{user}}
+      tagged_with: geëtiketteer met {{tags}}
+      your_traces: U GPS-spore
+    make_public: 
+      made_public: Spoor is openbaar gemaak
+    no_such_user: 
+      heading: Die gebruiker {{user}} bestaan nie
+      title: Die gebruiker bestaan nie
+    trace: 
+      ago: "{{time_in_words_ago}} gelede"
+      by: deur
+      count_points: "{{count}} punte"
+      edit: wysig
+      edit_map: Kaart bewysig
+      in: in
+      map: kaart
+      more: meer
+      pending: BESIG
+      private: PRIVAAT
+      public: OPENBAAR
+      trace_details: Wys spoor besonderhede
+      view_map: Wys kaart
+    trace_form: 
+      description: Beskrywing
+      help: Hulp
+      tags: Etikette
+      tags_help: met kommas geskei
+      upload_button: Laai op
+      upload_gpx: Laai GPX-lêer op
+      visibility: Sigbaarheid
+      visibility_help: wat beteken dit?
+    trace_header: 
+      see_all_traces: Wys alle spore
+      see_just_your_traces: Sien slegs u spore, of laai 'n spoor op
+      see_your_traces: Sien al u spore
+    trace_optionals: 
+      tags: Etikette
+    trace_paging_nav: 
+      of: van
+      showing: Wys bladsy
+    view: 
+      delete_track: Verwyder hierdie spoor
+      description: "Beskrywing:"
+      download: laai af
+      edit: wysig
+      edit_track: Wysig hierdie spoor
+      filename: "Lêernaam:"
+      heading: Besigtig spoor {{name}}
+      map: kaart
+      none: Geen
+      owner: "Eienaar:"
+      pending: BESIG
+      points: "Punte:"
+      start_coordinates: "Beginkoördinaat:"
+      tags: "Etikette:"
+      title: Besigting spoor {{name}}
+      trace_not_found: Spoor nie gevind nie!
+      uploaded: "Opgelaai op:"
+      visibility: "Sigbaarheid:"
+  user: 
+    account: 
+      email never displayed publicly: (word nie openbaar gemaak nie)
+      flash update success: U gebruikersinligting is verander.
+      home location: "Tuisligging:"
+      latitude: "Breedtegraad:"
+      longitude: "Lengtegraad:"
+      make edits public button: Maak al my wysigings openbaar
+      my settings: My voorkeure
+      no home location: U het nog nie u huis se ligging ingevoer nie.
+      preferred languages: "Voorkeur tale:"
+      profile description: "Profielbeskrywing:"
+      public editing: 
+        disabled link text: hoekom kan ek niks wysig nie?
+        enabled: Geaktiveer. U is nie anoniem nie en kan inligting wysig.
+        enabled link text: wat is dit?
+        heading: "Openbaar wysigings:"
+      return to profile: Terug na profiel
+      save changes button: Stoor wysigings
+      title: Wysig rekening
+      update home location on click: Opdateer tuisligging wanneer ek op die kaart kliek?
+    confirm: 
+      button: Bevestig
+      heading: Bevestig 'n gebruiker se rekening
+      press confirm button: Kliek op "Bevestig" hieronder om u rekening aktiveer.
+    confirm_email: 
+      button: Bevestig
+      success: U e-posadres is bevestig, dankie dat u geregistreer het!
+    friend_map: 
+      nearby mapper: "Nabygeleë karteerder: [[nearby_user]]"
+      your location: U ligging
+    login: 
+      auth failure: Jammer, kon nie met hierdie inligting aanteken nie.
+      create_account: registreer
+      email or username: "E-posadres of gebruikersnaam:"
+      heading: Teken in
+      login_button: Teken in
+      lost password link: Wagwoord vergeet?
+      password: "Wagwoord:"
+      please login: Teken in of {{create_user_link}}.
+      title: Teken in
+    lost_password: 
+      email address: "E-posadres:"
+      heading: Wagwoord vergeet?
+      new password button: Herstel wagwoord
+      notice email cannot find: Kon nie die e-posadres vind nie, jammer.
+      title: Wagwoord vergeet
+    make_friend: 
+      already_a_friend: U is reeds met {{name}} bevriend.
+      failed: Jammer, kon nie {{name}} as 'n vriend byvoeg nie.
+      success: "{{name}} is nou u vriend."
+    new: 
+      confirm email address: "Bevestig E-posadres:"
+      confirm password: "Bevestig wagwoord:"
+      display name: "Vertoon naam:"
+      email address: "E-posadres:"
+      fill_form: Vul die vorm in en ons stuur so spoedig moontlik aan u 'n e-pos om u rekening te aktiveer.
+      flash create success message: U rekening is suksesvol geskep. Kontroleer u e-pos vir 'n bevestigingsboodskap.<br /><br />Let daarop dat u nie sal kan aanteken alvorens u nie u rekening bevestig het nie.<br /><br />As u 'n spamfilter gebruik, sorg asseblief dat dit boodskappe vanaf webmaster@openstreetmap.org sal toelaat. Die stelsel stuur nie antwoorde op bevestigings-epos nie.
+      heading: Skep 'n rekening
+      license_agreement: Deur 'n rekening hier te skep bevestig u dat u akkoord gaan met voorwaarde dat al die werk wat u na OpenStreetMap oplaai onder die <a href="http://creativecommons.org/licenses/by-sa/2.0/deed.af">Creative Commons-lisensie (by-sa)</a> gelisensieer word (nie-eksklusief).
+      not displayed publicly: Word nie publiek vertoon nie (sien <a href="http://wiki.openstreetmap.org/wiki/Privacy_Policy" title="wiki-geheimhoudingbeleid insluitend afdeling oor e-posadresse">geheimhoudingbeleid</a>)
+      password: "Wagwoord:"
+      signup: Registreer
+      title: Skep rekening
+    no_such_user: 
+      body: Daar is geen gebruiker met die naam {{user}} nie. Kontroleer u spelling, of die skakel waarop u gekliek het is verkeerd.
+      heading: Die gebruiker {{user}} bestaan nie
+      title: Gebruiker bestaan nie
+    remove_friend: 
+      not_a_friend: "{{name}} is nie een van u vriende nie."
+      success: "{{name}} is uit u lys van vriende verwyder."
+    reset_password: 
+      confirm password: "Bevestig wagwoord:"
+      flash changed: U wagwoord is verander.
+      heading: Herstel wagwoord vir {{name}}
+      password: "Wagwoord:"
+      reset: Kry nuwe wagwoord
+      title: Herstel wagwoord
+    set_home: 
+      flash success: U tuisligging is suksesvol gebêre
+    view: 
+      add as friend: voeg by as vriend
+      add image: Voeg prent by
+      ago: ({{time_in_words_ago}} gelede)
+      change your settings: verander u voorkeure
+      delete image: Verwyder prent
+      description: Beskrywing
+      diary: dagboek
+      edits: wysigings
+      if set location: As u u ligging stel, sal 'n pragtige kaart en ander inligting hieronder verskyn. U kan u ligging stel in u {{settings_link}}.
+      km away: "{{count}}km vêr"
+      m away: "{{count}}m vêr"
+      mapper since: "Karteer sedert:"
+      my diary: my dagboek
+      my edits: my wysigings
+      my settings: my voorkeure
+      my traces: my spore
+      my_oauth_details: Wys my OAuth-besonderhede
+      nearby users: "Nabygeleë gebruikers:"
+      new diary entry: nuwe dagboekinskrywing
+      no friends: U het nog geen vriende bygevoeg nie.
+      no home location: Geen tuisligging verskaf nie.
+      no nearby users: Daar is nog geen nabygeleë gebruikers wat erken dat hulle karterinswerk doen nie.
+      remove as friend: verwyder as vriend
+      send message: stuur boodskap
+      settings_link_text: voorkeure
+      traces: spore
+      upload an image: Laai 'n prent op
+      user image heading: Foto van gebruiker
+      user location: Ligging van gebruiker
+      your friends: U vriende
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
new file mode 100644 (file)
index 0000000..8e76c43
--- /dev/null
@@ -0,0 +1,74 @@
+# Messages for Arabic (العربية)
+# Exported from translatewiki.net
+# Export driver: syck
+# Author: OsamaK
+ar: 
+  browse: 
+    map: 
+      loading: يُحمّل...
+  diary_entry: 
+    diary_entry: 
+      edit_link: حرّر هذه المدخلة
+  export: 
+    start: 
+      area_to_export: المنطقة المطلوب تصديرها
+      format: الهيئة
+      format_to_export: الهيئة المطلوب تصديرها
+      image_size: حجم الصورة
+      max: الأقصى
+      options: خيارات
+      scale: القياس
+  map: 
+    edit: حرّر
+    view: اعرض
+  message: 
+    delete: 
+      deleted: حُذفت الرسالة
+    mark: 
+      as_read: عُلّمت الرسالة مقروءة
+      as_unread: عُلّمت الرسالة غير مقروءة
+  site: 
+    index: 
+      permalink: وصلة دائمة
+      shortlink: وصلة قصيرة
+    key: 
+      table: 
+        entry: 
+          park: حديقة
+          wood: غابة
+    search: 
+      search: بحث
+      submit_text: اذهب
+      where_am_i: أين أنا؟
+    sidebar: 
+      close: أغلق
+      search_results: نتائج البحث
+  user: 
+    account: 
+      no home location: لم تدخل موقع منزلك.
+      public editing: 
+        disabled link text: لماذا لا أستطيع التعديل؟
+        enabled link text: ما هذا؟
+      save changes button: احفظ التغييرات
+    login: 
+      email or username: "عنوان البريد الإلكتروني أو اسم المستخدم:"
+      heading: ولوج
+      login_button: لُج
+      lost password link: أنسيت كلمة السر؟
+      password: "كلمة السر:"
+      please login: من فضلك لُج أو {{create_user_link}}.
+      title: ولوج
+    lost_password: 
+      email address: "عنوان البريد الإلكتروني:"
+      heading: أنسيت كلمة السر؟
+      notice email cannot find: تعذّر إيجاد عنوان البريد الإلكتروني، نحن آسفون.
+      title: نسيان كلمة السر
+    new: 
+      confirm email address: "تأكيد عنوان البريد الإلكتروني:"
+      confirm password: "تأكيد كلمة السر:"
+      email address: "عنوان البريد الإلكتروني:"
+      password: "كلمة السر:"
+    reset_password: 
+      title: إعادة ضبط كلمة السر
+    view: 
+      your friends: أصدقاؤك
diff --git a/config/locales/be-TARASK.yml b/config/locales/be-TARASK.yml
new file mode 100644 (file)
index 0000000..39de271
--- /dev/null
@@ -0,0 +1,176 @@
+# Messages for Belarusian (Taraškievica orthography) (Беларуская (тарашкевіца))
+# Exported from translatewiki.net
+# Export driver: syck
+# Author: EugeneZelenko
+# Author: Jim-by
+be-TARASK: 
+  activerecord: 
+    attributes: 
+      diary_entry: 
+        language: Мова
+        latitude: Шырата
+        longitude: Даўгата
+      trace: 
+        description: Апісаньне
+        latitude: Шырата
+        longitude: Даўгата
+      user: 
+        description: Апісаньне
+        languages: Мовы
+        pass_crypt: Пароль
+    models: 
+      country: Краіна
+      language: Мова
+      node: Вузел
+      session: Сэсыя
+      way: Шлях
+  browse: 
+    common_details: 
+      changeset_comment: "Камэнтар:"
+      version: "Вэрсія:"
+    map: 
+      deleted: Выдаленая
+      loading: Загрузка…
+    node: 
+      download_xml: Загрузіць XML
+      edit: рэдагаваць
+      node: Вузел
+      node_title: "Вузел: {{node_name}}"
+      view_history: паказаць гісторыю
+    node_details: 
+      coordinates: "Каардынаты:"
+    node_history: 
+      download_xml: Загрузіць XML
+      view_details: паказаць падрабязнасьці
+    not_found: 
+      type: 
+        node: вузел
+        way: шлях
+    relation: 
+      download_xml: Загрузіць XML
+      view_history: паказаць гісторыю
+    relation_history: 
+      download_xml: Загрузіць XML
+      view_details: паказаць падрабязнасьці
+    relation_member: 
+      entry_role: "{{type}} {{name}} як {{role}}"
+      type: 
+        node: Вузел
+        relation: Адносіны
+        way: Шлях
+    start_rjs: 
+      data_frame_title: Зьвесткі
+      data_layer_name: Зьвесткі
+      details: Падрабязнасьці
+      loading: Загрузка…
+      object_list: 
+        details: Падрабязнасьці
+        history: 
+          type: 
+            node: Вузел [[id]]
+            way: Шлях [[id]]
+        selected: 
+          type: 
+            node: Вузел [[id]]
+            way: Шлях [[id]]
+        type: 
+          node: Вузел
+          way: Шлях
+    way: 
+      download: "{{download_xml_link}}, {{view_history_link}} ці {{edit_link}}"
+      download_xml: Загрузіць XML
+      edit: рэдагаваць
+      view_history: паказаць гісторыю
+      way: Шлях
+      way_title: "Шлях: {{way_name}}"
+    way_details: 
+      nodes: "Вузлы:"
+      part_of: "Частка:"
+    way_history: 
+      download_xml: Загрузіць XML
+      view_details: паказаць падрабязнасьці
+  diary_entry: 
+    edit: 
+      language: "Мова:"
+      latitude: "Шырата:"
+      longitude: "Даўгата:"
+      save_button: Захаваць
+      subject: "Тэма:"
+    view: 
+      save_button: Захаваць
+  export: 
+    start: 
+      export_button: Экспартаваць
+      format: Фармат
+      licence: Ліцэнзія
+      options: Устаноўкі
+    start_rjs: 
+      export: Экспартаваць
+  layouts: 
+    edit: Рэдагаваць
+    export: Экспартаваць
+    history: Гісторыя
+  map: 
+    coordinates: "Каардынаты:"
+    edit: Рэдагаваць
+  message: 
+    inbox: 
+      subject: Тэма
+    message_summary: 
+      delete_button: Выдаліць
+      reply_button: Адказаць
+    new: 
+      subject: Тэма
+    outbox: 
+      subject: Тэма
+    read: 
+      reply_button: Адказаць
+      subject: Тэма
+    sent_message_summary: 
+      delete_button: Выдаліць
+  oauth_clients: 
+    edit: 
+      submit: Рэдагаваць
+  trace: 
+    edit: 
+      description: "Апісаньне:"
+      download: загрузіць
+      edit: рэдагаваць
+      filename: "Назва файла:"
+      map: мапа
+      save_button: Захаваць зьмены
+    trace: 
+      edit: рэдагаваць
+      map: мапа
+    trace_form: 
+      description: Апісаньне
+      help: Дапамога
+    view: 
+      description: "Апісаньне:"
+      download: загрузіць
+      edit: рэдагаваць
+      filename: "Назва файла:"
+      map: мапа
+  user: 
+    account: 
+      latitude: "Шырата:"
+      longitude: "Даўгата:"
+      my settings: Мае ўстаноўкі
+      save changes button: Захаваць зьмены
+    login: 
+      password: "Пароль:"
+    lost_password: 
+      new password button: Ачысьціць пароль
+    new: 
+      password: "Пароль:"
+    reset_password: 
+      password: "Пароль:"
+      reset: Ачысьціць пароль
+      title: Ачысьціць пароль
+    view: 
+      add image: Дадаць выяву
+      delete image: Выдаліць выяву
+      description: Апісаньне
+      edits: рэдагаваньні
+      my settings: мае ўстаноўкі
+      settings_link_text: устаноўкі
index 5cc277ef48a4a66ad02903d193cdd2353c53b30b..e995eeeb48163a993d9520f92dc3b17a5d2e7c81 100644 (file)
-be:
-  activerecord:
-    # Translates all the model names, which is used in error handling on the web site
-    models:
-      acl: "Спіс правоў доступу"
-      changeset: "Набор зменаў"
-      changeset_tag: "Цэтлік набору зменаў"
-      country: "Краіна"
-      diary_comment: "Каментар дзённіка"
-      diary_entry: "Запіс дзённіка"
-      friend: "Сябар"
-      language: "Мова"
-      message: "Паведамленне"
-      node: "Вузел"
-      node_tag: "Цэтлік вузла"
-      notifier: "Абвяшчэнне"
-      old_node: "Стары вузел"
-      old_node_tag: "Стары цэтлік вузла"
-      old_relation: "Старая сувязь"
-      old_relation_member: "Стары ўдзельнік сувязі"
-      old_relation_tag: "Стары цэтлік сувязі"
-      old_way: "Стары шлях"
-      old_way_node: "Стары вузел шляху"
-      old_way_tag: "Стары цэтлік шляху"
-      relation: "Сувязь"
-      relation_member: "Удзельнік сувязі"
-      relation_tag: "Цэтлік сувязі"
-      session: "Сеанс"
-      trace: "Трэк"
-      tracepoint: "Пункт трэку"
-      tracetag: "Цэтлік трэку"
-      user: "Карыстальнік"
-      user_preference: "Настаўленне карыстальніка"
-      user_token: "Адметка карыстальніка"
-      way: "Шлях"
-      way_node: "Вузел шляху"
-      way_tag: "Цэтлік шляху"
-    # Translates all the model attributes, which is used in error handling on the web site
-    # Only the ones that are used on the web site are translated at the moment
-    attributes:
-      diary_comment:
-        body: "Тэкст"
-      diary_entry:
-        user: "Карыстальнік"
-        title: "Загаловак"
-        latitude: "Шырата"
-        longitude: "Даўгата"
-        language: "Мова"
-      friend:
-        user: "Карыстальнік"
-        friend: "Сябар"
-      trace:
-        user: "Сябар"
-        visible: "Бачны"
-        name: "Назва"
-        size: "Памер"
-        latitude: "Шырата"
-        longitude: "Даўгата"
-        public: "Публічны"
-        description: "Апісанне"
-      message:
-        sender: "Ад"
-        title: "Загаловак"
-        body: "Тэкст"
-        recipient: "Каму"
-      user:
-        email: "Email"
-        active: "Актыўны"
-        display_name: "Бачнае імя"
-        description: "Апісанне"
-        languages: "Мовы"
-        pass_crypt: "Пароль"
-  map:
-    view: Карта
-    edit: Змяніць
-    coordinates: "Каардынаты:"
-  browse:
-    changeset:
-      title: "Набор зменаў"
-      changeset: "Набор зменаў: {{id}}"
-      download: "Сцягнуць {{changeset_xml_link}} ці {{osmchange_xml_link}}"
-      changesetxml: "Changeset XML"
-      osmchangexml: "osmChange XML"
-    changeset_details:
-      created_at: "Створаны:"
-      closed_at: "Закрыты:"
+# Messages for Belarusian (Беларуская)
+# Exported from translatewiki.net
+# Export driver: syck
+be: 
+  activerecord: 
+    attributes: 
+      diary_comment: 
+        body: Тэкст
+      diary_entry: 
+        language: Мова
+        latitude: Шырата
+        longitude: Даўгата
+        title: Загаловак
+        user: Карыстальнік
+      friend: 
+        friend: Сябар
+        user: Карыстальнік
+      message: 
+        body: Тэкст
+        recipient: Каму
+        sender: Ад
+        title: Загаловак
+      trace: 
+        description: Апісанне
+        latitude: Шырата
+        longitude: Даўгата
+        name: Назва
+        public: Публічны
+        size: Памер
+        user: Сябар
+        visible: Бачны
+      user: 
+        active: Актыўны
+        description: Апісанне
+        display_name: Бачнае імя
+        languages: Мовы
+        pass_crypt: Пароль
+    models: 
+      acl: Спіс правоў доступу
+      changeset: Набор зменаў
+      changeset_tag: Цэтлік набору зменаў
+      country: Краіна
+      diary_comment: Каментар дзённіка
+      diary_entry: Запіс дзённіка
+      friend: Сябар
+      language: Мова
+      message: Паведамленне
+      node: Вузел
+      node_tag: Цэтлік вузла
+      notifier: Абвяшчэнне
+      old_node: Стары вузел
+      old_node_tag: Стары цэтлік вузла
+      old_relation: Старая сувязь
+      old_relation_member: Стары ўдзельнік сувязі
+      old_relation_tag: Стары цэтлік сувязі
+      old_way: Стары шлях
+      old_way_node: Стары вузел шляху
+      old_way_tag: Стары цэтлік шляху
+      relation: Сувязь
+      relation_member: Удзельнік сувязі
+      relation_tag: Цэтлік сувязі
+      session: Сеанс
+      trace: Трэк
+      tracepoint: Пункт трэку
+      tracetag: Цэтлік трэку
+      user: Карыстальнік
+      user_preference: Настаўленне карыстальніка
+      user_token: Адметка карыстальніка
+      way: Шлях
+      way_node: Вузел шляху
+      way_tag: Цэтлік шляху
+  browse: 
+    changeset: 
+      changeset: "Набор зменаў:"
+      download: Сцягнуць {{changeset_xml_link}} ці {{osmchange_xml_link}}
+      title: Набор зменаў
+    changeset_details: 
       belongs_to: "Належыць:"
       bounding_box: "Межы:"
-      no_bounding_box: "Межы гэтага набора зменаў не вызначаны."
-      show_area_box: "Паказаць мяжу мясцовасці"
-      box: "мяжа"
+      box: мяжа
+      closed_at: "Закрыты:"
+      created_at: "Створаны:"
       has_nodes: "Складаецца з {{count}} вузлоў:"
-      has_ways: "Складаецца з {{count}} шляхоў:"
       has_relations: "Складаецца з {{count}} сувязей:"
+      has_ways: "Складаецца з {{count}} шляхоў:"
+      no_bounding_box: Межы гэтага набора зменаў не вызначаны.
+      show_area_box: Паказаць мяжу мясцовасці
     common_details: 
       edited_at: "Зменена:"
       edited_by: "Карыстальнікам:"
-      version: "Версія:"
       in_changeset: "У наборы зменаў:"
-    containing_relation:
-      entry: "Сувязь {{relation_name}}"
-      entry_role: "Сувязь {{relation_name}} (як {{relation_role}})"
-    map:
-      loading: "Загрузка..."
-      deleted: "Выдалены"
-    node_details:
-      coordinates: "Каардынаты: "
+      version: "Версія:"
+    map: 
+      deleted: Выдалены
+      loading: Загрузка...
+    node: 
+      download: "{{download_xml_link}} ці {{view_history_link}}"
+      download_xml: Сцягнуць XML
+      node: Вузел
+      node_title: "Вузел: {{node_name}}"
+      view_history: прагледзіць гісторыю
+    node_details: 
+      coordinates: "Каардынаты:"
       part_of: "Частка:"
-    node_history:
-      node_history: "Гісторыя вузла"
+    node_history: 
       download: "{{download_xml_link}} ці {{view_details_link}}"
-      download_xml: "Сцягнуць XML"
-      view_details: "прагледзіць дэталі"
-    node:
-      node: "Вузел"
-      node_title: "Вузел: {{node_name}}"
+      download_xml: Сцягнуць XML
+      node_history: Гісторыя вузла
+      view_details: прагледзіць дэталі
+    not_found: 
+      sorry: Прабачце, {{type}} з нумарам {{id}} не знойдзены.
+      type: 
+        node: вузел
+        relation: адносіны
+        way: лінія
+    paging_nav: 
+      of: з
+      showing_page: Паказ старонкі
+    relation: 
       download: "{{download_xml_link}} ці {{view_history_link}}"
-      download_xml: "Сцягнуць XML"
-      view_history: "прагледзіць гісторыю"
-    not_found:
-      sorry: "Прабачце, {{type}} з нумарам {{id}} не знойдзены."
-    paging_nav:
-      showing_page: "Паказ старонкі"
-      of: "з"
-    relation_details:
+      download_xml: Сцягнуць XML
+      relation: Сувязь
+      relation_title: "Сувязь: {{relation_name}}"
+      view_history: прагледзець гісторыю
+    relation_details: 
       members: "Удзельнікі:"
       part_of: "Частка:"
-    relation_history:
-      relation_history: "Гісторыя сувязі"
+    relation_history: 
+      relation_history: Гісторыя сувязі
       relation_history_title: "Гісторыя сувязі: {{relation_name}}"
-    relation:
-      relation: "Сувязь"
-      relation_title: "Сувязь: {{relation_name}}"
-      download: "{{download_xml_link}} ці {{view_history_link}}"
-      download_xml: "Сцягнуць XML"
-      view_history: "прагледзець гісторыю"
-    start:
-      view_data: "Прагледзець дадзеныя па бягучым аглядзе"
-      manually_select: "Выбраць іншую мясцовасць"
-    start_rjs:
-      data_frame_title: "Дадзеныя"
-      zoom_or_select: "Наблізьцеся ці выберыце іншую мясцовасць для агляду"
-      drag_a_box: "Расцягніце рамку на карце для выбара іншай мясцовасці"
-      manually_select: "Выбраць іншую мясцовасць"
-      loaded_an_area_with_num_features: "Вы загрузілі мясцовасць, што змяшчае [[num_features]] элементаў.  Увогуле, некаторыя вандроўнікі могуць не здолець апрацаваць гэтакую колькасць дадзеных. Звычайна, найлепшы рэзультат назіраецца, калі элементаў менш за 100, пры большай колькасці вандроўнік можа згубіць хуткасць. Калі вы ўпэўненыя, што хочаце паглядзець на гэтыя дадзеныя, націсніце кнопку ніжэй."
-      load_data: "Загрузіць дадзеныя"
+    start: 
+      manually_select: Выбраць іншую мясцовасць
+      view_data: Прагледзець дадзеныя па бягучым аглядзе
+    start_rjs: 
+      data_frame_title: Дадзеныя
+      data_layer_name: Дадзеныя
+      details: Падрабязней
+      drag_a_box: Расцягніце рамку на карце для выбара іншай мясцовасці
+      edited_by_user_at_timestamp: Зменена [[user]] у [[timestamp]]
+      history_for_feature: Гісторыя [[feature]]
+      load_data: Загрузіць дадзеныя
+      loaded_an_area_with_num_features: Вы загрузілі мясцовасць, што змяшчае [[num_features]] элементаў.  Увогуле, некаторыя вандроўнікі могуць не здолець апрацаваць гэтакую колькасць дадзеных. Звычайна, найлепшы рэзультат назіраецца, калі элементаў менш за 100, пры большай колькасці вандроўнік можа згубіць хуткасць. Калі вы ўпэўненыя, што хочаце паглядзець на гэтыя дадзеныя, націсніце кнопку ніжэй.
+      loading: Загрузка...
+      manually_select: Выбраць іншую мясцовасць
+      object_list: 
+        api: Атрымаць гэтую вобласць з API
+        back: Адлюстраваць спіс аб'ектаў
+        details: Дэталі
+        heading: Спіс аб'ектаў
+        selected: 
+          type: 
+            node: Вузел [[id]]
+            way: Лінія [[id]]
+        type: 
+          node: Вузел
+          way: Лінія
+      private_user: таемны карыстальнік
+      show_history: Паказаць гісторыю
       unable_to_load_size: "Нельга загрузіць: парем мяжы [[bbox_size]] занадта вялікі (павінен быць не больш як {{max_bbox_size}})"
-      loading: "Загрузка..."
-      show_history: "Паказаць гісторыю"
-      wait: "Пачакайце..."
-      history_for: "Гісторыя для [[feature]]"
-      details: "Падрабязней"
-      private_user: "таемны карыстальнік"
-      edited_by_user_at_timestamp: "Зменена [[user]] у [[timestamp]]"
-    tag_details:
+      wait: Пачакайце...
+      zoom_or_select: Наблізьцеся ці выберыце іншую мясцовасць для агляду
+    tag_details: 
       tags: "Цэтлікі:"
-    way_details:
+    way: 
+      download: "{{download_xml_link}} ці {{view_history_link}}"
+      download_xml: Сцягнуць XML
+      view_history: прагледзець гісторыю
+      way: Шлях
+      way_title: "Шлях: {{way_name}}"
+    way_details: 
+      also_part_of: 
+        one: таксама частка шляху {{related_ways}}
+        other: таксама частка шляхоў {{related_ways}}
       nodes: "Вузлы:"
       part_of: "Частка:"
-      also_part_of:
-        one: "таксама частка шляху {{related_ways}}"
-        other: "таксама частка шляхоў {{related_ways}}"
-    way_history:
-      way_history: "Гісторыя шляху"
-      way_history_title: "Гісторыя шляху: {{way_name}}"
+    way_history: 
       download: "{{download_xml_link}} ці {{view_details_link}}"
-      download_xml: "Сцягнуць XML"
-      view_details: "прагледзць падрабязней"
-    way:
-      way: "Шлях"
-      way_title: "Шлях: {{way_name}}"
-      download: "{{download_xml_link}} ці {{view_history_link}}"
-      download_xml: "Сцягнуць XML"
-      view_history: "прагледзець гісторыю"
-  changeset:
+      download_xml: Сцягнуць XML
+      view_details: прагледзць падрабязней
+      way_history: Гісторыя шляху
+      way_history_title: "Гісторыя шляху: {{way_name}}"
+  changeset: 
+    changeset: 
+      anonymous: Ананімна
+      big_area: (вялікая)
+      no_comment: (няма)
+      no_edits: (без зменаў)
+      show_area_box: паказаць мяжу мясцовасці
+      still_editing: (у працэсе рэдагавання)
+      view_changeset_details: Падрабязней пра набор зменаў
     changeset_paging_nav: 
-      showing_page: "Паказваецца старонка"
-      of: "з"
-    changeset:
-      still_editing: "(у працэсе рэдагавання)"
-      anonymous: "Ананімна"
-      no_comment: "(няма)"
-      no_edits: "(без зменаў)"
-      show_area_box: "паказаць мяжу мясцовасці"
-      big_area: "(вялікая)"
-      view_changeset_details: "Падрабязней пра набор зменаў"
-    changesets:
-      id: "ID"
-      saved_at: "Запісаны"
-      user: "Карыстальнік"
-      comment: "Каментар"
-      area: "Мясцовасць"
-    list_bbox:
-      history: "Гісторыя"
-      changesets_within_the_area: "Наборы зменаў у мясцовасці:"
-      show_area_box: "паказаць мяжу мясцовасці"
-      no_changesets: "Няма набораў зменаў"
-      all_changes_everywhere: "Для ўсіх зменаў паўсюль глядзіце {{recent_changes_link}}"
-      recent_changes: "Нядаўнія змены"
-      no_area_specified: "Мясцовасць не зададзена"
-      first_use_view: "Спачатку выкарыстайце {{view_tab_link}} каб выбраць патрэбную вам мясцовасць, і толькі потым заходзьце на картку 'Гісторыя'."
-      view_the_map: "прагледзіць карту"
-      view_tab: "картку агляду"
-      alternatively_view: "Ці вы можаце прагледзіць усе {{recent_changes_link}}"
-    list:
-      recent_changes: "Нядаўнія змены"
-      recently_edited_changesets: "Нядаўна змененыя наборы:"
-      for_more_changesets: "Каб убачыць больш набораў зменаў, выберыце карыстальніка і прагледзьце яго змены, ці перайдзіце на картку 'гісторыя' для пэўнай тэрыторыі."
-    list_user:
-      edits_by_username: "Змены карыстальніка {{username_link}}"
-      no_visible_edits_by: "Няма бычных зменаў карыстальніка {{name}}."
-      for_all_changes: "Для ўсіх зменаў усімі карыстальнікамі глядзіце {{recent_changes_link}}"
-      recent_changes: "Нядаўнія змены"
-  diary_entry:
-    new:
-      title: Новы запіс дзённіку
-    list:
-      title: "Дзённікі карыстальнікаў"
-      user_title: "Дзённік {{user}}"
+      of: з
+      showing_page: Паказваецца старонка
+    changesets: 
+      area: Мясцовасць
+      comment: Каментар
+      id: ID
+      saved_at: Запісаны
+      user: Карыстальнік
+  diary_entry: 
+    diary_comment: 
+      comment_from: Каментар {{link_user}} у {{comment_created_at}}
+    diary_entry: 
+      comment_count: 
+        one: 1 каментар
+        other: "Каментараў: {{count}}"
+      comment_link: Каментаваць гэты запіс
+      edit_link: Змяніць гэты запіс
+      posted_by: Напісана {{link_user}} у {{created}} на {{language_link}}
+      reply_link: Адказаць на гэты запіс
+    edit: 
+      body: "Цела:"
+      language: "Мова:"
+      latitude: "Шырата:"
+      location: "Месца:"
+      longitude: "Даўгата:"
+      marker_text: Месцазнаходжанне запісу дзённіку
+      save_button: Запісаць
+      subject: "Тэма:"
+      title: Змяніць запіс дзённіку
+      use_map_link: карыстацца картай
+    list: 
+      in_language_title: Дзённік запісаў у {{language}}
       new: Новы запіс дзённіку
       new_title: Новы запіс для вашага дзённіку
+      newer_entries: Навейшыя запісы
       no_entries: Няма запісаў
-      recent_entries: "Нядаўнія запісы ў дзённіку: "
       older_entries: Старэйшыя запісы
-      newer_entries: Навейшыя запісы
-    edit:
-      title: "Змяніць запіс дзённіку"
-      subject: "Тэма: "
-      body: "Цела: "
-      language: "Мова: "
-      location: "Месца: "
-      latitude: "Шырата: "
-      longitude: "Даўгата: "
-      use_map_link: "карыстацца картай"
-      save_button: "Запісаць"
-      marker_text: Месцазнаходжанне запісу дзённіку
-    view:
-      title: "Дзённік карыстальніка | {{user}}"
-      leave_a_comment: "Пакінуць каментар"
-      save_button: "Запісаць"
-    no_such_entry:
+      recent_entries: "Нядаўнія запісы ў дзённіку:"
+      title: Дзённікі карыстальнікаў
+      user_title: Дзённік {{user}}
+    new: 
+      title: Новы запіс дзённіку
+    no_such_entry: 
+      body: Прабаце, не існуе запісу ў дзённіку ці каментара з нумарам {{id}}. Праверце свой правапіс, ці, магчыма, вам далі няправільную спасылку.
       heading: "Няма запісу з нумарам: {{id}}"
-      body: "Прабаце, не існуе запісу ў дзённіку ці каментара з нумарам {{id}}. Праверце свой правапіс, ці, магчыма, вам далі няправільную спасылку."
-    no_such_user:
-      body: "Прабачце, не існуе карыстальніка {{user}}. Праверце свой правапіс, ці, магчыма, вам далі няправільную спасылку."
-    diary_entry:
-      posted_by: "Напісана {{link_user}} у {{created}} на {{language_link}}"
-      comment_link: Каментаваць гэты запіс
-      reply_link: Адказаць на гэты запіс
-      comment_count:
-        one: 1 каментар
-        other: "Каментараў: {{count}}"
-      edit_link: Змяніць гэты запіс
-    diary_comment:
-      comment_from: "Каментар {{link_user}} у {{comment_created_at}}"
-  export:
-    start:
-      area_to_export: "Экспартаваць мясцовасць"
-      manually_select: "Выбраць іншую мясцовасць"
-      format_to_export: "Фармат для экспарту"
-      osm_xml_data: "OpenStreetMap XML"
-      mapnik_image: "выява Mapnik"
-      osmarender_image: "выява Osmarender"
-      embeddable_html: "HTML для ўстаўкі"
-      licence: "Ліцэнзія"
-      export_details: 'Дадзеныя праекту OpenStreetMap распаўсюджваюцца па ліцэнзіі <a href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons Attribution-ShareAlike 2.0</a>.'
-      options: "Настаўленні"
-      format: "Фармат"
-      scale: "Маштаб"
-      max: "макс"
-      image_size: "Памер выявы"
-      zoom: "маштаб"
-      add_marker: "Дадаць маркер на карту"
+    no_such_user: 
+      body: Прабачце, не існуе карыстальніка {{user}}. Праверце свой правапіс, ці, магчыма, вам далі няправільную спасылку.
+      heading: Карыстальнік {{user}} не існуе
+      title: Няма такога карыстача
+    view: 
+      leave_a_comment: Пакінуць каментар
+      login: Логін
+      login_to_leave_a_comment: "{{login_link}} каб пакінуць каментар"
+      save_button: Запісаць
+      title: Дзённік карыстальніка | {{user}}
+      user_title: Дзённік {{user}}
+  export: 
+    start: 
+      add_marker: Дадаць маркер на карту
+      area_to_export: Экспартаваць мясцовасць
+      embeddable_html: HTML для ўстаўкі
+      export_button: Экспарт
+      export_details: Дадзеныя праекту OpenStreetMap распаўсюджваюцца па ліцэнзіі <a href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons Attribution-ShareAlike 2.0</a>.
+      format: Фармат
+      format_to_export: Фармат для экспарту
+      image_size: Памер выявы
       latitude: "Шыр:"
+      licence: Ліцэнзія
       longitude: "Даў:"
-      output: "Вывад"
-      paste_html: "Уставіць HTML для убудовы у вэб-сайт"
-      export_button: "Экспарт"
-    start_rjs:
-      export: "Экспарт"
-      drag_a_box: "Расцягніце рамку на карце для выбара мясцовасці"
-      manually_select: "Выбраць іншую мясцовасць"
-      click_add_marker: "Націсніце на карце, каб дадаць маркер"
-      change_marker: "Змяніць пазіцыю маркера"
-      add_marker: "Дадаць маркер на карту"
-      view_larger_map: "Прагледзець большую карту"
-  geocoder:
-    search:
-      title:
-        latlon: 'Рэзультаты з <a href="http://openstreetmap.org/">Internal</a>'
-        us_postcode: 'Рэзультаты з <a href="http://geocoder.us/">Geocoder.us</a>'
-        uk_postcode: 'Рэзультаты з <a href="http://www.npemap.org.uk/">NPEMap / FreeThe Postcode</a>'
-        ca_postcode: 'Рэзультаты з <a href="http://geocoder.ca/">Geocoder.CA</a>'
-        osm_namefinder: 'Рэзультаты з <a href="http://gazetteer.openstreetmap.org/namefinder/">OpenStreetMap Namefinder</a>'
-        geonames: 'Рэзультаты з <a href="http://www.geonames.org/">GeoNames</a>'
-    results:
-      no_results: "Нічога не знойдзена"
-  layouts:
-    welcome_user: "Вітаем, {{user_link}}"
-    home: "дамоў"
-    inbox: "уваходныя ({{count}})"
-    logout: выйсці
-    log_in: увайсці
-    sign_up: зарэгістравацца
-    view: Карта
+      manually_select: Выбраць іншую мясцовасць
+      mapnik_image: выява Mapnik
+      max: макс
+      options: Настаўленні
+      osm_xml_data: OpenStreetMap XML
+      osmarender_image: выява Osmarender
+      output: Вывад
+      paste_html: Уставіць HTML для убудовы у вэб-сайт
+      scale: Маштаб
+      zoom: маштаб
+    start_rjs: 
+      add_marker: Дадаць маркер на карту
+      change_marker: Змяніць пазіцыю маркера
+      click_add_marker: Націсніце на карце, каб дадаць маркер
+      drag_a_box: Расцягніце рамку на карце для выбара мясцовасці
+      export: Экспарт
+      manually_select: Выбраць іншую мясцовасць
+      view_larger_map: Прагледзець большую карту
+  geocoder: 
+    results: 
+      no_results: Нічога не знойдзена
+  layouts: 
+    donate: Падтрымайце OpenStreetMap {{link}} у фонд абнаўлення тэхнікі.
+    donate_link_text: ахвяраваннем
     edit: Змяніць
-    history: Гісторыя
+    edit_tooltip: Рэдагаваць карты
     export: Экспарт
+    export_tooltip: Экспартаваць данныя карты
     gps_traces: GPS Трэкі
-    user_diaries: Дзённікі карыстальнікаў
-    tag_line: Свабодная Wiki-карта свету
-    intro_1: "OpenStreetMap - свабодная для рэдагавання карта усяго свету. Яе ствараюць такія ж людзі, як вы."
-    intro_2: "OpenStreetMap дазваляе вам прагледзець, рэдагаваць і карыстацца геаграфічнымі звесткамі ў любым пункце планеты."
+    gps_traces_tooltip: Працаваць з трэкамі
+    help_wiki: Дапамога і Wiki
+    help_wiki_tooltip: Даведка і сайт Вікі
+    help_wiki_url: http://wiki.openstreetmap.org/wiki/RU:Main_Page
+    history: Гісторыя
+    history_tooltip: Гісторыя змен
+    home: дамоў
+    home_tooltip: Паказаць маю хату
+    inbox: уваходныя ({{count}})
+    inbox_tooltip: 
+      one: У вашай скрыні ёсць 1 новае паведамленне
+      other: У вашай скрыні ёсць {{count}} новых паведамленій
+      zero: У вашай скрыні няма непрачытаных паведамленняў
+    intro_1: OpenStreetMap - свабодная для рэдагавання карта усяго свету. Яе ствараюць такія ж людзі, як вы.
+    intro_2: OpenStreetMap дазваляе вам прагледзець, рэдагаваць і карыстацца геаграфічнымі звесткамі ў любым пункце планеты.
     intro_3: "Хостынг для OpenStreetMap: {{ucl}} і {{bytemark}}."
-    osm_offline: "База дадзеных OpenStreetMap зараз па-за сецівам, таму што праходзіць неабходная тэхнічная праца."
-    osm_read_only: "База дадзеных OpenStreetMap зараз даступная толькі для чытання, таму што праходзіць неабходная тэхнічная праца."
-    donate: "Падтрымайце OpenStreetMap {{link}} у фонд абнаўлення тэхнікі."
-    donate_link_text: ахвяраваннем
-    help_wiki: "Дапамога і Wiki"
-    news_blog: "Блог навінаў"
+    intro_3_ucl: Цэнтр UCL VR
+    log_in: увайсці
+    log_in_tooltip: Увайсці з акаўнтам, які існуе
+    logo: 
+      alt_text: Лагатып OpenStreetMap
+    logout: выйсці
+    logout_tooltip: выйсці
+    make_a_donation: 
+      text: Зрабіць ахвяраванне
+    news_blog: Блог навінаў
+    news_blog_tooltip: Блог навін OpenStreetMap, дармовыя геаданыя, і г.д.
+    osm_offline: База дадзеных OpenStreetMap зараз па-за сецівам, таму што праходзіць неабходная тэхнічная праца.
+    osm_read_only: База дадзеных OpenStreetMap зараз даступная толькі для чытання, таму што праходзіць неабходная тэхнічная праца.
     shop: Крама
-    sotm: 'Наведайце канферэнцыю OpenStreetMap, The State of the Map 2009, 10-12 ліпеня у Амстэрдаме!'
-    alt_donation: Зрабіць ахвяраванне
-  notifier:
-    diary_comment_notification:
+    shop_tooltip: Крама з фірмовай сімволікай OpenStreetMap
+    sign_up: Зарэгістравацца
+    sign_up_tooltip: Стварыць акаўнт для рэдагавання
+    sotm: Наведайце канферэнцыю OpenStreetMap, The State of the Map 2009, 10-12 ліпеня у Амстэрдаме!
+    tag_line: Свабодная Wiki-карта свету
+    user_diaries: Дзённікі карыстальнікаў
+    user_diaries_tooltip: Дзённікі карыстальнікаў
+    view: Карта
+    view_tooltip: Паглядзець карты
+    welcome_user: Вітаем, {{user_link}}
+    welcome_user_link_tooltip: Ваша старонка карыстача
+  map: 
+    coordinates: "Каардынаты:"
+    edit: Змяніць
+    view: Карта
+  message: 
+    inbox: 
+      date: Дата
+      from: Ад
+      my_inbox: Мае уваходныя
+      no_messages_yet: У вас пакуль няма паведамленняў. Чаму б не зкаардэнавацца з  {{people_mapping_nearby_link}}?
+      outbox: зыходныя
+      people_mapping_nearby: людзьмі, што жывуць непадалёку
+      subject: Тэма
+      title: Уваходныя
+      you_have: У вас {{new_count}} новых і {{old_count}} старых паведамленняў
+    mark: 
+      as_read: Паведамленне адмечана прачытаным
+      as_unread: Паведамленне адмечана нечытаным
+    message_summary: 
+      read_button: Адзначыць як прачытанае
+      reply_button: Адказаць
+      unread_button: Адзначыць як нечытанае
+    new: 
+      back_to_inbox: Вярнуцца да уваходных
+      body: Тэкст
+      message_sent: Паведамленне адпраўлена
+      send_button: Даслаць
+      send_message_to: Даслаць новае паведамленне {{name}}
+      subject: Тэма
+      title: Даслаць паведамленне
+    no_such_user: 
+      body: Нажаль, не атрымалася знайсці карыстача або паведамленне з такім імем або ідэнтыфікатарам
+      heading: Няма такога карыстальніка/паведамленні
+      title: Няма такога карыстальніка/паведамленні
+    outbox: 
+      date: Дата
+      inbox: уваходныя
+      my_inbox: Мае {{inbox_link}}
+      no_sent_messages: У вас пакуль няма дасланых паведамленняў. Чаму б не зкаардэнавацца з {{people_mapping_nearby_link}}?
+      outbox: зыходныя
+      people_mapping_nearby: людзьмі, што жывуць непадалёку
+      subject: Тэма
+      title: Зыходныя
+      to: Каму
+      you_have_sent_messages: У вас {{count}} дасланых паведамленняў
+    read: 
+      back_to_inbox: Вярнуцца да ўваходных
+      back_to_outbox: Вярнуцца да зыходных
+      date: Дата
+      from: Ад
+      reading_your_messages: Чытанне вашых паведамленняў
+      reading_your_sent_messages: Чытанне вашых дасланых паведамленняў
+      reply_button: Адказаць
+      subject: Тэма
+      title: Прачытаць паведамленне
+      to: Камууу
+      unread_button: Адзначыць, як непрачытанае
+  notifier: 
+    diary_comment_notification: 
       banner1: "*            Калі ласка, не адказвайце на гэтае паведамленне.             *"
       banner2: "*             Карыстайцеся сайтам OpenStreetMap для адказу.               *"
-      hi: "Вітанні, {{to_user}},"
+      footer: Вы можаце прагледзець каментар на {{readurl}} і пракаментаваць на {{commenturl}} ці адказаць на {{replyurl}}
       header: "{{from_user}} пракаментаваў ваш запіс у дзённіку на OpenStreetMap з тэмай {{subject}}:"
-      footer: "Вы можаце прагледзець каментар на {{readurl}} і пракаментаваць на {{commenturl}} ці адказаць на {{replyurl}}"
-    friend_notification:
+      hi: Вітанні, {{to_user}},
+      subject: "[OpenStreetMap] {{user}} пакінуў каментар у вашым дзённіку"
+    email_confirm: 
+      subject: "[OpenStreetMap] Пацвердзіце ваш адрас электроннай пошты"
+    email_confirm_html: 
+      click_the_link: Калі гэта вы, то перайдзіце па спасылцы, размешчанай ніжэй, каб пацвердзіць змену.
+      greeting: Добры дзень,
+      hopefully_you: "Хтосьці (спадзяемся, што вы) жадае змяніць свой адрас электроннай пошты ў {{server_url}} на адрас: {{new_address}}."
+    email_confirm_plain: 
+      click_the_link: Калі гэта вы, то перайдзіце па спасылцы, размешчанай ніжэй, каб пацвердзіць змену.
+      greeting: Добры дзень,
+      hopefully_you_1: Хтосьці (спадзяемся, што вы) жадае змяніць свой адрас электроннай пошты ў
+      hopefully_you_2: "{{server_url}} на адрас: {{new_address}}."
+    friend_notification: 
       had_added_you: "{{user}} дадаў вас, як сябра, на OpenStreetMap."
-      see_their_profile: "Вы можаце прагледзець профіль на {{userurl}} і дадаць, як сябра, у адказ, калі хочаце."
-    signup_confirm_plain:
-      greeting: "Вітанні!"
-      hopefully_you: "Нехта (спадзяемся, вы) хоча стварць рахунак "
-      # next two translations run-on : please word wrap appropriately
-      click_the_link_1: "Калі гэта вы, вітаем! Калі ласка, націсніце спасылку ніжэй, каб "
-      click_the_link_2: "пацвердзіць ваш рахунак і прачытаць больш пра OpenStreetMap."
+      see_their_profile: Вы можаце прагледзець профіль на {{userurl}} і дадаць, як сябра, у адказ, калі хочаце.
+      subject: "[OpenStreetMap] {{user}} дадаў вас у спіс сваіх сяброў"
+    gpx_notification: 
+      and_no_tags: і без тэгаў.
+      and_the_tags: "і наступнымі тэгамі:"
+      failure: 
+        failed_to_import: "збой імпарту. Адбылася памылка:"
+        more_info_1: Дадатковую інфармацыю аб збоі імпарту GPX і аб тым, як пазбегнуць
+        more_info_2: "збой,  можна знайсці тут:"
+        subject: "[OpenStreetMap] Збой імпарту GPX"
+      greeting: Прывітанне,
+      success: 
+        loaded_successfully: " |"
+        subject: "[OpenStreetMap] Імпарт GPX мінуў паспяхова"
+      with_description: з апісаннем
+      your_gpx_file: Гэта выглядае як ваш файл GPX
+    lost_password: 
+      subject: "[OpenStreetMap] Запыт на змену пароля"
+    lost_password_html: 
+      click_the_link: Калі гэта вы, калі ласка, перайдзіце па спасылцы, паказанай ніжэй, каб змяніць ваш пароль.
+      greeting: Прывітанне,
+      hopefully_you: Хтосьці (спадзяемся, што вы) запытаў змену пароля для гэтага адрасу электроннай пошты, зарэгістраванага на openstreetmap.org.
+    lost_password_plain: 
+      click_the_link: Калі гэта вы, калі ласка, перайдзіце па спасылцы, паказанай ніжэй, каб змяніць ваш пароль.
+      greeting: Прывітанне,
+      hopefully_you_1: Хтосьці (спадзяемся, што вы) запытаў змену пароля для гэтага
+      hopefully_you_2: адраса электроннай пошты, зарэгістраванага на openstreetmap.org.
+    message_notification: 
+      banner1: "* Калі ласка, не адказвайце на гэтае паведамленне. *"
+      banner2: "* Для адказу выкарыстайце сайт OpenStreetMap. *"
+      footer1: Вы можаце таксама прачытаць паведамленне - {{readurl}}
+      footer2: і вы можаце адказаць на {{replyurl}}
+      header: "{{from_user}} адправіў вам паведамленне з тэмай {{subject}} праз OpenStreetMap:"
+      hi: Прывітанне, {{to_user}},
+      subject: "[OpenStreetMap] {{user}} даслаў вам новае паведамленне"
+    signup_confirm: 
+      subject: "[OpenStreetMap] Пацвердзіце ваш адрас электроннай пошты"
+    signup_confirm_html: 
+      click_the_link: Калі гэта вы, вітаем! Калі ласка, націсніце спасылку ніжэй, каб пацвердзіць ваш рахунак і прачытаць больш пра OpenStreetMap
+      current_user: Спіс бягучых карыстальнікаў па катэгорыях іх геаграфічнага знаходжання даступны на  <a href="http://wiki.openstreetmap.org/wiki/Category:Users_by_geographical_region">Category:Users_by_geographical_region</a>.
+      get_reading: Пачытайце пра OpenStreetMap <a href="http://wiki.openstreetmap.org/wiki/Beginners%27_Guide">на wiki</p> ці  <a href="http://www.opengeodata.org/">блогу opengeodata</a>, на якім таксама ёсць <a href="http://www.opengeodata.org/?cat=13">подкасты</a>!
+      greeting: Вітанні!
+      hopefully_you: Нехта (спадзяемся, вы) хоча стварць рахунак
+      introductory_video: Вы можаце прагледзець {{introductory_video_link}}.
+      more_videos: Яшчэ больш {{more_videos_link}}.
+      more_videos_here: відэа тут
+      user_wiki_page: Рэкамендуем стварыць старонку карыстальніка на wiki, якая будзе уключаць цэтлікі катэгорый, якія адзначаюць, дзе вы знаходзіцеся, напрыклад <a href="http://wiki.openstreetmap.org/wiki/Category:Users_in_London">[[Category:Users_in_London]]</a>.
+      video_to_openstreetmap: уводнае відэа пра OpenStreetMap
+      wiki_signup: Вы таксама можаце захацець <a href="http://wiki.openstreetmap.org/index.php?title=Special:Userlogin&type=signup&returnto=Main_Page">зарэгістравацца на  OpenStreetMap wiki</a>.
+    signup_confirm_plain: 
+      click_the_link_1: Калі гэта вы, вітаем! Калі ласка, націсніце спасылку ніжэй, каб
+      click_the_link_2: пацвердзіць ваш рахунак і прачытаць больш пра OpenStreetMap.
+      current_user_1: Спіс бягучых карыстальнікаў па катэгорыях іх геаграфічнага знаходжання
+      current_user_2: "даступны на:"
+      greeting: Вітанні!
+      hopefully_you: Нехта (спадзяемся, вы) хоча стварць рахунак
       introductory_video: "Вы можаце прагледзець уводнае відэа пра OpenStreetMap тут:"
       more_videos: "І яшчэ больш відэа тут:"
-      the_wiki: "Пачытайце пра OpenStreetMap на wiki:"
       opengeodata: "OpenGeoData.org - афіцыйны блог OpenStreetMap, і таксама мае подкасты:"
+      the_wiki: "Пачытайце пра OpenStreetMap на wiki:"
+      the_wiki_url: http://wiki.openstreetmap.org/wiki/RU:Beginners_Guide
+      user_wiki_1: Рэкамендуем стварыць старонку карыстальніка на wiki, якая будзе уключаць цэтлікі катэгорый,
+      user_wiki_2: якія адзначаюць, дзе вы знаходзіцеся, напрыклад [[Category:Users_in_London]].
       wiki_signup: "Вы таксама можаце захацець зарэгістравацца на  OpenStreetMap wiki на:"
-      # next four translations are in pairs : please word wrap appropriately
-      user_wiki_1: "Рэкамендуем стварыць старонку карыстальніка на wiki, якая будзе уключаць цэтлікі катэгорый,"
-      user_wiki_2: "якія адзначаюць, дзе вы знаходзіцеся, напрыклад [[Category:Users_in_London]]."
-      current_user_1: "Спіс бягучых карыстальнікаў па катэгорыях іх геаграфічнага знаходжання"
-      current_user_2: "даступны на:"
-    signup_confirm_html:
-      greeting: "Вітанні!"
-      hopefully_you: "Нехта (спадзяемся, вы) хоча стварць рахунак"
-      click_the_link: "Калі гэта вы, вітаем! Калі ласка, націсніце спасылку ніжэй, каб пацвердзіць ваш рахунак і прачытаць больш пра OpenStreetMap"
-      introductory_video: "Вы можаце прагледзець {{introductory_video_link}}."
-      video_to_openstreetmap: "уводнае відэа пра OpenStreetMap"
-      more_videos: "Яшчэ больш {{more_videos_link}}."
-      more_videos_here: "відэа тут"
-      get_reading: 'Пачытайце пра OpenStreetMap <a href="http://wiki.openstreetmap.org/wiki/Beginners%27_Guide">на wiki</a> ці <a href="http://www.opengeodata.org/">блогу opengeodata</a>, на якім таксама ёсць <a href="http://www.opengeodata.org/?cat=13">подкасты</a>!'
-      wiki_signup: 'Вы таксама можаце захацець <a href="http://wiki.openstreetmap.org/index.php?title=Special:Userlogin&type=signup&returnto=Main_Page">зарэгістравацца на  OpenStreetMap wiki</a>.'
-      user_wiki_page: 'Рэкамендуем стварыць старонку карыстальніка на wiki, якая будзе уключаць цэтлікі катэгорый, якія адзначаюць, дзе вы знаходзіцеся, напрыклад <a href="http://wiki.openstreetmap.org/wiki/Category:Users_in_London">[[Category:Users_in_London]]</a>.'
-      current_user: 'Спіс бягучых карыстальнікаў па катэгорыях іх геаграфічнага знаходжання даступны на  <a href="http://wiki.openstreetmap.org/wiki/Category:Users_by_geographical_region">Category:Users_by_geographical_region</a>.'
-  message:
-    inbox:
-      title: "Уваходныя"
-      my_inbox: "Мае уваходныя"
-      outbox: "зыходныя"
-      you_have: "У вас {{new_count}} новых і {{old_count}} старых паведамленняў"
-      from: "Ад"
-      subject: "Тэма"
-      date: "Дата"
-      no_messages_yet: "У вас пакуль няма паведамленняў. Чаму б не зкаардэнавацца з  {{people_mapping_nearby_link}}?"
-      people_mapping_nearby: "людзьмі, што жывуць непадалёку" 
-    message_summary:
-      unread_button: "Адзначыць як нечытанае"
-      read_button: "Адзначыць як прачытанае"
-      reply_button: "Адказаць"
-    new:
-      title: "Даслаць паведамленне"
-      send_message_to: "Даслаць новае паведамленне {{name}}"
-      subject: "Тэма"
-      body: "Тэкст"
-      send_button: "Даслаць"
-      back_to_inbox: "Вярнуцца да уваходных"
-      message_sent: "Паведамленне адпраўлена"
-    no_such_user:
-      no_such_user: "Няма такога карыстальніка ці паведамлення"
-      sorry: "Прабачце, няма такога карыстальніка ці паведамлення з такім нумарам"
-    outbox: 
-      title: "Зыходныя"
-      my_inbox: "Мае {{inbox_link}}"
-      inbox: "уваходныя"
-      outbox: "зыходныя"
-      you_have_sent_messages: "У вас {{sent_count}} дасланых паведамленняў"
-      to: "Каму"
-      subject: "Тэма"
-      date: "Дата"
-      no_sent_messages: "У вас пакуль няма дасланых паведамленняў. Чаму б не зкаардэнавацца з {{people_mapping_nearby_link}}?"
-      people_mapping_nearby: "людзьмі, што жывуць непадалёку"
-    read:
-      title: "Прачытаць паведамленне"
-      reading_your_messages: "Чытанне вашых паведамленняў"
-      from: "Ад"
-      subject: "Тэма"
-      date: "Дата"
-      reply_button: "Адказаць"
-      unread_button: "Адзначыць, як непрачытанае"
-      back_to_inbox: "Вярнуцца да ўваходных"
-      reading_your_sent_messages: "Чытанне вашых дасланых паведамленняў"
-      to: "Камууу"
-      back_to_outbox: "Вярнуцца да зыходных"
-    mark:
-      as_read: "Паведамленне адмечана прачытаным"
-      as_unread: "Паведамленне адмечана нечытаным"
-  site:
-    index:
-      js_1: "Вы карыстаецеся вандроўнікам без падтрымкі javascript."
-      js_2: "OpenStreetMap выкарыстоўвае javascript для адлюстравання карты на сайце."
-      js_3: 'Вы можаце паспрабаваць выкарыстаць <a href="http://tah.openstreetmap.org/Browse/">статычны агляд Tiles@Home</a> калі не можаце уключыць javascript.'
+      wiki_signup_url: http://wiki.openstreetmap.org/index.php?title=Special:UserLogin&type=signup&returnto=RU%3AMain_Page
+  site: 
+    edit: 
+      not_public: Вы не дазволілі зрабіць усе вашыя змены публічнымі.
+      potlatch_unsaved_changes: You have unsaved changes. (To save in Potlatch, you should deselect the current шлях ці point, if editing in list mode, ці click save if you have a save button.)
+    index: 
+      js_1: Вы карыстаецеся вандроўнікам без падтрымкі JavaScript.
+      js_2: OpenStreetMap выкарыстоўвае JavaScript для адлюстравання карты на сайце.
+      js_3: Вы можаце паспрабаваць выкарыстаць <a href="http://tah.openstreetmap.org/Browse/">статычны агляд Tiles@Home</a> калі не можаце уключыць JavaScript.
+      license: 
+        notice: Ліцэнзіруецца на ўмовах {{license_name}} праектам {{project_name}} і яго карыстальнікамі.
+        project_name: OpenStreetMap
       permalink: Спасылка сюды
-      license:
-        notice: "Ліцэнзіруецца на ўмовах {{license_name}} праектам {{project_name}} і яго карыстальнікамі."
-        license_name: "Creative Commons Attribution-Share Alike 2.0"
-        project_name: "OpenStreetMap"
-    edit:
-      not_public: "Вы не дазволілі зрабіць усе вашыя змены публічнымі."
-      not_public_description: "You can no longer edit the map unless you do so. You can set your edits as public from your {{user_page}}."
-      user_page_link: user page
-      anon_edits: "({{link}})"
-      anon_edits_link: "http://wiki.openstreetmap.org/wiki/Disabling_anonymous_edits"
-      anon_edits_link_text: "Find out why this is the case."
-      flash_player_required: 'You need a Flash player to use Potlatch, the OpenStreetMap Flash editor. You can <a href="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">download Flash Player from Adobe.com</a>. <a href="http://wiki.openstreetmap.org/wiki/Editing">Several other options</a> are also available for editing OpenStreetMap.'
-      potlatch_unsaved_changes: "You have unsaved changes. (To save in Potlatch, you should deselect the current шлях ці point, if editing in list mode, ці click save if you have a save button.)"
-    sidebar:
-      search_results: Search Results
-      close: Close
-    search:
+    key: 
+      map_key: Ключ карты
+      map_key_tooltip: Легенда для рэндэрынгу mapnik на гэтым узроўні маштабу
+    search: 
       search: Пошук
-      where_am_i: "Дзе я?"
-      submit_text: "=>"
       search_help: "напрыклад: 'Мінск', 'Regent Street, Cambridge', 'CB2 5AQ', ці 'post offices near Lünen' <a href='http://wiki.openstreetmap.org/wiki/Search'>больш прыкладаў...</a>"
-    key:
-      map_key: "Ключ карты"
-  trace:
-    create:
-      upload_trace: "Зацягнуць GPS-трэк"
-      trace_uploaded: "Ваш GPX-файл быў зацягнуты і чакае ўстаўкі ў базу дадзеных. Гэта звычайна робіцца не больш за паўгадзіны. Вы атрымаеце працврджанне аб заканчэнні працэсу па электроннай пошце"
-    edit:
+      submit_text: =>
+      where_am_i: Дзе я?
+  trace: 
+    create: 
+      trace_uploaded: Ваш GPX-файл быў зацягнуты і чакае ўстаўкі ў базу дадзеных. Гэта звычайна робіцца не больш за паўгадзіны. Вы атрымаеце працврджанне аб заканчэнні працэсу па электроннай пошце
+      upload_trace: Зацягнуць GPS-трэк
+    delete: 
+      scheduled_for_deletion: Трэк запланаваны на выдаленне
+    edit: 
+      description: "Апісанне:"
+      edit: змяніць
       filename: "Назва файла:"
-      uploaded_at: "Зацягнуты:"
+      owner: "Уладальнік:"
       points: "Пунктаў:"
+      save_button: Запісаць змены
       start_coord: "Каардынаты пачатку:"
-      edit: "змяніць"
-      owner: "Уладальнік:"
-      description: "Апісанне:"
       tags: "Цэтлікі:"
-      save_button: "Запісаць змены"
-    no_such_user:
-      no_such_user: "Прабачце, карыстальнік {{name}} не знойдзены. Калі ласка, праверце свой правапіс, ці, магчыма, вам далі няправільную спасылку."
-    trace_form:
-      upload_gpx: "Зацягнуць GPX-файл"
-      description: "Апісанне"
-      tags: "Цэтлікі"
-      public: "Публічны?"
-      upload_button: "Зацягнуць"
-      help: "Дапамога"
-    trace_header:
-      see_just_your_traces: "Бачыць толькі свае трэкі, ці дадаць трэк"
-      see_all_traces: "Бачыць усе трэкі"
-      see_your_traces: "Бачыць усе свае трэкі"
-      traces_waiting: "У вас {{count}} трэкаў у чарзе. Калі ласка, пачакайце, пакуль яны будуць апрацаваныя, каб не блакірваць чаргу для астатніх карстальнікаў."
-    trace_optionals:
-      tags: "Цэтлікі"
-    view:
-      pending: "У ЧАРЗЕ"
+      uploaded_at: "Зацягнуты:"
+    list: 
+      public_traces: Публічныя GPS-трэкі
+      public_traces_from: Публічныя GPS-трэкі карыстальніка {{user}}
+      tagged_with: " адмечана як {{tags}}"
+      your_traces: Вашыя GPS-трэкі
+    make_public: 
+      made_public: Трэк зроблены публічным
+    no_such_user: 
+      body: Выбачыце, карыстальніка з імем {{user}} не існуе. Калі ласка, праверце правільнасць напісання. Магчыма спасылка, па якой вы дашлі, няслушная.
+      heading: Карыстач {{user}} не існуе
+      title: Няма такога карыстальніка
+    trace: 
+      ago: "{{time_in_words_ago}} таму"
+      by: з дапамогай
+      count_points: "{{count}} пунктаў"
+      edit: змяніць
+      edit_map: Змяніць карту
+      in: у
+      map: карта
+      more: яшчэ
+      pending: У ЧАРЗЕ
+      private: ПРЫВАТНЫ
+      public: ПУБЛІЧНЫ
+      trace_details: Прагледзець уласцівасці трэку
+      view_map: Прагледзець карту
+    trace_form: 
+      description: Апісанне
+      help: Дапамога
+      help_url: http://wiki.openstreetmap.org/wiki/RU:Upload
+      tags: Цэтлікі
+      upload_button: Зацягнуць
+      upload_gpx: Зацягнуць GPX-файл
+    trace_header: 
+      see_all_traces: Бачыць усе трэкі
+      see_just_your_traces: Бачыць толькі свае трэкі, ці дадаць трэк
+      see_your_traces: Бачыць усе свае трэкі
+      traces_waiting: У вас {{count}} трэкаў у чарзе. Калі ласка, пачакайце, пакуль яны будуць апрацаваныя, каб не блакірваць чаргу для астатніх карстальнікаў.
+    trace_optionals: 
+      tags: Цэтлікі
+    trace_paging_nav: 
+      of: з
+      showing: Прагляд старонкі
+    view: 
+      delete_track: Выдаліць гэты трэк
+      description: "Апісанне:"
+      download: сцягнуць
+      edit: змяніць
+      edit_track: Змяніць бягучы трэк
       filename: "Назва файла:"
-      download: "сцягнуць"
-      uploaded: "Зацягнуты:"
+      map: карта
+      none: Няма
+      owner: "Уладальнік:"
+      pending: У ЧАРЗЕ
       points: "Пункты:"
       start_coordinates: "Каардынаты пачатку:"
-      map: "карта"
-      edit: "змяніць"
-      owner: "Уладальнік:"
-      description: "Апісанне:"
-      tags: "Цэтлікі"
-      none: "Няма"
-      make_public: "Зрабіць гэты трэк агульнадаступным назаўсёды"
-      edit_track: "Змяніць бягучы трэк"
-      delete_track: "Выдаліць гэты трэк"
-      heading: "Прагляд трэку {{name}}"
-      trace_not_found: "Трэк не знойдзены!"
-    trace_paging_nav:
-      showing: "Прагляд старонкі"
-      of: "з"
-    trace:
-      pending: "У ЧАРЗЕ"
-      count_points: "{{count}} пунктаў"
-      ago: "{{time_in_words_ago}} таму"
-      more: "яшчэ"
-      trace_details: "Прагледзець уласцівасці трэку"
-      view_map: "Прагледзець карту"
-      edit: "змяніць"
-      edit_map: "Змяніць карту"
-      public: "ПУБЛІЧНЫ"
-      private: "ПРЫВАТНЫ"
-      by: " "
-      in: "у"
-      map: "карта"
-    list:
-      public_traces: "Публічныя GPS-трэкі"
-      your_traces: "Вашыя GPS-трэкі"
-      public_traces_from: "Публічныя GPS-трэкі карыстальніка {{user}}"
-      tagged_with: " адмечана як {{tags}}"
-    delete:
-      scheduled_for_deletion: "Трэк запланаваны на выдаленне"
-    make_public:
-      made_public: "Трэк зроблены публічным"
-  user:
-    login:
-      title: "Уваход"
-      heading: "Уваход"
-      please login: "Калі ласка, увайдзіце ці {{create_user_link}}."
-      create_account: "стварыце рахунак"
-      email or username: "Пошта ці імя карыстальніка: "
-      password: "Пароль: "
-      lost password link: "Згубліл пароль?"
-      login_button: "Увайсці"
-      account not active: "Прабачце, ваш рахунак пакуль не актывізаваны.<br>Калі ласка, націсніце на адпаведную спасылку ў лісце пацверджання рахунку, каб актывізаваць яго."
-      auth failure: "Прабачце, немагчыма увайсці з такім адрасам і паролем."
-    lost_password:
-      title: "згублены пароль"
-      heading: "Забылі пароль?"
+      tags: Цэтлікі
+      trace_not_found: Трэк не знойдзены!
+      uploaded: "Зацягнуты:"
+  user: 
+    account: 
+      email never displayed publicly: (ніколі нікому не паказваецца)
+      flash update success: Звесткі аб карыстальніку паспяхова абноўленыя.
+      flash update success confirm needed: Звесткі аб карыстальніку паспяхова абноўленыя. Праверце сваю пошту, вам павінны прыйсці запыт на пацверджанне змены адрасу.
+      home location: "Ваша месцазнаходжанне:"
+      latitude: "Шырата:"
+      longitude: "Даўгата:"
+      make edits public button: Зрабіць усе мае змены публічнымі
+      my settings: Мае настаўленні
+      no home location: Вы не выбралі вашае асноўнае месцазнаходжанне.
+      preferred languages: "Абраныя мовы:"
+      profile description: "Апісанне профілю:"
+      public editing: 
+        disabled: Адключана. Вы не можаце больш рэдагаваць, але ўсе ранейшыя змены ананімныя.
+        disabled link text: чаму я не магу рэдагаваць?
+        enabled: Уключана. Вы - не ананімны і можаце рэдагаваць дадзеныя.
+        enabled link: http://wiki.openstreetmap.org/wiki/Disabling_anonymous_edits
+        enabled link text: што гэта?
+        heading: "Публічнае рэдагаванне:"
+      return to profile: Вярнуцца да профілю
+      save changes button: Запісаць змены
+      title: Змяніць рахунак
+      update home location on click: Абнавіць каардэнаты, калі я пстрыкну па карце?
+    confirm: 
+      button: Пацвердзіць
+      failure: Рахунак карыстальніка з такім ключом ужо пацверджаны.
+      heading: Пацверджанне рахунку
+      press confirm button: Націсніце кнопку, каб актывізаваць рахунак.
+      success: Рахунак пацверджаны, дзякуй за рэгістрацыю!
+    confirm_email: 
+      button: Пацвердзіць
+      failure: Паштовы адрас ужо быў пацаерджаны гэтым ключом.
+      heading: Пацвердзіць змену паштовага адрасу
+      press confirm button: Націсніце кнопку, каб пацвердзіць ваш новы паштовы адрас.
+      success: Ваш адрас пацверджаны, дзякуй за рэгістрацыю!
+    friend_map: 
+      nearby mapper: "Карыстальнік: [[nearby_user]]"
+      your location: Ваша месцазнаходжанне
+    go_public: 
+      flash success: Усе вашыя змены цяпер публічныя, і вам цяпер дазволена рэдагаванне
+    login: 
+      account not active: Прабачце, ваш рахунак пакуль не актывізаваны.<br />Калі ласка, націсніце на адпаведную спасылку ў лісце пацверджання рахунку, каб актывізаваць яго.
+      auth failure: Прабачце, немагчыма увайсці з такім адрасам і паролем.
+      create_account: стварыце рахунак
+      email or username: "Пошта ці імя карыстальніка:"
+      heading: Уваход
+      login_button: Увайсці
+      lost password link: Згубліл пароль?
+      password: "Пароль:"
+      please login: Калі ласка, увайдзіце ці {{create_user_link}}.
+      title: Уваход
+    lost_password: 
+      email address: "Паштовы адрас:"
+      heading: Забылі пароль?
+      new password button: Выслаць мне новы пароль
+      notice email cannot find: Немагчыма знайсці гэтакі паштовы адрас, прабачце.
+      notice email on way: Жаль, што вы яго згубілі :-( але ліст ужо адпраўлены, і вы хутка зможаце яго скінуць.
+      title: згублены пароль
+    make_friend: 
+      already_a_friend: Вы ўжо сябруеце з {{name}}.
+      failed: Прабачце, немагчыма дадаць {{name}} у якасці сябра.
+      success: "{{name}} цяпер ваш сябар."
+    new: 
+      confirm email address: "Пацверджанне паштовага адрасу:"
+      confirm password: "Пацверджанне паролю:"
+      contact_webmaster: Калі ласка, спішыцеся з <a href="mailto:webmaster@openstreetmap.org">вэм-майстрам</a> каб стварыць вам рахунак - мы паспрабуем выдаць вам рахунак як мага хутчэй.
+      display name: "Бачнае імя:"
       email address: "Паштовы адрас:"
-      new password button: "Выслаць мне новы пароль"
-      notice email on way: "Жаль, што вы яго згубілі :-( але ліст ужо адпраўлены, і вы хутка зможаце яго скінуць."
-      notice email cannot find: "Немагчыма знайсці гэтакі паштовы адрас, прабачце."
-    reset_password:
-      title: "скінуць пароль"
-      flash changed check mail: "Ваш пароль быў скінуты і ўжо на шляху да вашай пошты :-)"
-      flash token bad: "Не знайшоў такі ключ, можа, праверце URL?"
-    new:
-      title: "Стварыць рахунак"
-      heading: "Стварыць рахунак карыстальніка"
-      no_auto_account_create: "На жаль, мы не можам стварыць для вас рахунак аўтаматычна."
-      contact_webmaster: 'Калі ласка, спішыцеся з <a href="mailto:webmaster@openstreetmap.org">вэм-майстрам</a> каб стварыць вам рахунак - мы паспрабуем выдаць вам рахунак як мага хутчэй. '
-      fill_form: "Запоўніце форму, і мы вышлем вам ліст для актывізацыі рахунка."
-      license_agreement: 'Ствараючы рахунак, вы згаджаецеся, што ўсё, што вы зацягнеце на openstreetmap.org і ўсе дадзеныя, створаныя пры выкарыстанні любой утыліты, што звязваецца з openstreetmap.org будуць ліцэнзіравацца (невыключна) на ўмовах <a href="http://creativecommons.org/licenses/by-sa/2.0/">гэтай ліцэнзіі Creative Commons (by-sa)</a>.'
-      email address: "Паштовы адрас: "
-      confirm email address: "Пацверджанне паштовага адрасу: "
-      not displayed publicly: 'Не паказваецца астатнім (глядзіце <a href="http://wiki.openstreetmap.org/wiki/Privacy_Policy" title="палітыка неразглашэння на wiki, у тым ліку секцыя пра паштовыя адрасы">палітыку неразглашэння</a>)'
-      display name: "Бачнае імя: "
-      password: "Пароль: "
-      confirm password: "Пацверджанне паролю: "
+      fill_form: Запоўніце форму, і мы вышлем вам ліст для актывізацыі рахунка.
+      flash create success message: Карыстальнік паспяхова створаны. Праверце сваю паштовую скрыню - у ёй павыінен быць код пацверджання, і вы зможаце пачаць маляваць наваі зараз! :-)<br /><br />Калі ласка, заўважце, што вы не можаце увайсці, пакуль вы не пацвердзілі свой паштовы адрас.<br /><br />Калі вы карыстаецеся супрацьспамавай сістэмай, якая рассылае запыты на пацверджанне, калі ласка, унясіце ў белы спіс webmaster@openstreetmap.org, бо мы не можам адказваць на запыты пацверджанняў.
+      heading: Стварыць рахунак карыстальніка
+      license_agreement: Ствараючы рахунак, вы згаджаецеся, што ўсё, што вы зацягнеце на openstreetmap.org і ўсе дадзеныя, створаныя пры выкарыстанні любой утыліты, што звязваецца з openstreetmap.org будуць ліцэнзіравацца (невыключна) на ўмовах <a href="http://creativecommons.org/licenses/by-sa/2.0/">гэтай ліцэнзіі Creative Commons (by-sa)</a>.
+      no_auto_account_create: На жаль, мы не можам стварыць для вас рахунак аўтаматычна.
+      not displayed publicly: Не паказваецца астатнім (глядзіце <a href="http://wiki.openstreetmap.org/wiki/Privacy_Policy" title="палітыка неразглашэння на wiki, у тым ліку секцыя пра паштовыя адрасы">палітыку неразглашэння</a>)
+      password: "Пароль:"
       signup: Зарэгістравацца
-      flash create success message: "Карыстальнік паспяхова створаны. Праверце сваю паштовую скрыню - у ёй павыінен быць код пацверджання, і вы зможаце пачаць маляваць наваі зараз! :-)<br /><br />Калі ласка, заўважце, што вы не можаце увайсці, пакуль вы не пацвердзілі свой паштовы адрас.<br /><br />Калі вы карыстаецеся супрацьспамавай сістэмай, якая рассылае запыты на пацверджанне, калі ласка, унясіце ў белы спіс webmaster@openstreetmap.org, бо мы не можам адказваць на запыты пацверджанняў."
-    no_such_user:
-      body: "Прабачце, карыстальнік {{user}} не знойдзены. Please check your spelling, Калі ласка, праверце свой правапіс, ці, магчыма, вам далі няправільную спасылку."
-    view:
+      title: Стварыць рахунак
+    no_such_user: 
+      body: Прабачце, карыстальнік {{user}} не знойдзены. Please check your spelling, Калі ласка, праверце свой правапіс, ці, магчыма, вам далі няправільную спасылку.
+      heading: Карыстальнік {{user}} не існуе
+      title: Няма такога карыстальніка
+    remove_friend: 
+      not_a_friend: "{{name}} не з'яўляецца вашым сябрам."
+      success: "{{name} выдалены са спіса сяброў."
+    reset_password: 
+      flash token bad: Не знайшоў такі ключ, можа, праверце URL?
+      title: скінуць пароль
+    set_home: 
+      flash success: Дамашняе месцазнаходжанне паспяхова запісана
+    view: 
+      add as friend: дадаць у сябры
+      add image: Дадаць выяву
+      ago: ({{time_in_words_ago}} таму)
+      change your settings: змяніць вашыя настаўленні
+      delete image: Выдаліць выяву
+      description: Апісанне
+      diary: дзённік
+      edits: змены
+      if set location: Калі вы вызначыце сваё месцазнаходжанне, ніжэй з'явіцца прыгожая карта і ўсё такое. Вы можаце вызначыць сваё месцазнаходжанне на старонцы {{settings_link}}.
+      km away: "{{count}} км ад вас"
+      mapper since: "Малюе карту з:"
       my diary: мой дзённік
-      new diary entry: новы запіс у дзённіку
       my edits: мае змены
-      my traces: мае трэкі
       my settings: мае настаўленні
+      my traces: мае трэкі
+      nearby users: "Карыстальнікі непадалёку:"
+      new diary entry: новы запіс у дзённіку
+      no friends: Вы пакуль не дадалі нікога ў сябры.
+      no home location: Карыстальнік не паказаў сваё месцазнаходжанне.
+      no nearby users: Пакуль няма карыстальнікаў, што адмецілі сваё месцазнаходжанне непадалёку.
+      remove as friend: выдаліць з сяброў
       send message: даслаць паведамленне
-      diary: дзённік
-      edits: змены
+      settings_link_text: настаўленняў
       traces: трэкі
-      remove as friend: выдаліць з сяброў
-      add as friend: дадаць у сябры
-      mapper since: "Малюе карту з: "
-      ago: "({{time_in_words_ago}} таму)"
-      user image heading: Выява карыстальніка
-      delete image: Выдаліць выяву
       upload an image: Зацягнуць выяву
-      add image: Дадаць выяву
-      description: Апісанне
+      user image heading: Выява карыстальніка
       user location: Месцазнаходжанне
-      no home location: "Карыстальнік не паказаў сваё месцазнаходжанне."
-      if set location: "Калі вы вызначыце сваё месцазнаходжанне, ніжэй з'явіцца прыгожая карта і ўсё такое. Вы можаце вызначыць сваё месцазнаходжанне на старонцы {{settings_link}}."
-      settings_link_text: настаўленняў
       your friends: Вашыя сябры
-      no friends: Вы пакуль не дадалі нікога ў сябры.
-      km away: "{{count}} км ад вас"
-      nearby users: "Карыстальнікі непадалёку: "
-      no nearby users: "Пакуль няма карыстальнікаў, што адмецілі сваё месцазнаходжанне непадалёку."
-      change your settings: змяніць вашыя настаўленні
-    friend_map:
-      your location: Ваша месцазнаходжанне
-      nearby mapper: "Карыстальнік: "
-    account:
-      title: "Змяніць рахунак"
-      my settings: Мае настаўленні
-      email never displayed publicly: "(ніколі нікому не паказваецца)"
-      public editing:
-        heading: "Публічнае рэдагаванне: "
-        enabled: "Уключана. Вы - не ананімны і можаце рэдагаваць дадзеныя."
-        enabled link: "http://wiki.openstreetmap.org/wiki/Disabling_anonymous_edits"
-        enabled link text: "што гэта?"
-        disabled: "Адключана. Вы не можаце больш рэдагаваць, але ўсе ранейшыя змены ананімныя."
-        disabled link text: "чаму я не магу рэдагаваць?"
-      profile description: "Апісанне профілю: "
-      preferred languages: "Абраныя мовы: "
-      home location: "Ваша месцазнаходжанне: "
-      no home location: "Вы не выбралі вашае асноўнае месцазнаходжанне."
-      latitude: "Шырата: "
-      longitude: "Даўгата: "
-      update home location on click: "Абнавіць каардэнаты, калі я пстрыкну па карце?"
-      save changes button: Запісаць змены
-      make edits public button: Зрабіць усе мае змены публічнымі
-      return to profile: Вярнуцца да профілю
-      flash update success confirm needed: "Звесткі аб карыстальніку паспяхова абноўленыя. Праверце сваю пошту, вам павінны прыйсці запыт на пацверджанне змены адрасу."
-      flash update success: "Звесткі аб карыстальніку паспяхова абноўленыя."
-    confirm:
-      heading: Пацверджанне рахунку
-      press confirm button: "Націсніце кнопку, каб актывізаваць рахунак."
-      button: Пацвердзіць
-      success: "Рахунак пацверджаны, дзякуй за рэгістрацыю!"
-      failure: "Рахунак карыстальніка з такім ключом ужо пацверджаны."
-    confirm_email:
-      heading: Пацвердзіць змену паштовага адрасу
-      press confirm button: "Націсніце кнопку, каб пацвердзіць ваш новы паштовы адрас."
-      button: Пацвердзіць
-      success: "Ваш адрас пацверджаны, дзякуй за рэгістрацыю!"
-      failure: "Паштовы адрас ужо быў пацаерджаны гэтым ключом."
-    set_home:
-      flash success: "Дамашняе месцазнаходжанне паспяхова запісана"
-    go_public:
-      flash success: "Усе вашыя змены цяпер публічныя, і вам цяпер дазволена рэдагаванне"
-    make_friend:
-      success: "{{name}} цяпер ваш сябар."
-      failed: "Прабачце, немагчыма дадаць {{name}} у якасці сябра."
-      already_a_friend: "Вы ўжо сябруеце з {{name}}."
-    remove_friend:
-      success: "{{name} выдалены са спіса сяброў."
-      not_a_friend: "{{name}} не з'яўляецца вашым сябрам."
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
new file mode 100644 (file)
index 0000000..47427fc
--- /dev/null
@@ -0,0 +1,75 @@
+# Messages for Bulgarian (Български)
+# Exported from translatewiki.net
+# Export driver: syck
+# Author: DCLXVI
+bg: 
+  browse: 
+    containing_relation: 
+      entry: Релация {{relation_name}}
+      entry_role: Релация {{relation_name}} (като {{relation_role}})
+    map: 
+      loading: Зареждане...
+    node: 
+      download: "{{download_xml_link}}, {{view_history_link}} или {{edit_link}}"
+      download_xml: Изтегляне на XML
+      edit: редактиране
+      node: Възел
+      node_title: "Възел: {{node_name}}"
+      view_history: преглед на историята
+    node_details: 
+      coordinates: "Координати:"
+      part_of: "Част от:"
+    node_history: 
+      download: "{{download_xml_link}} или {{view_details_link}}"
+      download_xml: Изтегляне на XML
+      view_details: преглед на детайлите
+    not_found: 
+      type: 
+        node: възел
+        relation: релация
+        way: път
+    paging_nav: 
+      of: от
+      showing_page: Показване на страница
+    relation_history: 
+      download: "{{download_xml_link}} или {{view_details_link}}"
+      download_xml: Изтегляне на XML
+      view_details: преглед на детайлите
+    relation_member: 
+      type: 
+        node: Възел
+        relation: Релация
+    way: 
+      download: "{{download_xml_link}}, {{view_history_link}} или {{edit_link}}"
+      download_xml: Изтегляне на XML
+      edit: редактиране
+      view_history: преглед на историята
+      way: Път
+    way_details: 
+      part_of: "Част от:"
+    way_history: 
+      download: "{{download_xml_link}} или {{view_details_link}}"
+      download_xml: Изтегляне на XML
+      view_details: преглед на детайлите
+  changeset: 
+    changesets: 
+      comment: Коментар
+      id: Номер
+      user: Потребител
+  diary_entry: 
+    diary_entry: 
+      comment_count: 
+        one: 1 коментар
+        other: "{{count}} коментара"
+    view: 
+      login: Влизане
+      save_button: Съхраняване
+  message: 
+    new: 
+      send_button: Изпращане
+    read: 
+      date: Дата
+      from: От
+      subject: Тема
+      to: До
+      unread_button: Отбелязване като непрочетено
diff --git a/config/locales/br.yml b/config/locales/br.yml
new file mode 100644 (file)
index 0000000..95f301f
--- /dev/null
@@ -0,0 +1,970 @@
+# Messages for Breton (Brezhoneg)
+# Exported from translatewiki.net
+# Export driver: syck
+# Author: Fohanno
+# Author: Fulup
+br: 
+  activerecord: 
+    attributes: 
+      diary_comment: 
+        body: Korf
+      diary_entry: 
+        language: Yezh
+        latitude: Ledred
+        longitude: Hedred
+        title: Titl
+        user: Implijer
+      friend: 
+        friend: Mignon
+        user: Implijer
+      message: 
+        body: Korf
+        recipient: Degemerer
+        sender: Kaser
+        title: Titl
+      trace: 
+        description: Deskrivadur
+        latitude: Ledred
+        longitude: Hedred
+        name: Anv
+        public: Foran
+        size: Ment
+        user: Implijer
+        visible: Gwelus
+      user: 
+        active: Oberiant
+        description: Deskrivadur
+        display_name: Anv diskouezet
+        email: Postel
+        languages: Yezhoù
+        pass_crypt: Ger-tremen
+    models: 
+      acl: Roll kontroll moned
+      changeset: Strollad kemmoù
+      changeset_tag: Balizenn strollad kemmoù
+      country: Bro
+      diary_comment: Addispleg eus an deizlevr
+      diary_entry: Enmoned en deizlevr
+      friend: Mignon
+      language: Yezh
+      message: Kemennadenn
+      node: Skoulm
+      node_tag: Balizenn skoulm
+      notifier: Kemenn
+      old_node: Skoulm kozh
+      old_node_tag: balizenn ar skoulm kozh
+      old_relation: Darempred kozh
+      old_relation_member: Ezel darempred kozh
+      old_relation_tag: Balizenn darempred kozh
+      old_way: Hent kozh
+      old_way_node: Skoulm an hent kozh
+      old_way_tag: Balizenn an hent kozh
+      relation: Darempred
+      relation_member: Ezel an darempred
+      relation_tag: Balizenn darempred
+      session: Dalc'h
+      trace: Roud
+      tracepoint: Poent eus ar roud
+      tracetag: Balizenn roud
+      user: Implijer
+      user_preference: Penndibaboù Implijer
+      user_token: Jedouer an implijer
+      way: Hent
+      way_node: Skoulm eus an hent
+      way_tag: Balizenn hent
+  browse: 
+    changeset: 
+      changeset: "Strollad kemmoù : {{id}}"
+      changesetxml: Strollad kemmoù XML
+      download: Pellgargañ {{changeset_xml_link}} pe {{osmchange_xml_link}}
+      feed: 
+        title: Strollad kemmoù {{id}}
+        title_comment: Strollad kemmoù {{id}} - {{comment}}
+      osmchangexml: osmChange XML
+      title: Strollad kemmoù
+    changeset_details: 
+      belongs_to: "Zo da :"
+      bounding_box: "Boest bevenniñ :"
+      box: boest
+      closed_at: "Serret d'an :"
+      created_at: "Krouet d'an :"
+      has_nodes: 
+        one: "Zo gantañ an {{count}} skoulm-mañ :"
+        other: "Zo gantañ an {{count}} skoulm-mañ :"
+      has_relations: 
+        one: "Zo gantañ an {{count}} darempred-mañ :"
+        other: "Zo gantañ an {{count}} darempred-mañ :"
+      has_ways: 
+        one: "Zo gantañ an {{count}} hent-mañ :"
+        other: "Zo gantañ an {{count}} hent-mañ :"
+      no_bounding_box: N'eus bet stoket boest bevenniñ ebet evit ar strollad kemmoù-mañ.
+      show_area_box: Diskouez boest an takad
+    changeset_navigation: 
+      all: 
+        next_tooltip: Strollad kemmoù da-heul
+        prev_tooltip: Strollad kemmoù kent
+      user: 
+        name_tooltip: Gwelet an aozadennoù gant {{user}}
+        next_tooltip: Aozadenn da-heul gant {{user}}
+        prev_tooltip: Aozadenn gent gant {{user}}
+    common_details: 
+      changeset_comment: "Addispleg :"
+      edited_at: "Aozet d'an :"
+      edited_by: "Aozet gant :"
+      in_changeset: "Er strollad kemmoù :"
+      version: "Stumm :"
+    containing_relation: 
+      entry: Darempred {{relation_name}}
+      entry_role: Darempred {{relation_name}} (evel {{relation_role}})
+    map: 
+      deleted: Dilamet
+      larger: 
+        area: Gwelet an takad war ur gartenn vrasoc'h
+        node: Gwelet ar skoulm war ur gartenn vrasoc'h
+        relation: Gwelet an darempred war ur gartenn vrasoc'h
+        way: Gwelet an hent war ur gartenn vrasoc'h
+      loading: O kargañ...
+    node: 
+      download: "{{download_xml_link}}, {{view_history_link}} pe {{edit_link}}"
+      download_xml: Pellgargañ XML
+      edit: aozañ
+      node: Skoulm
+      node_title: "Skoulm : {{node_name}}"
+      view_history: gwelet an istor
+    node_details: 
+      coordinates: "Daveennoù :"
+      part_of: "Lodenn eus :"
+    node_history: 
+      download: "{{download_xml_link}} pe {{view_details_link}}"
+      download_xml: Pellgargañ XML
+      node_history: Istor ar skoulmoù
+      node_history_title: "Istor ar skoulm : {{node_name}}"
+      view_details: gwelet ar munudoù
+    not_found: 
+      sorry: Ho tigarez, an {{type}} gant an id {{id}} n'eo ket bet kavet.
+      type: 
+        changeset: strollad kemmoù
+        node: skoulm
+        relation: darempred
+        way: hent
+    paging_nav: 
+      of: eus
+      showing_page: O tiskouez ar bajenn
+    relation: 
+      download: "{{download_xml_link}} pe {{view_history_link}}"
+      download_xml: Pellgargañ XML
+      relation: Darempred
+      relation_title: "Darempred : {{relation_name}}"
+      view_history: gwelet an istor
+    relation_details: 
+      members: "Izili :"
+      part_of: "Lodenn eus :"
+    relation_history: 
+      download: "{{download_xml_link}} pe {{view_details_link}}"
+      download_xml: Pellgargañ XML
+      relation_history: Istor an darempred
+      relation_history_title: "Istor an darempred : {{relation_name}}"
+      view_details: gwelet ar munudoù
+    relation_member: 
+      entry_role: "{{type}} {{name}} evel {{role}}"
+      type: 
+        node: Skoulm
+        relation: Darempred
+        way: Hent
+    start: 
+      manually_select: Diuzañ un takad disheñvel gant an dorn
+      view_data: Gwelet ar roadennoù evit gwel red ar gartenn
+    start_rjs: 
+      data_frame_title: Roadennoù
+      data_layer_name: Roadennoù
+      details: Munudoù
+      drag_a_box: Tresit ur voest war ar gartenn evit diuzañ un takad
+      edited_by_user_at_timestamp: Aozet gant [[user]] da [[timestamp]]
+      history_for_feature: Istor evit [[feature]]
+      load_data: Kargañ ar roadennoù
+      loaded_an_area_with_num_features: Karget hoc'h eus un takad zo ennañ [[num_features]] elfenn. Peurliesañ o devez poan ar merdeerioù o tiskwel kemend-all a roadennoù, ha labourat a reont gwelloc'h pa vez nebeutoc'h a 100 elfenn da ziskwel, a-hend-all e c'hall ho merdeer bezañ gorrek pe chom hep respont. Ma'z oc'h sur hoc'h eus c'hoant da ziskwel ar roadennoù-mañ, e c'hallit ober dre glikañ war ar bouton amañ dindan.
+      loading: O kargañ...
+      manually_select: Diuzañ un takad disheñvel gant an dorn
+      object_list: 
+        api: Tapout an takad-mañ diwar an API
+        back: Diskwel roll an traezoù
+        details: Munudoù
+        heading: Roll traezoù
+        history: 
+          type: 
+            node: Skoulm [[id]]
+            way: Hent [[id]]
+        selected: 
+          type: 
+            node: Skoulm [[id]]
+            way: hent [[id]]
+        type: 
+          node: Skoulm
+          way: Hent
+      private_user: implijer prevez
+      show_history: Diskouez an istor
+      unable_to_load_size: "Ne c'haller ket kargañ : re vras eo ment ar voest bevenniñ ([[bbox_size]]). Ret eo dezhi bezañ bihanoc'h eget {{max_bbox_size}})"
+      wait: Gortozit...
+      zoom_or_select: Zoumañ pe diuzañ un takad eus ar gartenn da welet
+    tag_details: 
+      tags: "Balizennoù :"
+    way: 
+      download: "{{download_xml_link}}, {{view_history_link}} pe {{edit_link}}"
+      download_xml: Pellgargañ XML
+      edit: aozañ
+      view_history: gwelet an istor
+      way: Hent
+      way_title: "Hent : {{way_name}}"
+    way_details: 
+      also_part_of: 
+        one: lodenn ivez eus an hent {{related_ways}}
+        other: lodenn ivez eus an hentoù {{related_ways}}
+      nodes: "Skoulmoù :"
+      part_of: "Lodenn eus :"
+    way_history: 
+      download: "{{download_xml_link}} pe {{view_details_link}}"
+      download_xml: Pellgargañ XML
+      view_details: gwelet ar munudoù
+      way_history: Istor an hent
+      way_history_title: "Istor an hent : {{way_name}}"
+  changeset: 
+    changeset: 
+      anonymous: Dizanv
+      big_area: (bras)
+      no_comment: (hini ebet)
+      no_edits: (aozadenn ebet)
+      show_area_box: diskouez takad ar voest
+      still_editing: (oc'h aozañ c'hoazh)
+      view_changeset_details: Gwelet munudoù ar strollad kemmoù
+    changeset_paging_nav: 
+      of: eus
+      showing_page: O tiskouez ar bajenn
+    changesets: 
+      area: Takad
+      comment: Addispleg
+      id: ID
+      saved_at: Enrollet da
+      user: Implijer
+    list: 
+      description: Kemmoù graet nevez zo
+      description_bbox: Strolladoù kemmoù e-barzh {{bbox}}
+      description_user: Strolladoù kemmoù gant {{user}}
+      description_user_bbox: Strolladoù kemmoù gant {{user}} e-barzh {{bbox}}
+      heading: Strolladoù kemmoù
+      heading_bbox: strolladoù kemmoù
+      heading_user: Strolladoù kemmoù
+      heading_user_bbox: Strolladoù kemmoù
+      title: Strolladoù kemmoù
+      title_bbox: Strolladoù kemmoù e-barzh {{bbox}}
+      title_user: Strolladoù kemmoù gant {{user}}
+      title_user_bbox: Strolladoù kemmoù gant {{user}} e-barzh {{bbox}}
+  diary_entry: 
+    diary_comment: 
+      comment_from: Addispleg gant {{link_user}}  d'an {{comment_created_at}}
+    diary_entry: 
+      comment_count: 
+        one: 1 addispleg
+        other: "{{count}} addispleg"
+      comment_link: Addisplegañ an enmoned-mañ
+      edit_link: Aozañ an enmoned-mañ
+      posted_by: Postet gant {{link_user}} da {{created}} e {{language_link}}
+      reply_link: Respont d'an enmoned-mañ
+    edit: 
+      body: "Korf :"
+      language: "Yezh :"
+      latitude: Ledred
+      location: "Lec'hiadur :"
+      longitude: "Hedred :"
+      marker_text: Lec'hiadur an enmoned en deizlevr
+      save_button: Enrollañ
+      subject: "Danvez :"
+      title: Aozañ an enmoned en deizlevr
+      use_map_link: implijout ar gartenn
+    feed: 
+      all: 
+        description: Enmonedoù nevez en deizlevr gant implijerien eus OpenStreetMap
+        title: Enmonedoù en deizlevr OpenStreetMap
+      language: 
+        description: Enmonedoù nevez a-walc'h e deizlevr implijerien OpenStreetMap e {{language_name}}
+        title: Enmonedoù deizlevr OpenStreetMap e {{language_name}}
+      user: 
+        description: Enmonedoù nevez e deizlevr OpenStreetMap gant {{user}}
+        title: Enmonedoù deizlevr OpenStreetMap evit {{user}}
+    list: 
+      in_language_title: Enmonedoù en deizlevr e {{language}}
+      new: Enmoned nevez en deizlevr
+      new_title: Ouzhpennañ un enmoned nevez d'ho teizlevr
+      newer_entries: Enmonedoù nevesañ
+      no_entries: Enmoned ebet en ho teizlevr
+      older_entries: Enmonedoù koshañ
+      recent_entries: "Enmonedoù nevez en deizlevr :"
+      title: Deizlevrioù an implijerien
+      user_title: Deizlevr {{user}}
+    new: 
+      title: Enmoned nevez en deizlevr
+    no_such_entry: 
+      body: Ho tigarez, n'eus enmoned deizlevr ebet nag addsiqpleg ebet gant an id {{id}}. Gwiriit hag-eñ eo skrivet mat, pe marteze hoc'h eus kliket war ul liamm fall.
+      heading: "Enmoned ebet gant an id : {{id}}"
+      title: Enmoned ebet evel-se en deizlevr
+    no_such_user: 
+      body: Ho tigarez, n'eus implijer ebet en anv {{user}}. Gwiriit hag-eñ eo skrivet mat, pe marteze hoc'h eus kliket war ul liamm fall.
+      heading: N'eus ket eus an implijer {{user}}
+      title: N'eus implijer ebet evel-se
+    view: 
+      leave_a_comment: Lezel un addispleg
+      login: Kevreañ
+      login_to_leave_a_comment: "{{login_link}} evit lezel un addispleg"
+      save_button: Enrollañ
+      title: Deizlevrioù an implijerien | {{user}}
+      user_title: Deizlevr {{user}}
+  export: 
+    start: 
+      add_marker: Ouzhpennañ ur merker d'ar gartenn
+      area_to_export: Takad da ezporzhiañ
+      embeddable_html: HTML enkorfadus
+      export_button: Ezporzhiañ
+      export_details: Roadennoù OpenStreetMap zo dindan an aotre-implijout <a href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons Attribution-ShareAlike 2.0</a>.
+      format: Furmad
+      format_to_export: Furmad da ezporzhiañ
+      image_size: Ment ar skeudenn
+      latitude: "Led. :"
+      licence: Aotre implijout
+      longitude: "Hed. :"
+      manually_select: Diuzañ un takad disheñvel gant an dorn
+      mapnik_image: Skeudenn Mapnik
+      max: d'ar muiañ
+      options: Dibarzhioù
+      osm_xml_data: Roadennoù XML OpenStreetMap
+      osmarender_image: Skeudenn Osmarender
+      output: Er-maez
+      paste_html: Pegañ HTML evit bezañ enkorfet en ul lec'hienn web
+      scale: Skeuliad
+      zoom: Zoum
+    start_rjs: 
+      add_marker: Ouzhpennañ ur merker d'ar gartenn
+      change_marker: Cheñch lec'hiadur ar merker
+      click_add_marker: Klikit war ar gartenn evit ouzhpennañ ur merker
+      drag_a_box: Tresañ ur voest war ar gartenn evit diuzañ un takad
+      export: Ezporzhiañ
+      manually_select: Diuzañ un takad disheñvel gant an dorn
+      view_larger_map: Gwelet ur gartenn vrasoc'h
+  geocoder: 
+    description: 
+      title: 
+        geonames: Lec'hiadur diwar <a href="http://www.geonames.org/">GeoNames</a>
+        osm_namefinder: "{{types}} diwar <a href=\"http://gazetteer.openstreetmap.org/namefinder/\">OpenStreetMap Namefinder</a>"
+      types: 
+        cities: Keodedoù
+        places: Lec'hioù
+        towns: Kêrioù
+    description_osm_namefinder: 
+      prefix: "{{distance}} {{direction}} eus {{type}}"
+    direction: 
+      east: reter
+      north: norzh
+      north_east: biz
+      north_west: gwalarn
+      south: su
+      south_east: gevred
+      south_west: mervent
+      west: kornôg
+    distance: 
+      one: war-dro 1 km
+      other: war-dro {{count}} km
+      zero: nebeutoc'h eget 1 km
+    results: 
+      no_results: N'eus bet kavet respont ebet
+    search: 
+      title: 
+        ca_postcode: Disoc'hoù diwar <a href="http://geocoder.ca/">Geocoder.CA</a>
+        geonames: Disoc'hoù diwar <a href="http://www.geonames.org/">GeoNames</a>
+        latlon: Disoc'hoù diwar <a href="http://openstreetmap.org/">Internal</a>
+        osm_namefinder: Disoc'hoù diwar <a href="http://gazetteer.openstreetmap.org/namefinder/">OpenStreetMap Namefinder</a>
+        uk_postcode: Disoc'hoù diwar <a href="http://www.npemap.org.uk/">NPEMap / FreeThe Postcode</a>
+        us_postcode: Disoc'hoù diwar <a href="http://geocoder.us/">Geocoder.us</a>
+    search_osm_namefinder: 
+      suffix_parent: "{{suffix}} ({{parentdistance}} {{parentdirection}} eus {{parentname}})"
+      suffix_place: " {{distance}} {{direction}} diouzh {{placename}}"
+  javascripts: 
+    map: 
+      base: 
+        cycle_map: Kelc'hiad kartenn
+        noname: AnvEbet
+    site: 
+      edit_zoom_alert: Ret eo deoc'h zoumañ evit aozañ ar gartenn
+      history_zoom_alert: Ret eo deoc'h zoumañ evit gwelet istor an aozadennoù
+  layouts: 
+    donate: Skoazellit OpenStreetMap dre {{link}} d'an Hardware Upgrade Fund.
+    donate_link_text: oc'h ober un donezon
+    edit: Aozañ
+    edit_tooltip: Aozañ kartennoù
+    export: Ezporzhiañ
+    export_tooltip: Ezporzhiañ roadennoù ar gartenn
+    gps_traces: Roudoù GPS
+    gps_traces_tooltip: Merañ ar roudoù
+    help_wiki: Skoazell &amp; Wiki
+    help_wiki_tooltip: Skoazell &amp; lec'hienn Wiki evit ar raktres
+    history: Istor
+    history_tooltip: Istor ar strollad kemmoù
+    home: degemer
+    home_tooltip: Mont da lec'h ar gêr
+    inbox: boest resev ({{count}})
+    inbox_tooltip: 
+      one: 1 gemennadenn anlennet zo en ho poest resev
+      other: E-barzh ho poest resev ez eus {{count}} kemennadenn anlennet
+      zero: N'eus kemennadenn anlennet ebet en ho poest resev
+    intro_1: OpenStreetMap zo ur gartenn digoust eus ar bed a-bezh, a c'haller kemmañ. Graet eo gant tud eveldoc'h.
+    intro_2: Gant OpenStreetMap e c'hallit gwelet, aozañ hag implijout roadennoù douaroniel eus forzh pelec'h er bed.
+    intro_3: Herberc'hiet eo OpenStreetMap gant {{ucl}} et {{bytemark}}.
+    license: 
+      title: OpenStreetMap data zo dindan an aotre-implijout Creative Commons Attribution-Share Alike 2.0
+    log_in: kevreañ
+    log_in_tooltip: Kevreañ gant ur gont zo anezhi dija
+    logo: 
+      alt_text: Logo OpenStreetMap
+    logout: digevreañ
+    logout_tooltip: Digevreañ
+    make_a_donation: 
+      text: Ober un donezon
+      title: Skoazellañ OpenStreetMap gant ur road arc'hant
+    news_blog: Blog keleier
+    news_blog_tooltip: Blog keleier diwar-benn OpenStreetMap, roadennoù douaroniel digoust, hag all.
+    osm_offline: Ezlinenn eo diaz roadennoù OpenStreetMap evit bremañ e-pad ma pleder gant ul labour kempenn bras.
+    osm_read_only: Diaz roadennoù OpenStreetMap zo da lenn hepken evit bremañ evit bremañ abalamour da labourioù kempenn bras.
+    shop: Stal
+    shop_tooltip: Stal gant produioù OpenStreetMap
+    sign_up: En em enskrivañ
+    sign_up_tooltip: Krouiñ ur gont evit aozañ
+    sotm: Deuit da gendiviz 2009 OpenStreetMap, <a href="http://www.stateofthemap.org">The State of the Map</a>, 10-12 a viz Gouere en Amsterdam!
+    tag_line: Kartenn digoust eus ar bed Wiki
+    user_diaries: Deizlevrioù an implijer
+    user_diaries_tooltip: Gwelet deizlevrioù an implijerien
+    view: Gwelet
+    view_tooltip: Gwelet ar c'hartennoù
+    welcome_user: Degemer mat, {{user_link}}
+    welcome_user_link_tooltip: Ho pajenn implijer
+  map: 
+    coordinates: "Daveennoù :"
+    edit: Aozañ
+    view: Gwelet
+  message: 
+    delete: 
+      deleted: Kemennadenn dilamet
+    inbox: 
+      date: Deiziad
+      from: A-berzh
+      my_inbox: Ma boest resev
+      no_messages_yet: N'hoc'h eus kemennadenn ebet c'hoazh. Ha ma'z afec'h e darempred gant darn eus an {{people_mapping_nearby_link}}?
+      outbox: boest kas
+      people_mapping_nearby: tud o kartennañ en ardremez
+      subject: Danvez
+      title: Boest resev
+      you_have: Bez' hoc'h eus {{new_count}} kemennadenn nevez ha {{old_count}} kemennadenn gozh
+    mark: 
+      as_read: Kemennadenn merket evel lennet
+      as_unread: Merkañ evel anlennet
+    message_summary: 
+      delete_button: Dilemel
+      read_button: Merkañ evel lennet
+      reply_button: Respont
+      unread_button: Merkañ evel anlennet
+    new: 
+      back_to_inbox: Distreiñ d'ar voest resev
+      body: Korf
+      message_sent: Kemennadenn kaset
+      send_button: Kas
+      send_message_to: Kas ur gemennadenn nevez da {{name}}
+      subject: Danvez
+      title: Kas ur gemennadenn
+    no_such_user: 
+      body: Ho tigarez, n'eus implijer ebet na kemennadenn ebet gant an anv pe an id-se
+      heading: N'eus ket un implijer pe ur gemennadenn evel-se
+      title: N'eus ket un implijer pe ur gemennadenn evel-se
+    outbox: 
+      date: Deiziad
+      inbox: boest resev
+      my_inbox: Ma {{inbox_link}}
+      no_sent_messages: N'hoc'h eus kaset kemennadenn ebet c'hoazh. Ha ma'z afec'h a darempred gant darn eus an {{people_mapping_nearby_link}}?
+      outbox: boest kas
+      people_mapping_nearby: tud o kartennañ en ardremez
+      subject: Danvez
+      title: Boest kas
+      to: Da
+      you_have_sent_messages: Kaset hoc'h eus {{count}} kemennadenn
+    read: 
+      back_to_inbox: Distreiñ d'ar voest resev
+      back_to_outbox: Distreiñ d'ar voest kas
+      date: Deiziad
+      from: A-berzh
+      reading_your_messages: O lenn ho kemennadennoù
+      reading_your_sent_messages: O lenn ho kemennadennoù kaset
+      reply_button: Respont
+      subject: Danvez
+      title: Lenn ar gemennadenn
+      to: Da
+      unread_button: Merkañ evel anlennet
+    sent_message_summary: 
+      delete_button: Dilemel
+  notifier: 
+    diary_comment_notification: 
+      banner1: "*                  Na respontit ket d'ar postel-mañ, mar plij                                                 *"
+      banner2: "*                Implijt lec'hienn web OpenStreetMap web site evit respont                           *"
+      footer: Gallout a rit ivez lenn an addispleg war {{readurl}}, lezel addisplegoù war {{commenturl}} pe respont war {{replyurl}}
+      header: "{{from_user}} en deus lezet un addispleg war hoc'h enmoned nevez e deizlevr OpenStreetMap gant an danvez {{subject}} :"
+      hi: Demat {{to_user}},
+      subject: "[OpenStreetMap] {{user}} en deus lezet un addispleg war hoc'h enmoned en deizlevr"
+    email_confirm: 
+      subject: "[OpenStreetMap] Kadarnaat ho chomlec'h postel"
+    email_confirm_html: 
+      click_the_link: Ma'z eo c'hwi, klikit war al liamm amañ dindan evit kadarnaat ar c'hemm.
+      greeting: Demat,
+      hopefully_you: Unan bennak (c'hwi moarvat) a garfe cheñch e chomlec'h postel eus {{server_url}} da {{new_address}}.
+    email_confirm_plain: 
+      click_the_link: Ma'z eo c'hwi, klikit war al liamm amañ dindan, mar plij, evit kadarnaat ar c'hemm.
+      greeting: Demat,
+      hopefully_you_1: Unan bennak (c'hwi moarvat) a garfe cheñch e chomlec'h postel da
+      hopefully_you_2: "{{server_url}} da {{new_address}}."
+    friend_notification: 
+      had_added_you: "{{user}} en deus hoc'h ouzhpennet evel mignon war OpenStreetMap."
+      see_their_profile: Gallout a rit gwelet o frofil war {{userurl}} hag o ouzhpennañ evel mignoned ma karit.
+      subject: "[OpenStreetMap] {{user}} en deus hoc'h ouzhpennet evel mignon"
+    gpx_notification: 
+      and_no_tags: ha balizenn ebet.
+      and_the_tags: "hag ar balizennoù-mañ :"
+      failure: 
+        failed_to_import: "n'en deus ket gallet bezañ enporzhiet. Setu amañ ar fazi :"
+        more_info_1: Muioc'h a ditouroù diwar-benn ar c'hudennoù enporzhiañ GPX ha penaos en em virout diouto
+        more_info_2: "a c'hall bezañ kavet war :"
+        subject: "[OpenStreetMap] fazi e-pad an enporzhiadur GPX"
+      greeting: Demat,
+      success: 
+        loaded_successfully: karget gant {{trace_points}} diwar {{possible_points}} poent posupl.
+        subject: "[OpenStreetMap] Graet eo an enporzhiadenn GPX"
+      with_description: gant an deskrivadur
+      your_gpx_file: War a seblant, ho restr GPX
+    lost_password: 
+      subject: "[OpenStreetMap] Goulenn adderaouekaat ar ger-tremen"
+    lost_password_html: 
+      click_the_link: Ma'z eo c'hwi, klikit war al liamm amañ dindan evit adderaouekaat ho ker-tremen.
+      greeting: Demat,
+      hopefully_you: Unan bennak (c'hwi moarvat) en deus goulennet e vefe adderaouekaet ger-tremen ar gont openstreetmap.org gant ar chomlec'h postel-mañ.
+    lost_password_plain: 
+      click_the_link: Ma'z eo c'hwi, klikit war al liamm amañ dindan, mar plij, evit adderaouekaat ho ker-tremen.
+      greeting: Demat,
+      hopefully_you_1: Unan bennak (c'hwi, moarvat) en deus goulennet e vefe adderaouekaet ar ger-tremen
+      hopefully_you_2: kont openstreetmap.org gant ar chomlec'h postel-mañ.
+    message_notification: 
+      banner1: "*                  Na respontit ket d'ar postel-mañ, mar plij.                                                *"
+      banner2: "*                Implijit lec'hienn web OpenStreetMap evit respont.                                      *"
+      footer1: Gallout a rit ivez lenn ar gemennadenn war {{readurl}}
+      footer2: ha gallout a rit respont da {{replyurl}}
+      header: "{{from_user}} en deus kaset deoc'h ur gemennadenn dre OpenStreetMap gant an danvez {{subject}} :"
+      hi: Demat {{to_user}},
+      subject: "[OpenStreetMap] {{user}} en deus kaset ur gemennadenn deoc'h"
+    signup_confirm: 
+      subject: "[OpenStreetMap] Kadarnaat ho chomlec'h postel"
+    signup_confirm_html: 
+      click_the_link: Ma'z eo c'hwi, degemer mat deoc'h ! Klikit war al liamm amañ dindan evit kadarnaat krouidigezh ho kont ha gouzout hiroc'h diwar-benn OpenStreetMap
+      current_user: Ur roll eus an implijerien red dre rummadoù, diazezet war al lec'h m'emaint er bed, a c'haller kaout diwar <a href="http://wiki.openstreetmap.org/wiki/Category:Users_by_geographical_region">Category:Users_by_geographical_region</a>.
+      get_reading: Muioc'h a ditouroù diwar-benn OpenStreetMap <a href="http://wiki.openstreetmap.org/wiki/FR:Beginners_Guide">war ar wiki</a> pe <a href="http://www.opengeodata.org/">war ar blog opengeodata</a> a ginnig ivez  <a href="http://www.opengeodata.org/?cat=13">podskignadennoù da selaou</a> !
+      greeting: Demat !
+      hopefully_you: Unan bennak (c'hwi, moarvat) a garfe krouiñ ur gont war
+      introductory_video: Gallout a rit sellet ouzh un {{introductory_video_link}}.
+      more_videos: Bez' ez eus {{more_videos_link}}.
+      more_videos_here: muioc'h a videoioù amañ
+      user_wiki_page: Erbediñ a reomp deoc'h krouiñ ur bajenn implijer war ar wiki, enni balizennoù rummadoù o tiskouez pelec'h emaoc'h, evel <a href="http://wiki.openstreetmap.org/wiki/Category:Users_in_Brest">[[Category:Users_in_Brest]]</a>.
+      video_to_openstreetmap: video evit kregiñ gant OpenStreetMap
+      wiki_signup: Gallout a rit ivez <a href="http://wiki.openstreetmap.org/index.php?title=Special:Userlogin&type=signup&returnto=Main_Page">krouiñ ur gont war wiki OpenStreetMap</a>.
+    signup_confirm_plain: 
+      click_the_link_1: Ma'z eo c'hwi, degemer mat deoc'h ! Klikit war al liamm amañ dindan evit kadarnaat ho
+      click_the_link_2: kont ha lenn muioc'h a ditouroù diwar-benn OpenStreetMap.
+      current_user_1: Ur roll eus an implijerien diazezet war al lec'h m'emaint er bed
+      current_user_2: "a c'haller kaout diwar :"
+      greeting: Demat !
+      hopefully_you: Unan bennak (c'hwi moarvat) a garfe krouiñ ur gont war
+      introductory_video: "Gallout a rit sellet ouzh ur video evit kregiñ gant OpenStreetMap amañ :"
+      more_videos: "Muioc'h a videoioù zo amañ :"
+      opengeodata: "OpenGeoData.org eo blog OpenStreetMap, ha kinnig a ra podskignadennoù ivez :"
+      the_wiki: "Lennit traoù diwar-benn OpenStreetMap war ar wiki :"
+      user_wiki_1: Erbediñ a reomp deoc'h krouiñ ur bajenn implijer wiki, enni
+      user_wiki_2: rummadoù hag a verk pelec'h emaoc'h, evel [[Category:Users_in_Brest]].
+      wiki_signup: "Gallout a rit ivez krouiñ ur gont war wiki OpenStreetMap war :"
+  oauth: 
+    oauthorize: 
+      allow_read_gpx: lenn ho roudoù GPS prevez.
+      allow_read_prefs: lenn ho penndibaboù implijer.
+      allow_to: "Lezel an arload arval da :"
+      allow_write_api: kemmañ ar gartenn.
+      allow_write_diary: krouiñ enmonedoù en deizlevr, addisplegoù ha kavout mignoned.
+      allow_write_gpx: kas roudoù GPS.
+      allow_write_prefs: kemmañ ho penndibaboù implijer.
+      request_access: Emañ an arload {{app_name}} o c'houlenn mont d'ho kont. Gwiriit hag-eñ hoc'h eus c'hoant e vefe ar barregezhioù-mañ gant hoc'h arloadoù. Gallout a rit dibab kement ha ma karit.
+    revoke: 
+      flash: Torret hoc'h eus ar jedouer evit {{application}}
+  oauth_clients: 
+    create: 
+      flash: Marilhet eo bet an titouroù
+    destroy: 
+      flash: Distrujet eo bet marilhadur an arload arval
+    edit: 
+      submit: Aozañ
+      title: Aozañ hoc'h arload
+    form: 
+      allow_read_gpx: lenn o roudoù GPS prevez.
+      allow_read_prefs: lenn e benndibaboù implijer.
+      allow_write_api: kemmañ ar gartenn.
+      allow_write_diary: krouit enmonedoù en deizlevr, addisplegoù, ha kavit mignoned.
+      allow_write_gpx: kas roudoù GPS.
+      allow_write_prefs: kemmañ e benndibaboù implijer.
+      callback_url: URL gervel en-dro
+      name: Anv
+      requests: "Goulenn an aotreoù-mañ digant an implijer :"
+      required: Rekis
+      support_url: URL skoazell
+      url: URL pennañ an arload
+    index: 
+      application: Anv an arload
+      issued_at: Kaset da
+      list_tokens: "Ar jedoueroù-mañ zo bet skignet d'an arloadoù en hoc'h anv :"
+      my_apps: Ma arloadoù arvalien
+      my_tokens: Ma arloadoù aotreet
+      no_apps: Ha bez' hoc'h eus un arload ho pefe c'hoant da varilhañ evit implijout ar standard {{oauth}} ganimp ? Ret eo deoc'h marilhañ hoc'h arload web a-raok dezhi ober rekedoù d'ar servij-mañ.
+      register_new: Marilhañ hoc'h arload
+      registered_apps: "Marilhet eo an arloadoù arvalien-mañ ganeoc'h :"
+      revoke: Terriñ !
+      title: Ma munudoù OAuth
+    new: 
+      submit: Marilhañ
+      title: Marilhañ un arload nevez
+    not_found: 
+      sorry: Ho tigarez, an {{type}}-mañ n'eo ket bet kavet.
+    show: 
+      access_url: "URL ar jedouer moned :"
+      allow_read_gpx: lenn o roudoù GPS prevez.
+      allow_read_prefs: lenn e benndibaboù implijer.
+      allow_write_api: kemmañ ar gartenn.
+      allow_write_diary: krouit enmonedoù en deizlevr, addisplegoù ha kavit mignoned.
+      allow_write_gpx: kas roudoù GPS.
+      allow_write_prefs: kemmañ o fenndibaboù implijerien.
+      authorize_url: "URL aotren :"
+      edit: Aozañ ar munudoù
+      key: "Alc'hwez an implijer :"
+      requests: "O c'houlenn an aotreoù-mañ digant an implijer :"
+      secret: "Sekred an implijer :"
+      support_notice: Skorañ a reomp hmac-sha1 (erbedet) hag an destenn diaoz er mod ssl.
+      title: Munudoù OAuth evit {{app_name}}
+      url: "URL ar jedouer reked :"
+    update: 
+      flash: Hizivaet eo bet titouroù an arval
+  site: 
+    edit: 
+      anon_edits_link_text: Kavit perak.
+      flash_player_required: Ezhomm hoc'h eus eus ul lenner Flash evit implijout Potlatch, aozer flash OpenStreetMap. Gallout a rit <a href="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">pellgargañ Flash Player diwar Adobe.com</a>. <a href="http://wiki.openstreetmap.org/wiki/Editing">Meur a zibarzh</a> a c'haller kaout evit aozañ OpenStreetMap.
+      not_public: N'hoc'h eus ket lakaet hoc'h aozadennoù da vezañ foran.
+      not_public_description: Ne c'hallit ket ken aozañ ar gartenn nemet e lakafec'h hoc'h aozadennoù da vezañ foran. Gallout a rit lakaat hoc'h aozadennoù da vezañ foran diwar ho {{user_page}}.
+      potlatch_unsaved_changes: Kemmoù n'int ket bet enrollet zo ganeoc'h. (Evit enrollañ e Potlatch, e tlefec'h diziuzañ an hent pe ar poent red m'emaoc'h oc'h aozañ er mod bev, pe klikañ war enrollañ ma vez ur bouton enrollañ ganeoc'h.)
+      user_page_link: pajenn implijer
+    index: 
+      js_1: Pe emaoc'h oc'h implijout ur merdeer ha ne skor ket JavaScript, pe hoc'h eus diweredekaet JavaScript.
+      js_2: OpenStreetMap a implij JavaScript evit e gartenn risklus.
+      js_3: Ma ne c'hallit ket gweredekaat JavaScrip e c'hallit esaeañ gant ar <a href="http://tah.openstreetmap.org/Browse/">merdeer statek Tiles@Home</a>.
+      license: 
+        license_name: Creative Commons Attribution-Share Alike 2.0
+        notice: Dindan aotre-implijout {{license_name}} gant an {{project_name}} hag e genobererien.
+        project_name: raktres OpenStreetMap
+      permalink: Permalink
+      shortlink: Liamm berr
+    key: 
+      map_key: Alc'hwez ar gartenn
+      map_key_tooltip: Alc'hwez evit ar mapnik gant al live zoum-mañ
+      table: 
+        entry: 
+          admin: Bevenn velestradurel
+          allotments: Lodennaouegoù
+          apron: 
+            - Roudenn aerborzh
+            - termenva
+          bridge: Bord du = pont
+          bridleway: Hent evit kezeg
+          brownfield: Takad greanterezh
+          building: Savadur pouezus
+          byway: Gwenodenn
+          cable: 
+            - Teleferik
+            - fungador
+          cemetery: Bered
+          centre: Kreizenn sport
+          commercial: Takad kenwerzhel
+          common: 
+            - prad
+            - prad
+          construction: Hentoù war ar stern
+          cycleway: Roudenn divrodegoù
+          destination: Moned d'ar pal
+          farm: Ti-feurm
+          footway: Hent evit an dud war droad
+          forest: Koad
+          golf: Tachenn golf
+          heathland: Lanneier
+          industrial: Takad greantel
+          lake: 
+            - Lenn
+            - mirlec'h
+          military: Takad milourel
+          motorway: Gourhent
+          park: Park
+          permissive: Moned aotreüs
+          pitch: Tachenn sport
+          primary: Hent bras
+          private: Moned prevez
+          rail: Hent-houarn
+          reserve: Gwarezva natur
+          resident: Takad annez
+          retail: Takad kenwerzh
+          runway: 
+            - Roudenn evit an taksioù
+            - Roudenn evit an taksioù
+          school: 
+            - Skol
+            - skol-veur
+          secondary: Hent bihan
+          station: Porzh-houarn
+          subway: Linenn vetro
+          summit: 
+            - Lein
+            - pikern
+          tourist: Diduañs evit an douristed
+          track: Roudenn
+          tram: 
+            - tramgarr
+            - tramgarr
+          trunk: Hent broadel
+          tunnel: Bord poentoùigoù = riboul
+          unclassified: Hent n'eo ket rummet
+          unsurfaced: Hent n'eo ket goloet
+          wood: Koad
+        heading: Alc'hwez evit z{{zoom_level}}
+    search: 
+      search: Klask
+      search_help: "da skouer : 'Kemper', 'Straed Siam, Brest', 'CB2 5AQ', pe 'tiez-post tost da Roazhon' <a href='http://wiki.openstreetmap.org/wiki/Search'>muioc'h a skouerioù...</a>"
+      submit_text: Kas
+      where_am_i: Pelec'h emaon ?
+    sidebar: 
+      close: Serriñ
+      search_results: Disoc'hoù an enklask
+  trace: 
+    create: 
+      trace_uploaded: Kaset eo bet ho restr GPX hag emañ en gortoz a vezañ ensoc'het en diaz roadennoù. C'hoarvezout a ra dindan un hanter-eurvezh peurvuiañ, ha kaset e vo ur postel deoc'h pa vo echu.
+      upload_trace: Kas ar roud GPS
+    delete: 
+      scheduled_for_deletion: Roudenn da vezañ dilamet
+    edit: 
+      description: "Deskrivadur :"
+      download: pellgargañ
+      edit: aozañ
+      filename: "Anv ar restr :"
+      heading: Oc'h aozañ ar roud {{name}}
+      map: kartenn
+      owner: "Perc'henn :"
+      points: "Poentoù :"
+      save_button: Enrollañ ar c'hemmoù
+      start_coord: "Daveennoù orin :"
+      tags: "Balizennoù :"
+      tags_help: bevennet gant virgulennoù
+      title: Oc'h aozañ ar roud {{name}}
+      uploaded_at: "Kaset da :"
+      visibility: "Gwelusted :"
+      visibility_help: Petra a dalvez an dra-mañ ?
+    list: 
+      public_traces: Roudoù GPS foran
+      public_traces_from: Roudoù GPS foran gant {{user}}
+      tagged_with: " balizennet gant {{tags}}"
+      your_traces: Ho roudoù GPS
+    make_public: 
+      made_public: Roudenn lakaet da vezañ foran
+    no_such_user: 
+      body: Ho tigarez, n'eus implijer ebet en anv {{user}}. Gwiriit hag-eñ eo skrivet mar, pe marteze hoc'h eus kliket war ul liamm fall.
+      heading: N'eus ket eus an implijer {{user}}
+      title: Implijer ebet evel-se
+    trace: 
+      ago: "{{time_in_words_ago}} zo"
+      by: gant
+      count_points: "{{count}} poent"
+      edit: aozañ
+      edit_map: Aozañ ar gartenn
+      in: e-barzh
+      map: kartenn
+      more: muioc'h
+      pending: WAR C'HORTOZ
+      private: PREVEZ
+      public: FORAN
+      trace_details: Gwelet munudoù ar roud
+      view_map: Gwelet ar gartenn
+    trace_form: 
+      description: Deskrivadur
+      help: Skoazell
+      tags: Balizennoù
+      tags_help: bevennet gant virgulennoù
+      upload_button: Kas
+      upload_gpx: Kas ar restr GPX
+      visibility: Gwelusted
+      visibility_help: Petra a dalvez ?
+    trace_header: 
+      see_all_traces: Gwelet an holl roudoù
+      see_just_your_traces: Gwelet ho roudoù hepken, pe kas ur roud
+      see_your_traces: Gwelet hoc'h holl roudoù
+      traces_waiting: Bez' hoc'h eus {{count}} roud a c'hortoz bezañ kaset. Gwell e vefe gortoz a-raok kas re all, evit chom hep stankañ al lostennad evit an implijerien all.
+    trace_optionals: 
+      tags: Balizennoù
+    trace_paging_nav: 
+      of: eus
+      showing: O tiskouez ar bajenn
+    view: 
+      delete_track: Dilemel ar roudenn-mañ
+      description: "Deskrivadur :"
+      download: pellgargañ
+      edit: aozañ
+      edit_track: Aozañ ar roudenn-mañ
+      filename: "Anv ar restr :"
+      heading: O welet ar roud {{name}}
+      map: kartenn
+      none: Hini ebet
+      owner: Perc'henn
+      pending: WAR C'HORTOZ
+      points: "Poentoù :"
+      start_coordinates: "Daveennoù orin :"
+      tags: "Balizennoù :"
+      title: O welet ar roud {{name}}
+      trace_not_found: N'eo ket bet kavet ar roud !
+      uploaded: "Karget da :"
+      visibility: "Gwelusted :"
+    visibility: 
+      identifiable: Anavezadus (diskouezet e roll ar roudoù hag evel anavezadus, poentoù urzhiet gant an deiziadoù)
+      private: Prevez (rannet ent dizanv hepken, poentoù hep urzh)
+      public: Foran (diskouezet e roll ar roudoù hag ent dizanv, poentoù hep urzh)
+      trackable: A c'haller treseal (rannet evel dizanv hepken, poent uzhiet gant deiziadoù)
+  user: 
+    account: 
+      email never displayed publicly: (n'eo ket diskwelet d'an holl morse)
+      flash update success: Hizivaet eo bet titouroù an implijer.
+      flash update success confirm needed: Hizivaet eo bet titouroù an implijer. Gwiriit ho posteloù evit kadarnaat ho chomlec'h postel nevez.
+      home location: "Lec'hiadur ar gêr :"
+      latitude: "Ledred :"
+      longitude: "Hedred :"
+      make edits public button: Lakaat ma holl aozadennoù da vezañ foran
+      my settings: Ma arventennoù
+      no home location: N'hoc'h eus ket ebarzhet lec'hiadur ho kêr.
+      preferred languages: "Yezhoù gwellañ karet :"
+      profile description: "Deskrivadur ar profil :"
+      public editing: 
+        disabled: Diweredekaet ha ne c'hall ket aozañ roadennoù ; diznav eo an holl aozadennoù kent.
+        disabled link text: Perak n'on ket evit aozañ ?
+        enabled: Gweredekaet. N'eo ket dizanv ha gallout a ra aozañ roadennoù.
+        enabled link text: Petra eo se ?
+        heading: "Aozañ foran :"
+      return to profile: Distreiñ d'ar profil
+      save changes button: Enrollañ ar c'hemmoù
+      title: Aozañ ar gont
+      update home location on click: Hizivaat lec'hiadur ho kêr pa glikit war ar gartenn ?
+    confirm: 
+      button: Kadarnaat
+      failure: Ur gont implijer gant ar jedouer-mañ zo bet kadarnaet dija.
+      heading: Kadarnaat kont un implijer
+      press confirm button: Pouezit war ar bouton kadarnaat amañ dindan evit gweredekaat ho kont.
+      success: Kadarnaet eo ho kont, trugarez evit bezañ en em enskrivet !
+    confirm_email: 
+      button: Kadarnaat
+      failure: Kadarnaet ez eus bet ur chomlec'h postel dija gant art jedouer-mañ.
+      heading: Kadarnaat ur c'hemm chomlec'h postel
+      press confirm button: Pouezit war ar bouton kadarnaat evit kadarnaat ho chomlec'h postel nevez.
+      success: Kadarnaet eo ho chomlec'h postel, trugarez evit bezañ en em enskrivet !
+    friend_map: 
+      nearby mapper: "Kartennour en ardremez : [[nearby_user]]"
+      your location: Ho lec'hiadur
+    go_public: 
+      flash success: Foran eo hoc'h holl aozadennoù bremañ, ha n'oc'h ket aotreet da aozañ.
+    login: 
+      account not active: Ho tigarez, n'eo ket oberiant ho kont c'hoazh. <br/>Klikit war al liamm er postel kadarnaat, mar plij, evit gweredekaat ho kont.
+      auth failure: Ho tigarez, met n'eus ket bet gallet hoc'h anavezout gant an titouroù pourchaset.
+      create_account: krouiñ ur gont
+      email or username: "Chomlec'h postel pe anv implijer :"
+      heading: Kevreañ
+      login_button: Kevreañ
+      lost password link: Kollet hoc'h eus ho ker-tremen ?
+      password: "Ger-tremen :"
+      please login: Kevreit, mar plij, pe {{create_user_link}}.
+      title: Kevreañ
+    lost_password: 
+      email address: "Chomlec'h postel :"
+      heading: Ankouaet hoc'h eus ho ker-tremen ?
+      new password button: Adderaouekaat ar ger-tremen
+      notice email cannot find: Ho tigarez, n'eo ket bet kavet ar chomlec'h postel-se.
+      notice email on way: Kaset ez eus bet ur postel deoc'h evit adderaouekaat ho ker-tremen.
+      title: Ger-tremen kollet
+    make_friend: 
+      already_a_friend: Mignon oc'h gant {{name}} dija.
+      failed: Ho tigarez, n'eus ket bet gallet ouzhpennañ {{name}} evel mignon.
+      success: "{{name}} zo ho mignon bremañ."
+    new: 
+      confirm email address: "Kadarnaat ar chomlec'h postel :"
+      confirm password: "Kadarnaat ar ger-tremen :"
+      contact_webmaster: Kit e darempred gant ar <a href="mailto:webmaster@openstreetmap.org">mestr-gwiad</a>, mar plij, evit ma krouo ur gont evidoc'h - klask a raimp plediñ gant ho koulenn kerkent ha ma vo tu.
+      display name: "Anv diskwelet :"
+      email address: "Chomlec'h postel :"
+      fill_form: Leugnit ar furmskrid hag e kasimp deoc'h ur postel evit gweredekaat ho kont.
+      flash create success message: Krouet eo bet an implijer.  Gwelit ha resevet hoc'h eus ho postel kadarnaat, ha prest e viot da gartennañ diouzhtu.:-)<br /><br />Ho pezet soñj ne c'hallot ket kevreañ keit ha n'ho po ket resevet ar postel kadarnaat ha kadarnaet ho chomlec'h postel.<br /><br />Ma implijit ur reizhiad enep-strob hag a gas goulennoù kadarnaat, lakait webmaster@openstreetmap.org en ho liestenn wenn, mar plij, rak n'omp ket evit respont d'ar posteloù-se.
+      heading: Krouiñ ur gont implijer
+      license_agreement: Dre grouiñ ur gont ez asantit e vefe an holl roadennoù a gasit d'ar raktres OpenStreetMap dindan an aotre-implijout <a href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons license (by-sa)</a> (peurgetket).
+      no_auto_account_create: Siwazh n'omp ket evit krouiñ ur gont evidoc'h ent emgefreek.
+      not displayed publicly: N'eo ket diskwelet d'an holl (gwelet <a href="http://wiki.openstreetmap.org/wiki/Privacy_Policy" title="wiki privacy policy including section on email addresses">hor c'harta prevezded</a>)
+      password: "Ger-tremen :"
+      signup: En em enskrivañ
+      title: Krouiñ ur gont
+    no_such_user: 
+      body: Ho tigarez, n'eus implijer ebet en anv {{user}}. Gwiriit hag-eñ eo skrivet mat, pe marteze hoc'h eus kliket war ul liamm fall.
+      heading: N'eus ket eus an implijer {{user}}
+      title: N'eus ket un implijer evel-se
+    remove_friend: 
+      not_a_friend: "{{name}} n'eo ket unan eus ho mignoned."
+      success: "{{name}} zo bet lamet eus ho mignoned."
+    reset_password: 
+      confirm password: "Kadarnaat ar ger-tremen :"
+      flash changed: Cheñchet eo bet ho ker-tremen.
+      flash token bad: N'eo ket bet kavet ar jedouer-se, gwiriañ an URL marteze ?
+      heading: Adderaouekaat ar ger-tremen evit {{user}}
+      password: "Ger-tremen :"
+      reset: Adderaouekaat ar ger-tremen
+      title: Adderaouekaat ar ger-tremen
+    set_home: 
+      flash success: Enrollet eo bet lec'hiadur ar gêr
+    view: 
+      add as friend: Ouzhpennañ evel mignon
+      add image: Ouzhpennañ ur skeudenn
+      ago: ({{time_in_words_ago}} zo)
+      change your settings: cheñch hoc'h arventennoù
+      delete image: Dilemel ar skeudenn
+      description: Deskrivadur
+      diary: deizlevr
+      edits: kemmoù
+      if set location: Ma lakait ho lec'hiadur e teuio ur gartenn vrav war wel dindani. Gallout a rit lakaat ho lec'hiadur war ho pajenn {{settings_link}}.
+      km away: war-hed {{count}} km
+      m away: war-hed {{count}} m
+      mapper since: "Kartennour abaoe :"
+      my diary: ma deizlevr
+      my edits: ma aozadennoù
+      my settings: ma arventennoù
+      my traces: ma roudoù
+      my_oauth_details: Gwelet ma munudoù OAuth
+      nearby users: "Implijerien tost deoc'h :"
+      new diary entry: enmoned nevez en deizlevr
+      no friends: N'hoc'h eus ouzhpennet mignon ebet c'hoazh.
+      no home location: N'eus bet lakaet lec'hiadur ebet evit ar gêr.
+      no nearby users: N'eus implijer ebet en ardremez c'hoazh.
+      remove as friend: Lemel evel mignon
+      send message: Kas ur gemennadenn
+      settings_link_text: arventennoù
+      traces: roudoù
+      upload an image: Kas ur skeudenn
+      user image heading: Skeudenn implijer
+      user location: Lec'hiadur an implijer
+      your friends: Ho mignoned
diff --git a/config/locales/bs.yml b/config/locales/bs.yml
new file mode 100644 (file)
index 0000000..45f8934
--- /dev/null
@@ -0,0 +1,17 @@
+# Messages for Bosnian (Bosanski)
+# Exported from translatewiki.net
+# Export driver: syck
+# Author: CERminator
+bs: 
+  activerecord: 
+    attributes: 
+      diary_entry: 
+        title: Naslov
+        user: Korisnik
+    models: 
+      country: Država
+      language: Jezik
+      message: Poruka
+      relation: Veza
+      relation_member: Član veze
+      user: Korisnik
index 0387eba4ecda372305da34126621d34d78a72e4a..984f7e3fc7417a2dd8066fb7d113fa1f28d1477c 100644 (file)
-ca:
-  html:
-    dir: "ltr"
-  activerecord:
-    models:
-      acl: "Llista de control d'accés"
-      changeset: "Conjunt de canvis"
-      changeset_tag: "Etiqueta del conjunt de canvis"
-      country: "País"
-      diary_comment: "Commentari del diari"
-      diary_entry: "Entrada al diari"
-      friend: "Amic"
-      language: "Idioma"
-      message: "Missatge"
-      node: "Node"
-      node_tag: "Etiqueta del node"
-      notifier: "Notificador"
-      old_node: "Node antic"
-      old_node_tag: "Etiqueta del node antic"
-      old_relation: "Relació antiga"
-      old_relation_member: "Membre de la relació antiga"
-      old_relation_tag: "Etiqueta de relació antiga"
-      old_way: "Camí antic"
-      old_way_node: "Node del camí antic"
-      old_way_tag: "Etiqueta del camí antic"
-      relation: "Relació"
-      relation_member: "Membre de la relació"
-      relation_tag: "Etiqueta de la relació"
-      session: "Sessió"
-      trace: "Traç"
-      tracepoint: "Punt de traç"
-      tracetag: "Etiqueta del traç"
-      user: "Usuari"
-      user_preference: "Preferències d'usuari"
-      user_token: ""
-      way: "Camí"
-      way_node: "Node del camí"
-      way_tag: "Etiqueta del camí"
-    attributes:
-      diary_comment:
-        body: "Cos"
-      diary_entry:
-        user: "Usuari"
-        title: "Títol"
-        latitude: "Latitud"
-        longitude: "Longitud"
-        language: "Idioma"
-      friend:
-        user: "Usuari"
-        friend: "Amic"
-      trace:
-        user: "Usuari"
-        visible: "Visible"
-        name: "Nom"
-        size: "Mida"
-        latitude: "Latitud"
-        longitude: "Longitud"
-        public: "Públic"
-        description: "Descripció"
-      message:
-        sender: "Remitent"
-        title: "Títol"
-        body: "Cos"
-        recipient: "Destinatari"
-      user:
-        email: "E-mail"
-        active: "Actiu"
-        display_name: "Nom en pantalla"
-        description: "Descripció"
-        languages: "Idiomes"
-        pass_crypt: "Contrasenya"
-  map:
-    view: "Veure"
-    edit: "Edita"
-    coordinates: "Coordenades:"
-  browse:
-    changeset:
-      title: "Conjunt de canvis"
-      changeset: "Conjunt de canvis {{id}}"
-      download: "Baixa {{changeset_xml_link}} o {{osmchange_xml_link}}"
-      changesetxml: "XML del conjunt de canvis"
-      osmchangexml: "XML en format osmChange"
-    changeset_details:
-      created_at: "Creat el:"
-      closed_at: "Tancat el:"
+# Messages for Catalan (Català)
+# Exported from translatewiki.net
+# Export driver: syck
+# Author: PerroVerd
+# Author: SMP
+ca: 
+  activerecord: 
+    attributes: 
+      diary_comment: 
+        body: Cos
+      diary_entry: 
+        language: Idioma
+        latitude: Latitud
+        longitude: Longitud
+        title: Títol
+        user: Usuari
+      friend: 
+        friend: Amic
+        user: Usuari
+      message: 
+        body: Cos
+        recipient: Destinatari
+        sender: Remitent
+        title: Títol
+      trace: 
+        description: Descripció
+        latitude: Latitud
+        longitude: Longitud
+        name: Nom
+        public: Públic
+        size: Mida
+        user: Usuari
+        visible: Visible
+      user: 
+        active: Actiu
+        description: Descripció
+        display_name: Nom en pantalla
+        email: E-mail
+        languages: Idiomes
+        pass_crypt: Contrasenya
+    models: 
+      acl: Llista de control d'accés
+      changeset: Conjunt de canvis
+      changeset_tag: Etiqueta del conjunt de canvis
+      country: País
+      diary_comment: Commentari del diari
+      diary_entry: Entrada al diari
+      friend: Amic
+      language: Idioma
+      message: Missatge
+      node: Node
+      node_tag: Etiqueta del node
+      notifier: Notificador
+      old_node: Node antic
+      old_node_tag: Etiqueta del node antic
+      old_relation: Relació antiga
+      old_relation_member: Membre de la relació antiga
+      old_relation_tag: Etiqueta de relació antiga
+      old_way: Camí antic
+      old_way_node: Node del camí antic
+      old_way_tag: Etiqueta del camí antic
+      relation: Relació
+      relation_member: Membre de la relació
+      relation_tag: Etiqueta de la relació
+      session: Sessió
+      trace: Traç
+      tracepoint: Punt de traç
+      tracetag: Etiqueta del traç
+      user: Usuari
+      user_preference: Preferències d'usuari
+      way: Camí
+      way_node: Node del camí
+      way_tag: Etiqueta del camí
+  browse: 
+    changeset: 
+      changeset: Conjunt de canvis {{id}}
+      changesetxml: XML del conjunt de canvis
+      download: Baixa {{changeset_xml_link}} o {{osmchange_xml_link}}
+      osmchangexml: XML en format osmChange
+      title: Conjunt de canvis
+    changeset_details: 
       belongs_to: "Pertany a:"
-      show_area_box: "Mostra caixa de l'àrea"
-      box: "caixa"
+      box: caixa
+      closed_at: "Tancat el:"
+      created_at: "Creat el:"
       has_nodes: "Té els següents {{count}} nodes:"
-      has_ways: "Té els següents {{count}} camins:"
       has_relations: "Té les següents {{count}} relacions:"
-    common_details:
+      has_ways: "Té els següents {{count}} camins:"
+      show_area_box: Mostra caixa de l'àrea
+    common_details: 
+      changeset_comment: "Comentari:"
       edited_at: "Editat:"
       edited_by: "Editat per:"
-      version: "Versió"
       in_changeset: "Al conjunt de canvis:"
-    containing_relation:
-      entry: "Relació {{relation_name}}"
-      entry_role: "Relació {{relation_name}} (com a  {{relation_role}})"
-    map:
-      loading: "Carregant..."
-      deleted: "Esborrat"
-    node_details:
+      version: Versió
+    containing_relation: 
+      entry: Relació {{relation_name}}
+      entry_role: Relació {{relation_name}} (com a  {{relation_role}})
+    map: 
+      deleted: Esborrat
+      loading: Carregant...
+    node: 
+      download: "{{download_xml_link}} o {{view_history_link}}"
+      download_xml: Baixa l'XML
+      node: Node
+      node_title: "Node: {{node_name}}"
+      view_history: visualitza l'historial
+    node_details: 
       coordinates: "Coordenades:"
       part_of: "Part de:"
-    node_history:
-      node_history: "Historial del node"
+    node_history: 
       download: "{{download_xml_link}} o {{view_details_link}}"
-      download_xml: "Baixa l'XML"
-      view_details: "veure detalls"
-    node:
-      node: "Node"
-      node_title: "Node: {{node_name}}"
-      download: "{{download_xml_link}} o {{view_history_link}}"
-      download_xml: "Baixa l'XML"
-      view_history: "visualitza l'historial"
-    not_found:
-      sorry: "Ho sentim, no s'ha trobat el {{type}} amb l'id {{id}}."
-      type:
-        node: "node"
-        way: "camí"
-        relation: "relació"
-    paging_nav:
-      showing_page: "Mostrant pàgina"
-      of: "de"
-    relation_details:
+      download_xml: Baixa l'XML
+      node_history: Historial del node
+      view_details: veure detalls
+    not_found: 
+      sorry: Ho sentim, no s'ha trobat el {{type}} amb l'id {{id}}.
+      type: 
+        node: node
+        relation: relació
+        way: camí
+    paging_nav: 
+      of: de
+      showing_page: Mostrant pàgina
+    relation: 
+      download: "{{download_xml_link}} oo {{view_history_link}}"
+      download_xml: Baixa l'XML
+      relation: Relació
+      relation_title: "Relació: {{relation_name}}"
+      view_history: visualitza l'historial
+    relation_details: 
       members: "Membres:"
       part_of: "Part de:"
-    relation_history:
-      relation_history: "Historial de la relació"
+    relation_history: 
+      relation_history: Historial de la relació
       relation_history_title: "Historial de la relació: {{relation_name}}"
-    relation:
-      relation: "Relació"
-      relation_title: "Relació: {{relation_name}}"
-      download: "{{download_xml_link}} oo {{view_history_link}}"
-      download_xml: "Baixa l'XML"
-      view_history: "visualitza l'historial"
-    start:
-      view_data: "Visualitza la informació per a la vista del mapa actual"
-      manually_select: "Sel·lecciona una altra àrea manualment"
-    start_rjs:
-      data_layer_name: "Informació"
-      data_frame_title: "Informació"
-      object_list:
-        type:
-          way: "Camí"
-        selected:
-          type:
-            way: "Camí [[id]]"
-    way:
-      way: "Camí"
-  diary_entry:
-    edit:
-      language: "Idioma"
-
+    start: 
+      manually_select: Sel·lecciona una altra àrea manualment
+      view_data: Visualitza la informació per a la vista del mapa actual
+    start_rjs: 
+      data_frame_title: Informació
+      data_layer_name: Informació
+      details: Detalls
+      object_list: 
+        details: Detalls
+        history: 
+          type: 
+            node: Node [[id]]
+        selected: 
+          type: 
+            node: Node [[id]]
+            way: Camí [[id]]
+        type: 
+          node: Node
+          way: Camí
+    way: 
+      way: Camí
+  changeset: 
+    list: 
+      heading: Conjunt de canvis
+      heading_bbox: Conjunt de canvis
+      heading_user: Conjunt de canvis
+      heading_user_bbox: Conjunt de canvis
+      title: Conjunt de canvis
+  diary_entry: 
+    edit: 
+      language: Idioma
+  map: 
+    coordinates: "Coordenades:"
+    edit: Edita
+    view: Veure
+  trace: 
+    edit: 
+      map: mapa
+      owner: "Propietari:"
+      points: "Punts:"
+      visibility: "Visibilitat:"
+    trace: 
+      ago: fa {{time_in_words_ago}}
+      by: en
+      in: a
+    trace_paging_nav: 
+      of: de
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
new file mode 100644 (file)
index 0000000..6e84b59
--- /dev/null
@@ -0,0 +1,486 @@
+# Messages for Czech (Česky)
+# Exported from translatewiki.net
+# Export driver: syck
+# Author: Bilbo
+# Author: Mormegil
+cs: 
+  activerecord: 
+    attributes: 
+      diary_entry: 
+        language: Jazyk
+        title: Nadpis
+        user: Uživatel
+      friend: 
+        friend: Přítel
+        user: Uživatel
+      message: 
+        recipient: Příjemce
+        sender: Odesílatel
+        title: Nadpis
+      trace: 
+        description: Popis
+        name: Název
+        size: Velikost
+        user: Uživatel
+        visible: Viditelnost
+      user: 
+        active: Aktivní
+        description: Popis
+        email: E-mail
+        languages: Jazyky
+        pass_crypt: Heslo
+    models: 
+      changeset: Sada změn
+      changeset_tag: Tag sady změn
+      country: Země
+      friend: Přítel
+      language: Jazyk
+      message: Zpráva
+      node: Uzel
+      node_tag: Tag uzlu
+      old_node: Starý uzel
+      old_node_tag: Starý tag uzlu
+      old_relation: Stará relace
+      old_relation_member: Starý člen relace
+      old_relation_tag: Starý tag relace
+      old_way: Stará cesta
+      old_way_node: Starý uzel cesty
+      old_way_tag: Starý tag cesty
+      relation: Relace
+      relation_member: Člen relace
+      relation_tag: Tag relace
+      user: Uživatel
+      way: Cesta
+      way_node: Uzel cesty
+      way_tag: Tag cesty
+  browse: 
+    changeset: 
+      changeset: "Sada změn: {{id}}"
+      download: Stáhnout {{changeset_xml_link}} nebo {{osmchange_xml_link}}
+      feed: 
+        title: Sada změn {{id}}
+        title_comment: "Sada změn: {{id}} - {{comment}}"
+      title: Sada změn
+    changeset_details: 
+      closed_at: "Uzavřeno v:"
+      created_at: "Vytvořeno v:"
+    changeset_navigation: 
+      all: 
+        next_tooltip: Další sada změn
+        prev_tooltip: Předchozí sada změn
+      user: 
+        name_tooltip: Zobrazit úpravy od {{user}}
+        next_tooltip: Další úprava od {{user}}
+        prev_tooltip: Předešlá úprava od {{user}}
+    common_details: 
+      changeset_comment: "Komentář:"
+      in_changeset: "V sadě změn:"
+      version: "Verze:"
+    containing_relation: 
+      entry: Relace {{relation_name}}
+      entry_role: Relace {{relation_name}} (jako {{relation_role}})
+    map: 
+      deleted: Smazáno
+      larger: 
+        area: Zobrazit oblast na větší mapě
+        node: Zobrazit uzel na větší mapě
+        relation: Zobrazit relaci na větší mapě
+        way: Zobrazit cestu na větší mapě
+    node: 
+      download: "{{download_xml_link}}, {{view_history_link}} nebo {{edit_link}}"
+      download_xml: Stáhnout XML
+      edit: upravit
+      node: Uzel
+      node_title: "Uzel: {{node_name}}"
+      view_history: zobrazit historii
+    node_details: 
+      coordinates: "Souřadnice:"
+      part_of: "Součást:"
+    node_history: 
+      download: "{{download_xml_link}} nebo {{view_details_link}}"
+      download_xml: Stáhnout XML
+      node_history: Historie uzlu
+      node_history_title: "Historie uzlu: {{node_name}}"
+      view_details: zobrazit detaily
+    not_found: 
+      sorry: Promiňte, ale {{type}} s id {{id}} nebylo možné nalézt.
+      type: 
+        changeset: sada změn
+        node: uzel
+        relation: relace
+        way: cesta
+    paging_nav: 
+      of: z
+      showing_page: Zobrazuji stranu
+    relation: 
+      download: "{{download_xml_link}} nebo {{view_history_link}}"
+      download_xml: Stáhnout XML
+