From: Andy Allan Date: Wed, 29 Nov 2017 12:18:39 +0000 (+0000) Subject: Merge branch 'master' into moderation X-Git-Tag: live~3986^2~91 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/effb1b7f4170bb7244c4dfffcbe6134fe00e2bc4?hp=dd619fbe73fcd19e2dc4f3e8160158b8d90b3a66 Merge branch 'master' into moderation --- diff --git a/.rubocop.yml b/.rubocop.yml index e1f1724e0..55be8141c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -27,15 +27,34 @@ Rails: Layout/ExtraSpacing: AllowForAlignment: true -Style/BracesAroundHashParameters: - EnforcedStyle: context_dependent +Lint/PercentStringArray: + Exclude: + - 'config/initializers/secure_headers.rb' + - 'app/controllers/site_controller.rb' -Style/FileName: +Naming/FileName: Exclude: - 'script/deliver-message' - 'script/locale/reload-languages' - 'script/update-spam-blocks' +Rails/ApplicationRecord: + Enabled: false + +Rails/HasManyOrHasOneDependent: + Enabled: false + +Rails/HttpPositionalArguments: + Enabled: false + +Rails/SkipsModelValidations: + Exclude: + - 'db/migrate/*.rb' + - 'app/controllers/user_controller.rb' + +Style/BracesAroundHashParameters: + EnforcedStyle: context_dependent + Style/FormatStringToken: EnforcedStyle: template @@ -60,19 +79,3 @@ Style/StringLiterals: Style/SymbolArray: EnforcedStyle: brackets - -Rails/ApplicationRecord: - Enabled: false - -Rails/HttpPositionalArguments: - Enabled: false - -Rails/SkipsModelValidations: - Exclude: - - 'db/migrate/*.rb' - - 'app/controllers/user_controller.rb' - -Lint/PercentStringArray: - Exclude: - - 'config/initializers/secure_headers.rb' - - 'app/controllers/site_controller.rb' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index e89927c9d..b4104079c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,11 +1,19 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2016-10-20 21:45:27 +0100 using RuboCop version 0.44.1. +# on 2017-10-05 10:04:24 +0100 using RuboCop version 0.50.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: aligned, indented +Layout/MultilineOperationIndentation: + Exclude: + - 'lib/bounding_box.rb' + # Offense count: 34 Lint/AmbiguousOperator: Exclude: @@ -14,11 +22,11 @@ Lint/AmbiguousOperator: - 'test/lib/bounding_box_test.rb' - 'test/lib/country_test.rb' -# Offense count: 117 +# Offense count: 124 Lint/AmbiguousRegexpLiteral: Enabled: false -# Offense count: 30 +# Offense count: 32 # Configuration parameters: AllowSafeAssignment. Lint/AssignmentInCondition: Exclude: @@ -36,52 +44,62 @@ Lint/AssignmentInCondition: - 'lib/osm.rb' - 'script/deliver-message' -# Offense count: 5 +# Offense count: 4 Lint/HandleExceptions: Exclude: - 'app/controllers/amf_controller.rb' - 'app/controllers/user_controller.rb' - - 'config/initializers/session.rb' + +# Offense count: 3 +Lint/InterpolationCheck: + Exclude: + - 'test/controllers/node_controller_test.rb' + +# Offense count: 2 +Lint/RescueWithoutErrorClass: + Exclude: + - 'app/helpers/browse_helper.rb' # Offense count: 2 Lint/ShadowingOuterLocalVariable: Exclude: - 'app/views/changeset/list.atom.builder' -# Offense count: 630 +# Offense count: 666 Metrics/AbcSize: Max: 280 -# Offense count: 35 -# Configuration parameters: CountComments. +# Offense count: 41 +# Configuration parameters: CountComments, ExcludedMethods. Metrics/BlockLength: - Max: 295 + Max: 240 # Offense count: 12 +# Configuration parameters: CountBlocks. Metrics/BlockNesting: Max: 5 -# Offense count: 62 +# Offense count: 63 # Configuration parameters: CountComments. Metrics/ClassLength: - Max: 1790 + Max: 1796 -# Offense count: 69 +# Offense count: 71 Metrics/CyclomaticComplexity: Max: 20 -# Offense count: 2826 -# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives. +# Offense count: 3004 +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: - Max: 1072 + Max: 1073 -# Offense count: 612 +# Offense count: 675 # Configuration parameters: CountComments. Metrics/MethodLength: Max: 179 -# Offense count: 1 +# Offense count: 2 # Configuration parameters: CountComments. Metrics/ModuleLength: Max: 147 @@ -95,6 +113,30 @@ Metrics/ParameterLists: Metrics/PerceivedComplexity: Max: 23 +# Offense count: 5 +Naming/AccessorMethodName: + Exclude: + - 'app/controllers/application_controller.rb' + - 'app/helpers/title_helper.rb' + - 'app/models/old_way.rb' + - 'lib/osm.rb' + - 'lib/potlatch.rb' + +# Offense count: 8 +# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist. +# NamePrefix: is_, has_, have_ +# NamePrefixBlacklist: is_, has_, have_ +# NameWhitelist: is_a? +Naming/PredicateName: + Exclude: + - 'spec/**/*' + - 'app/models/changeset.rb' + - 'app/models/old_node.rb' + - 'app/models/old_relation.rb' + - 'app/models/old_way.rb' + - 'app/models/user.rb' + - 'lib/classic_pagination/pagination.rb' + # Offense count: 2 # Configuration parameters: Include. # Include: app/**/*.rb, config/**/*.rb, lib/**/*.rb @@ -122,7 +164,7 @@ Rails/NotNullColumn: - 'db/migrate/025_add_end_time_to_changesets.rb' - 'db/migrate/20120404205604_add_user_and_description_to_redaction.rb' -# Offense count: 17 +# Offense count: 20 Rails/OutputSafety: Exclude: - 'app/controllers/user_controller.rb' @@ -136,27 +178,18 @@ Rails/OutputSafety: - 'lib/rich_text.rb' - 'test/helpers/application_helper_test.rb' -# Offense count: 74 +# Offense count: 86 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: strict, flexible Rails/TimeZone: Enabled: false -# Offense count: 5 -Style/AccessorMethodName: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/helpers/title_helper.rb' - - 'app/models/old_way.rb' - - 'lib/osm.rb' - - 'lib/potlatch.rb' - # Offense count: 1 Style/AsciiComments: Exclude: - 'test/models/message_test.rb' -# Offense count: 220 +# Offense count: 219 Style/Documentation: Enabled: false @@ -182,35 +215,15 @@ Style/LineEndConcatenation: - 'test/controllers/relation_controller_test.rb' - 'test/controllers/way_controller_test.rb' -# Offense count: 71 +# Offense count: 75 # Cop supports --auto-correct. +# Configuration parameters: Strict. Style/NumericLiterals: MinDigits: 11 -# Offense count: 8 -# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist. -# NamePrefix: is_, has_, have_ -# NamePrefixBlacklist: is_, has_, have_ -# NameWhitelist: is_a? -Style/PredicateName: - Exclude: - - 'spec/**/*' - - 'app/models/changeset.rb' - - 'app/models/old_node.rb' - - 'app/models/old_relation.rb' - - 'app/models/old_way.rb' - - 'app/models/user.rb' - - 'lib/classic_pagination/pagination.rb' - -# Offense count: 97 +# Offense count: 95 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: compact, exploded Style/RaiseArgs: Enabled: false - -# Offense count: 2 -# Cop supports --auto-correct. -Style/RescueModifier: - Exclude: - - 'app/helpers/browse_helper.rb' diff --git a/.travis.yml b/.travis.yml index ad8f7e599..48ddb4a1d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,10 +4,10 @@ rvm: - 2.3.1 cache: bundler addons: - postgresql: 9.1 + postgresql: 9.5 apt: packages: - - postgresql-server-dev-9.1 + - postgresql-server-dev-9.5 services: - memcached env: @@ -18,9 +18,10 @@ before_script: - psql -U postgres -c "CREATE DATABASE openstreetmap" - psql -U postgres -c "CREATE EXTENSION btree_gist" openstreetmap - make -C db/functions libpgosm.so - - psql -U postgres -c "CREATE FUNCTION maptile_for_point(int8, int8, int4) RETURNS int4 AS '${PWD}/db/functions/libpgosm', 'maptile_for_point' LANGUAGE C STRICT" openstreetmap - - psql -U postgres -c "CREATE FUNCTION tile_for_point(int4, int4) RETURNS int8 AS '${PWD}/db/functions/libpgosm', 'tile_for_point' LANGUAGE C STRICT" openstreetmap - - psql -U postgres -c "CREATE FUNCTION xid_to_int4(xid) RETURNS int4 AS '${PWD}/db/functions/libpgosm', 'xid_to_int4' LANGUAGE C STRICT" openstreetmap + - ln db/functions/libpgosm.so /tmp + - psql -U postgres -c "CREATE FUNCTION maptile_for_point(int8, int8, int4) RETURNS int4 AS '/tmp/libpgosm', 'maptile_for_point' LANGUAGE C STRICT" openstreetmap + - psql -U postgres -c "CREATE FUNCTION tile_for_point(int4, int4) RETURNS int8 AS '/tmp/libpgosm', 'tile_for_point' LANGUAGE C STRICT" openstreetmap + - psql -U postgres -c "CREATE FUNCTION xid_to_int4(xid) RETURNS int4 AS '/tmp/libpgosm', 'xid_to_int4' LANGUAGE C STRICT" openstreetmap - cp config/travis.database.yml config/database.yml - bundle exec rake db:migrate script: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 477e8c63f..961377ec8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,7 +42,8 @@ sudo gem install rcov rcov -x gems test/*/*.rb ``` -The tests are automatically run on commit with the results shown at [http://cruise.openstreetmap.org/](http://cruise.openstreetmap.org/) +The tests are automatically run on Pull Requests and other commits with the +results shown on [Travis CI](https://travis-ci.org/openstreetmap/openstreetmap-website). ## Comments @@ -96,4 +97,3 @@ Otherwise you should either push your changes to a publicly visible git reposito and send the details to the [rails-dev](http://lists.openstreetmap.org/listinfo/rails-dev) list or generate patches with `git format-patch` and send them to the [rails-dev](http://lists.openstreetmap.org/listinfo/rails-dev) list. - diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 000000000..423ef70a6 --- /dev/null +++ b/FAQ.md @@ -0,0 +1,30 @@ +## How do I create a banner to promote my OpenStreetMap event? + +We occasionally display banner images on the main page of [openstreetmap.org](https://www.openstreetmap.org/) to +promote a large OpenStreetMap focused conference or host a worldwide donation +drive. This is a great way to reach a lot of people! + +1. Please review [openstreetmap/operations#150](https://github.com/openstreetmap/operations/issues/150) to +know whether your event qualifies for a front-page banner. + +2. Create the banner image. Some guidelines: + * Image should be 350px wide (exactly) x 350px tall (or shorter). + * Use a standard web image format (.gif, .jpg, .png) + * Note that a close 'X' button will be drawn over the top right 60x60px + corner of the banner, so please do not put anything important in that space. + +3. Prepare a pull request which includes the following: + * The banner should be saved under the + [`app/assets/images/banners/`](https://github.com/openstreetmap/openstreetmap-website/tree/master/app/assets/images/banners) folder, and should have a name that makes it clear what it is for (e.g. `donate-2017.jpg`) + * Edit [`config/banners.yml`](https://github.com/openstreetmap/openstreetmap-website/blob/master/config/banners.yml) + to contain an entry for the event banner. It should contain the following: + * `id` - a unique identifier (e.g. `donate2017`) + * `alt` - alt name for the image (e.g. `OpenStreetMap Funding Drive 2017`) + * `link` - URL for your event page (e.g. `https://donate.openstreetmap.org/`) + * `img` - the filename for the banner image (e.g. `banners/donate-2017.jpg`) + * `enddate` - the final date that the banner will be shown (e.g. `2017-oct-31`) + * (optional) Feel free to cleanup the old images from the `app/assets/images/banners/` + folder and old entries in the `config/banners.yml` file. + +See [PR #1296](https://github.com/openstreetmap/openstreetmap-website/pull/1296) +as an example. diff --git a/Gemfile b/Gemfile index 92e0def8f..43f39340a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source "https://rubygems.org" # Require rails -gem "rails", "5.0.5" +gem "rails", "5.1.4" # Require things which have moved to gems in ruby 1.9 gem "bigdecimal", "~> 1.1.0", :platforms => :ruby_19 @@ -32,7 +32,7 @@ gem "jquery-rails" gem "jsonify-rails" # Use R2 for RTL conversion -gem "r2" +gem "r2", "~> 0.2.7" # Use autoprefixer to generate CSS prefixes gem "autoprefixer-rails" @@ -42,12 +42,12 @@ gem "image_optim_rails" # Load rails plugins gem "actionpack-page_caching" -gem "composite_primary_keys", "~> 9.0.7" -gem "deadlock_retry", ">= 1.2.0" +gem "composite_primary_keys", "~> 10.0.0" gem "dynamic_form" gem "http_accept_language", "~> 2.0.0" gem "i18n-js", ">= 3.0.0" gem "oauth-plugin", ">= 0.5.1" +gem "openstreetmap-deadlock_retry", ">= 1.3.0", :require => "deadlock_retry" gem "paperclip", "~> 4.0" gem "rack-cors" gem "rails-i18n", "~> 4.0.0" @@ -107,6 +107,7 @@ gem "logstasher" # Gems useful for development group :development do + gem "annotate" gem "listen" gem "vendorer" end @@ -122,9 +123,10 @@ end # Needed in development as well so rake can see konacha tasks group :development, :test do + gem "capybara", "~> 2.13" gem "coveralls", :require => false - gem "factory_girl_rails" + gem "factory_bot_rails" gem "jshint" - # gem "konacha" gem "poltergeist" + gem "puma", "~> 3.7" end diff --git a/Gemfile.lock b/Gemfile.lock index ce2b4f114..d67d34d47 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,58 +3,61 @@ GEM specs: SystemTimer (1.2.3) aasm (4.1.0) - actioncable (5.0.5) - actionpack (= 5.0.5) - nio4r (>= 1.2, < 3.0) + actioncable (5.1.4) + actionpack (= 5.1.4) + nio4r (~> 2.0) websocket-driver (~> 0.6.1) - actionmailer (5.0.5) - actionpack (= 5.0.5) - actionview (= 5.0.5) - activejob (= 5.0.5) + actionmailer (5.1.4) + actionpack (= 5.1.4) + actionview (= 5.1.4) + activejob (= 5.1.4) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.0.5) - actionview (= 5.0.5) - activesupport (= 5.0.5) + actionpack (5.1.4) + actionview (= 5.1.4) + activesupport (= 5.1.4) rack (~> 2.0) - rack-test (~> 0.6.3) + rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) actionpack-page_caching (1.1.0) actionpack (>= 4.0.0, < 6) - actionview (5.0.5) - activesupport (= 5.0.5) + actionview (5.1.4) + activesupport (= 5.1.4) builder (~> 3.1) - erubis (~> 2.7.0) + erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.0.5) - activesupport (= 5.0.5) + activejob (5.1.4) + activesupport (= 5.1.4) globalid (>= 0.3.6) - activemodel (5.0.5) - activesupport (= 5.0.5) - activerecord (5.0.5) - activemodel (= 5.0.5) - activesupport (= 5.0.5) - arel (~> 7.0) - activesupport (5.0.5) + activemodel (5.1.4) + activesupport (= 5.1.4) + activerecord (5.1.4) + activemodel (= 5.1.4) + activesupport (= 5.1.4) + arel (~> 8.0) + activesupport (5.1.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.5.1) - public_suffix (~> 2.0, >= 2.0.2) - arel (7.1.4) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) + annotate (2.7.2) + activerecord (>= 3.2, < 6.0) + rake (>= 10.4, < 13.0) + arel (8.0.0) ast (2.3.0) - autoprefixer-rails (7.1.2.3) + autoprefixer-rails (7.1.6) execjs bigdecimal (1.1.0) builder (3.2.3) canonical-rails (0.2.1) rails (>= 4.1, < 5.2) - capybara (2.14.4) + capybara (2.15.4) addressable - mime-types (>= 1.16) + mini_mime (>= 0.1.3) nokogiri (>= 1.3.3) rack (>= 1.0.0) rack-test (>= 0.5.4) @@ -70,8 +73,8 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - composite_primary_keys (9.0.7) - activerecord (~> 5.0.0) + composite_primary_keys (10.0.1) + activerecord (~> 5.1.0) concurrent-ruby (1.0.5) coveralls (0.8.21) json (>= 1.8, < 3) @@ -83,30 +86,30 @@ GEM safe_yaml (~> 1.0.0) crass (1.0.2) dalli (2.7.6) - deadlock_retry (1.2.0) docile (1.1.5) dynamic_form (1.1.4) - erubis (2.7.0) + erubi (1.7.0) execjs (2.7.0) - exifr (1.3.1) - factory_girl (4.8.0) + exifr (1.3.2) + factory_bot (4.8.2) activesupport (>= 3.0.0) - factory_girl_rails (4.8.0) - factory_girl (~> 4.8.0) + factory_bot_rails (4.8.2) + factory_bot (~> 4.8.2) railties (>= 3.0.0) faraday (0.12.2) multipart-post (>= 1.2, < 3) ffi (1.9.18) fspath (3.1.0) geoip (1.6.3) - globalid (0.4.0) + globalid (0.4.1) activesupport (>= 4.2.0) - hashdiff (0.3.4) + hashdiff (0.3.7) hashie (3.5.6) htmlentities (4.3.4) http_accept_language (2.0.5) - i18n (0.8.6) - i18n-js (3.0.0) + i18n (0.9.0) + concurrent-ruby (~> 1.0) + i18n-js (3.0.2) i18n (~> 0.6, >= 0.6.6) image_optim (0.25.0) exifr (~> 1.2, >= 1.2.2) @@ -143,20 +146,22 @@ GEM rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) logstash-event (1.2.02) - logstasher (1.2.1) + logstasher (1.2.2) activesupport (>= 4.0) logstash-event (~> 1.2.0) request_store - loofah (2.0.3) + loofah (2.1.1) + crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.6.6) mime-types (>= 1.16, < 4) - method_source (0.8.2) + method_source (0.9.0) mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) mimemagic (0.3.0) - mini_portile2 (2.2.0) + mini_mime (0.1.4) + mini_portile2 (2.3.0) minitest (5.10.3) minitest-capybara (0.8.2) capybara (~> 2.2) @@ -172,12 +177,12 @@ GEM minitest-capybara (~> 0.8) minitest-metadata (~> 0.6) minitest-rails (~> 3.0) - multi_json (1.12.1) + multi_json (1.12.2) multi_xml (0.6.0) multipart-post (2.0.0) nio4r (2.1.0) - nokogiri (1.8.0) - mini_portile2 (~> 2.2.0) + nokogiri (1.8.1) + mini_portile2 (~> 2.3.0) nokogumbo (1.4.13) nokogiri oauth (0.4.7) @@ -192,7 +197,7 @@ GEM multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - omniauth (1.6.1) + omniauth (1.7.1) hashie (>= 3.4.6, < 3.6.0) rack (>= 1.6.2, < 3) omniauth-facebook (4.0.0) @@ -220,6 +225,7 @@ GEM omniauth-windowslive (0.0.12) multi_json (~> 1.12) omniauth-oauth2 (~> 1.4) + openstreetmap-deadlock_retry (1.3.0) paperclip (4.3.7) activemodel (>= 3.2.0) activesupport (>= 3.2.0) @@ -230,34 +236,35 @@ GEM parser (2.4.0.0) ast (~> 2.2) pg (0.21.0) - poltergeist (1.15.0) + poltergeist (1.16.0) capybara (~> 2.1) cliver (~> 0.3.1) websocket-driver (>= 0.2.0) powerpack (0.1.1) - progress (3.3.1) + progress (3.4.0) psych (2.2.4) - public_suffix (2.0.5) + public_suffix (3.0.0) + puma (3.10.0) r2 (0.2.7) rack (2.0.3) - rack-cors (1.0.1) + rack-cors (1.0.2) rack-openid (1.3.1) rack (>= 1.1.0) ruby-openid (>= 2.1.8) - rack-test (0.6.3) - rack (>= 1.0) + rack-test (0.7.0) + rack (>= 1.0, < 3) rack-uri_sanitizer (0.0.2) - rails (5.0.5) - actioncable (= 5.0.5) - actionmailer (= 5.0.5) - actionpack (= 5.0.5) - actionview (= 5.0.5) - activejob (= 5.0.5) - activemodel (= 5.0.5) - activerecord (= 5.0.5) - activesupport (= 5.0.5) + rails (5.1.4) + actioncable (= 5.1.4) + actionmailer (= 5.1.4) + actionpack (= 5.1.4) + actionview (= 5.1.4) + activejob (= 5.1.4) + activemodel (= 5.1.4) + activerecord (= 5.1.4) + activesupport (= 5.1.4) bundler (>= 1.3.0) - railties (= 5.0.5) + railties (= 5.1.4) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.2) actionpack (~> 5.x, >= 5.0.1) @@ -271,15 +278,15 @@ GEM rails-i18n (4.0.2) i18n (~> 0.6) rails (>= 4.0) - railties (5.0.5) - actionpack (= 5.0.5) - activesupport (= 5.0.5) + railties (5.1.4) + actionpack (= 5.1.4) + activesupport (= 5.1.4) method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (2.2.2) rake - rake (12.0.0) + rake (12.2.1) rb-fsevent (0.10.2) rb-inotify (0.9.10) ffi (>= 0.5.0, < 2) @@ -288,24 +295,24 @@ GEM redcarpet (3.4.0) ref (2.0.0) request_store (1.3.2) - rinku (2.0.2) + rinku (2.0.3) rotp (3.3.0) - rubocop (0.49.1) + rubocop (0.51.0) parallel (~> 1.10) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) - rainbow (>= 1.99.1, < 3.0) + rainbow (>= 2.2.2, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) ruby-openid (2.7.0) - ruby-progressbar (1.8.1) + ruby-progressbar (1.9.0) ruby_dep (1.5.0) safe_yaml (1.0.4) sanitize (4.5.0) crass (~> 1.0.2) nokogiri (>= 1.4.4) nokogumbo (~> 1.4.1) - sass (3.5.1) + sass (3.5.3) sass-listen (~> 4.0.0) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) @@ -316,17 +323,17 @@ GEM sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - secure_headers (3.6.7) - useragent + secure_headers (5.0.1) + useragent (>= 0.15.0) simplecov (0.14.1) docile (~> 1.1.0) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) - simplecov-html (0.10.1) + simplecov-html (0.10.2) sprockets (3.7.1) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.0) + sprockets-rails (3.2.1) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) @@ -339,7 +346,7 @@ GEM thread_safe (0.3.6) tilt (2.0.8) tins (1.15.0) - tzinfo (1.2.3) + tzinfo (1.2.4) thread_safe (~> 0.1) uglifier (3.2.0) execjs (>= 0.3.0, < 3) @@ -348,7 +355,7 @@ GEM validates_email_format_of (1.6.3) i18n vendorer (0.1.16) - webmock (3.0.1) + webmock (3.1.0) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff @@ -365,16 +372,17 @@ DEPENDENCIES SystemTimer (>= 1.1.3) aasm actionpack-page_caching + annotate autoprefixer-rails bigdecimal (~> 1.1.0) canonical-rails + capybara (~> 2.13) coffee-rails (~> 4.2) - composite_primary_keys (~> 9.0.7) + composite_primary_keys (~> 10.0.0) coveralls dalli - deadlock_retry (>= 1.2.0) dynamic_form - factory_girl_rails + factory_bot_rails faraday geoip htmlentities @@ -399,14 +407,16 @@ DEPENDENCIES omniauth-mediawiki (>= 0.0.3) omniauth-openid omniauth-windowslive + openstreetmap-deadlock_retry (>= 1.3.0) paperclip (~> 4.0) pg poltergeist psych - r2 + puma (~> 3.7) + r2 (~> 0.2.7) rack-cors rack-uri_sanitizer - rails (= 5.0.5) + rails (= 5.1.4) rails-controller-testing rails-i18n (~> 4.0.0) record_tag_helper @@ -423,4 +433,4 @@ DEPENDENCIES webmock BUNDLED WITH - 1.13.7 + 1.15.4 diff --git a/README.md b/README.md index 5b909454f..6b929fef9 100644 --- a/README.md +++ b/README.md @@ -40,3 +40,8 @@ We're always keen to have more developers! Pull requests are very welcome. * IRC - there is the #osm-dev channel on irc.oftc.net. More details on contributing to the code are in the [CONTRIBUTING.md](CONTRIBUTING.md) file. + +# Maintainers + +* Tom Hughes [@tomhughes](https://github.com/tomhughes/) +* Andy Allan [@gravitystorm](https://github.com/gravitystorm/) diff --git a/Vendorfile b/Vendorfile index 8c9898dd9..d66dd80d8 100644 --- a/Vendorfile +++ b/Vendorfile @@ -11,13 +11,13 @@ folder 'vendor/assets' do end folder 'leaflet' do - file 'leaflet.js', 'https://unpkg.com/leaflet@1.1.0/dist/leaflet-src.js' - file 'leaflet.css', 'https://unpkg.com/leaflet@1.1.0/dist/leaflet.css' + file 'leaflet.js', 'https://unpkg.com/leaflet@1.2.0/dist/leaflet-src.js' + file 'leaflet.css', 'https://unpkg.com/leaflet@1.2.0/dist/leaflet.css' [ 'layers.png', 'layers-2x.png', 'marker-icon.png', 'marker-icon-2x.png', 'marker-shadow.png' ].each do |image| - file "images/#{image}", "https://unpkg.com/leaflet@1.1.0/dist/images/#{image}" + file "images/#{image}", "https://unpkg.com/leaflet@1.2.0/dist/images/#{image}" end from 'git://github.com/aratcliffe/Leaflet.contextmenu.git', :tag => 'v1.2.1' do diff --git a/app/assets/images/banners/banner-sotm-2017.png b/app/assets/images/banners/banner-sotm-2017.png deleted file mode 100644 index a861d1f12..000000000 Binary files a/app/assets/images/banners/banner-sotm-2017.png and /dev/null differ diff --git a/app/assets/images/banners/banner-sotmus2017.png b/app/assets/images/banners/banner-sotmus2017.png new file mode 100644 index 000000000..25382bf4a Binary files /dev/null and b/app/assets/images/banners/banner-sotmus2017.png differ diff --git a/app/assets/images/banners/osmf-membership-drive-2017.png b/app/assets/images/banners/osmf-membership-drive-2017.png new file mode 100644 index 000000000..0b62b2168 Binary files /dev/null and b/app/assets/images/banners/osmf-membership-drive-2017.png differ diff --git a/app/assets/images/banners/sotmasia-2017-banner.png b/app/assets/images/banners/sotmasia-2017-banner.png new file mode 100644 index 000000000..f18f5bf72 Binary files /dev/null and b/app/assets/images/banners/sotmasia-2017-banner.png differ diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 7d5b99f60..4461c5ab7 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,4 +1,4 @@ -//= require jquery +//= require jquery3 //= require jquery_ujs //= require jquery.timers //= require jquery.cookie @@ -79,18 +79,6 @@ $(document).ready(function () { var headerWidth = 0, compactWidth = 0; - $("header").children(":visible").each(function (i,e) { - headerWidth = headerWidth + $(e).outerWidth(); - }); - - $("body").addClass("compact"); - - $("header").children(":visible").each(function (i,e) { - compactWidth = compactWidth + $(e).outerWidth(); - }); - - $("body").removeClass("compact"); - function updateHeader() { var windowWidth = $(window).width(); @@ -103,9 +91,29 @@ $(document).ready(function () { } } - updateHeader(); + /* + * Chrome 60 and later seem to fire the "ready" callback + * before the DOM is fully ready causing us to measure the + * wrong sizes for the header elements - use a 0ms timeout + * to defer the measurement slightly as a workaround. + */ + setTimeout(function () { + $("header").children(":visible").each(function (i,e) { + headerWidth = headerWidth + $(e).outerWidth(); + }); + + $("body").addClass("compact"); + + $("header").children(":visible").each(function (i,e) { + compactWidth = compactWidth + $(e).outerWidth(); + }); + + $("body").removeClass("compact"); + + updateHeader(); - $(window).resize(updateHeader); + $(window).resize(updateHeader); + }, 0); $("#menu-icon").on("click", function(e) { e.preventDefault(); diff --git a/app/assets/javascripts/edit/id.js.erb b/app/assets/javascripts/edit/id.js.erb index 6b902587e..983117183 100644 --- a/app/assets/javascripts/edit/id.js.erb +++ b/app/assets/javascripts/edit/id.js.erb @@ -20,6 +20,8 @@ $(document).ready(function () { if (hashParams.background) params.background = hashParams.background; if (hashParams.comment) params.comment = hashParams.comment; + if (hashParams.disable_features) params.disable_features = hashParams.disable_features; + if (hashParams.hashtags) params.hashtags = hashParams.hashtags; if (hashParams.offset) params.offset = hashParams.offset; if (hashParams.walkthrough) params.walkthrough = hashParams.walkthrough; diff --git a/app/assets/javascripts/index.js b/app/assets/javascripts/index.js index b30564a1a..00e6a9d32 100644 --- a/app/assets/javascripts/index.js +++ b/app/assets/javascripts/index.js @@ -114,6 +114,7 @@ $(document).ready(function () { .removeClass('leaflet-control-locate leaflet-bar') .addClass('control-locate') .children("a") + .attr('href', '#') .removeClass('leaflet-bar-part leaflet-bar-part-single') .addClass('control-button'); diff --git a/app/assets/javascripts/index/contextmenu.js b/app/assets/javascripts/index/contextmenu.js index 148ccf908..1ee703e60 100644 --- a/app/assets/javascripts/index/contextmenu.js +++ b/app/assets/javascripts/index/contextmenu.js @@ -8,7 +8,8 @@ OSM.initializeContextMenu = function (map) { lng = latlng.lng.toFixed(precision); OSM.router.route("/directions?" + querystring.stringify({ - route: lat + "," + lng + ";" + $("#route_to").val() + from: lat + "," + lng, + to: $("#route_to").val() })); } }); @@ -22,7 +23,8 @@ OSM.initializeContextMenu = function (map) { lng = latlng.lng.toFixed(precision); OSM.router.route("/directions?" + querystring.stringify({ - route: $("#route_from").val() + ";" + lat + "," + lng + from: $("#route_from").val(), + to: lat + "," + lng })); } }); diff --git a/app/assets/javascripts/index/query.js b/app/assets/javascripts/index/query.js index 018aedf98..7ac613d71 100644 --- a/app/assets/javascripts/index/query.js +++ b/app/assets/javascripts/index/query.js @@ -146,7 +146,7 @@ OSM.Query = function(map) { if (feature.type === "node" && feature.lat && feature.lon) { geometry = L.circleMarker([feature.lat, feature.lon], featureStyle); - } else if (feature.type === "way" && feature.geometry) { + } else if (feature.type === "way" && feature.geometry && feature.geometry.length > 0) { geometry = L.polyline(feature.geometry.filter(function (point) { return point !== null; }).map(function (point) { diff --git a/app/assets/javascripts/leaflet.layers.js b/app/assets/javascripts/leaflet.layers.js index eedf718d3..a465e1449 100644 --- a/app/assets/javascripts/leaflet.layers.js +++ b/app/assets/javascripts/leaflet.layers.js @@ -49,7 +49,7 @@ L.OSM.layers = function(options) { .appendTo(item); map.whenReady(function() { - var miniMap = L.map(div[0], {attributionControl: false, zoomControl: false}) + var miniMap = L.map(div[0], {attributionControl: false, zoomControl: false, keyboard: false}) .addLayer(new layer.constructor({ apikey: layer.options.apikey })); miniMap.dragging.disable(); diff --git a/app/assets/javascripts/user.js b/app/assets/javascripts/user.js index 44872a78c..bdf044305 100644 --- a/app/assets/javascripts/user.js +++ b/app/assets/javascripts/user.js @@ -28,6 +28,7 @@ $(document).ready(function () { .removeClass('leaflet-control-locate leaflet-bar') .addClass('control-locate') .children("a") + .attr('href', '#') .removeClass('leaflet-bar-part leaflet-bar-part-single') .addClass('control-button'); @@ -84,6 +85,10 @@ $(document).ready(function () { $("select#user_auth_provider").on("change", updateAuthUID); + $("input#user_image").on("change", function () { + $("#image_action_new").prop("checked", true); + }); + function enableAuth() { $("#auth_prompt").hide(); $("#auth_field").show(); diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index 6755b7e56..4e89c04c9 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -1664,6 +1664,10 @@ tr.turn:hover { display: inline; } +.pagination { + padding-top: $lineheight; +} + /* Rules for the diary entry page */ .diary_entry { @@ -2776,12 +2780,30 @@ input.richtext_title[type="text"] { vertical-align: middle; background: 40px 40px image-url('about/sprite.png') no-repeat; - &.local { background-position: 0px 0px; } - &.community { background-position: 0px -40px; } - &.open { background-position: 0px -80px; } - &.partners { background-position: 0px -120px; } - &.infringement { background-position: 0px -160px; } - &.legal { background-position: -45px -160px; } + &.local { + /* no-r2 */ + background-position: 0px 0px; + } + &.community { + /* no-r2 */ + background-position: 0px -40px; + } + &.open { + /* no-r2 */ + background-position: 0px -80px; + } + &.partners { + /* no-r2 */ + background-position: 0px -120px; + } + &.infringement { + /* no-r2 */ + background-position: 0px -160px; + } + &.legal { + /* no-r2 */ + background-position: -45px -160px; + } } } diff --git a/app/controllers/amf_controller.rb b/app/controllers/amf_controller.rb index 51db8296d..5181280d9 100644 --- a/app/controllers/amf_controller.rb +++ b/app/controllers/amf_controller.rb @@ -151,7 +151,7 @@ class AmfController < ApplicationController cs = Changeset.find(closeid.to_i) cs.set_closed_time_now if cs.user_id != user.id - raise OSM::APIUserChangesetMismatchError.new + raise OSM::APIUserChangesetMismatchError elsif closecomment.empty? cs.save! else @@ -186,7 +186,7 @@ class AmfController < ApplicationController # Return presets (default tags, localisation etc.): # uses POTLATCH_PRESETS global, set up in OSM::Potlatch. - def getpresets(usertoken, lang) #:doc: + def getpresets(usertoken, _lang) user = getuser(usertoken) langs = if user && !user.languages.empty? @@ -229,7 +229,7 @@ class AmfController < ApplicationController begin other = YAML.safe_load(File.open(Rails.root.join("config", "potlatch", "locales", "#{lang}.yml")))[lang] loaded_lang = lang - rescue + rescue StandardError other = en end @@ -253,7 +253,7 @@ class AmfController < ApplicationController # nodes in the bbox, nodes are any visible nodes in the bbox but not # used in any way, rel is any relation which refers to either a way # or node that we're returning. - def whichways(xmin, ymin, xmax, ymax) #:doc: + def whichways(xmin, ymin, xmax, ymax) amf_handle_error_with_timeout("'whichways'", nil, nil) do enlarge = [(xmax - xmin) / 8, 0.01].min xmin -= enlarge @@ -297,7 +297,7 @@ class AmfController < ApplicationController # Find deleted ways in current bounding box (similar to whichways, but ways # with a deleted node only - not POIs or relations). - def whichways_deleted(xmin, ymin, xmax, ymax) #:doc: + def whichways_deleted(xmin, ymin, xmax, ymax) amf_handle_error_with_timeout("'whichways_deleted'", nil, nil) do enlarge = [(xmax - xmin) / 8, 0.01].min xmin -= enlarge @@ -321,7 +321,7 @@ class AmfController < ApplicationController # Get a way including nodes and tags. # Returns the way id, a Potlatch-style array of points, a hash of tags, the version number, and the user ID. - def getway(wayid) #:doc: + def getway(wayid) amf_handle_error_with_timeout("'getway' #{wayid}", "way", wayid) do if POTLATCH_USE_SQL points = sql_get_nodes_in_way(wayid) @@ -366,7 +366,7 @@ class AmfController < ApplicationController # 4. version, # 5. is this the current, visible version? (boolean) - def getway_old(id, timestamp) #:doc: + def getway_old(id, timestamp) amf_handle_error_with_timeout("'getway_old' #{id}, #{timestamp}", "way", id) do if timestamp == "" # undelete @@ -375,7 +375,7 @@ class AmfController < ApplicationController else begin # revert - timestamp = DateTime.strptime(timestamp.to_s, "%d %b %Y, %H:%M:%S") + timestamp = Time.strptime(timestamp.to_s, "%d %b %Y, %H:%M:%S") old_way = OldWay.where("way_id = ? AND timestamp <= ?", id, timestamp).unredacted.order("timestamp DESC").first unless old_way.nil? if old_way.visible @@ -411,7 +411,7 @@ class AmfController < ApplicationController # sort and collapse list (to within 2 seconds); trim all dates before the # start date of the way. - def getway_history(wayid) #:doc: + def getway_history(wayid) revdates = [] revusers = {} Way.find(wayid).old_ways.unredacted.collect do |a| @@ -444,7 +444,7 @@ class AmfController < ApplicationController # Find history of a node. Returns 'node', id, and an array of previous versions as above. - def getnode_history(nodeid) #:doc: + def getnode_history(nodeid) history = Node.find(nodeid).old_nodes.unredacted.reverse.collect do |old_node| [(old_node.timestamp + 1).strftime("%d %b %Y, %H:%M:%S")] + change_user(old_node) end @@ -492,7 +492,7 @@ class AmfController < ApplicationController # 4. list of members, # 5. version. - def getrelation(relid) #:doc: + def getrelation(relid) amf_handle_error("'getrelation' #{relid}", "relation", relid) do rel = Relation.where(:id => relid).first @@ -528,7 +528,7 @@ class AmfController < ApplicationController # 2. new relation id, # 3. version. - def putrelation(renumberednodes, renumberedways, usertoken, changeset_id, version, relid, tags, members, visible) #:doc: + def putrelation(renumberednodes, renumberedways, usertoken, changeset_id, version, relid, tags, members, visible) amf_handle_error("'putrelation' #{relid}", "relation", relid) do user = getuser(usertoken) @@ -582,7 +582,7 @@ class AmfController < ApplicationController new_relation.id = relid relation.delete_with_history!(new_relation, user) end - end # transaction + end if relid <= 0 return [0, "", relid, new_relation.id, new_relation.version] @@ -616,7 +616,7 @@ class AmfController < ApplicationController # 6. hash of changed node versions (node=>version) # 7. hash of deleted node versions (node=>version) - def putway(renumberednodes, usertoken, changeset_id, wayversion, originalway, pointlist, attributes, nodes, deletednodes) #:doc: + def putway(renumberednodes, usertoken, changeset_id, wayversion, originalway, pointlist, attributes, nodes, deletednodes) amf_handle_error("'putway' #{originalway}", "way", originalway) do # -- Initialise @@ -679,7 +679,7 @@ class AmfController < ApplicationController pointlist.collect! do |a| renumberednodes[a] ? renumberednodes[a] : a - end # renumber nodes + end new_way = Way.new new_way.tags = attributes new_way.nds = pointlist @@ -711,7 +711,7 @@ class AmfController < ApplicationController # and we don't want to delete it end end - end # transaction + end [0, "", originalway, way.id, renumberednodes, way.version, nodeversions, deletednodes] end @@ -726,7 +726,7 @@ class AmfController < ApplicationController # 3. new node id, # 4. version. - def putpoi(usertoken, changeset_id, version, id, lon, lat, tags, visible) #:doc: + def putpoi(usertoken, changeset_id, version, id, lon, lat, tags, visible) amf_handle_error("'putpoi' #{id}", "node", id) do user = getuser(usertoken) return -1, "You are not logged in, so the point could not be saved." unless user @@ -772,7 +772,7 @@ class AmfController < ApplicationController new_node.id = id node.delete_with_history!(new_node, user) end - end # transaction + end if id <= 0 return [0, "", id, new_node.id, new_node.version] @@ -787,7 +787,7 @@ class AmfController < ApplicationController # # Returns array of id, long, lat, hash of tags, (current) version. - def getpoi(id, timestamp) #:doc: + def getpoi(id, timestamp) amf_handle_error("'getpoi' #{id}", "node", id) do id = id.to_i n = Node.where(:id => id).first @@ -816,7 +816,7 @@ class AmfController < ApplicationController # of the nodes have been changed by someone else then, there is a problem! # Returns 0 (success), unchanged way id, new way version, new node versions. - def deleteway(usertoken, changeset_id, way_id, way_version, deletednodes) #:doc: + def deleteway(usertoken, changeset_id, way_id, way_version, deletednodes) amf_handle_error("'deleteway' #{way_id}", "way", way_id) do user = getuser(usertoken) return -1, "You are not logged in, so the way could not be deleted." unless user @@ -853,7 +853,7 @@ class AmfController < ApplicationController # elsewhere and we don't want to delete it end end - end # transaction + end [0, "", way_id, old_way.version, nodeversions] end end @@ -866,7 +866,7 @@ class AmfController < ApplicationController # When we are writing to the api, we need the actual user model, # not just the id, hence this abstraction - def getuser(token) #:doc: + def getuser(token) if token =~ /^(.+)\:(.+)$/ User.authenticate(:username => Regexp.last_match(1), :password => Regexp.last_match(2)) else @@ -907,7 +907,7 @@ class AmfController < ApplicationController # Alternative SQL queries for getway/whichways def sql_find_ways_in_area(bbox) - sql = <<-EOF + sql = <<-SQL SELECT DISTINCT current_ways.id AS wayid,current_ways.version AS version FROM current_way_nodes INNER JOIN current_nodes ON current_nodes.id=current_way_nodes.node_id @@ -915,20 +915,20 @@ class AmfController < ApplicationController WHERE current_nodes.visible=TRUE AND current_ways.visible=TRUE AND #{OSM.sql_for_area(bbox, 'current_nodes.')} - EOF + SQL ActiveRecord::Base.connection.select_all(sql).collect { |a| [a["wayid"].to_i, a["version"].to_i] } end def sql_find_pois_in_area(bbox) pois = [] - sql = <<-EOF + sql = <<-SQL SELECT current_nodes.id,current_nodes.latitude*0.0000001 AS lat,current_nodes.longitude*0.0000001 AS lon,current_nodes.version FROM current_nodes LEFT OUTER JOIN current_way_nodes cwn ON cwn.node_id=current_nodes.id WHERE current_nodes.visible=TRUE AND cwn.id IS NULL AND #{OSM.sql_for_area(bbox, 'current_nodes.')} - EOF + SQL ActiveRecord::Base.connection.select_all(sql).each do |row| poitags = {} ActiveRecord::Base.connection.select_all("SELECT k,v FROM current_node_tags WHERE id=#{row['id']}").each do |n| @@ -942,36 +942,36 @@ class AmfController < ApplicationController def sql_find_relations_in_area_and_ways(bbox, way_ids) # ** It would be more Potlatchy to get relations for nodes within ways # during 'getway', not here - sql = <<-EOF + sql = <<-SQL SELECT DISTINCT cr.id AS relid,cr.version AS version FROM current_relations cr INNER JOIN current_relation_members crm ON crm.id=cr.id INNER JOIN current_nodes cn ON crm.member_id=cn.id AND crm.member_type='Node' WHERE #{OSM.sql_for_area(bbox, 'cn.')} - EOF + SQL unless way_ids.empty? - sql += <<-EOF + sql += <<-SQL UNION SELECT DISTINCT cr.id AS relid,cr.version AS version FROM current_relations cr INNER JOIN current_relation_members crm ON crm.id=cr.id WHERE crm.member_type='Way' AND crm.member_id IN (#{way_ids.join(',')}) - EOF + SQL end ActiveRecord::Base.connection.select_all(sql).collect { |a| [a["relid"].to_i, a["version"].to_i] } end def sql_get_nodes_in_way(wayid) points = [] - sql = <<-EOF + sql = <<-SQL SELECT latitude*0.0000001 AS lat,longitude*0.0000001 AS lon,current_nodes.id,current_nodes.version FROM current_way_nodes,current_nodes WHERE current_way_nodes.id=#{wayid.to_i} AND current_way_nodes.node_id=current_nodes.id AND current_nodes.visible=TRUE ORDER BY sequence_id - EOF + SQL ActiveRecord::Base.connection.select_all(sql).each do |row| nodetags = {} ActiveRecord::Base.connection.select_all("SELECT k,v FROM current_node_tags WHERE id=#{row['id']}").each do |n| diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 9324a8ed5..c6cc3ba5f 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -193,7 +193,7 @@ class ApiController < ApplicationController # this "uniq" may be slightly inefficient; it may be better to first collect and output # all node-related relations, then find the *not yet covered* way-related ones etc. relations.uniq.each do |relation| - doc.root << relation.to_xml_node(nil, changeset_cache, user_display_name_cache) + doc.root << relation.to_xml_node(changeset_cache, user_display_name_cache) end response.headers["Content-Disposition"] = "attachment; filename=\"map.osm\"" diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 68fc4338e..db5d086ec 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -346,7 +346,7 @@ class ApplicationController < ActionController::Base # or raises a suitable error. +method+ should be a symbol, e.g: :put or :get. def assert_method(method) ok = request.send((method.to_s.downcase + "?").to_sym) - raise OSM::APIBadMethodError.new(method) unless ok + raise OSM::APIBadMethodError, method unless ok end ## @@ -366,7 +366,7 @@ class ApplicationController < ActionController::Base yield end rescue ActionView::Template::Error => ex - ex = ex.original_exception + ex = ex.cause if ex.is_a?(Timeout::Error) || (ex.is_a?(ActiveRecord::StatementInvalid) && ex.message =~ /execution expired/) @@ -413,7 +413,9 @@ class ApplicationController < ActionController::Base def map_layout append_content_security_policy_directives( + :child_src => %w[127.0.0.1:8111 127.0.0.1:8112], :connect_src => %w[nominatim.openstreetmap.org overpass-api.de router.project-osrm.org valhalla.mapzen.com], + :form_action => %w[render.openstreetmap.org], :script_src => %w[graphhopper.com open.mapquestapi.com], :img_src => %w[developer.mapquest.com] ) @@ -427,6 +429,10 @@ class ApplicationController < ActionController::Base request.xhr? ? "xhr" : "map" end + def allow_thirdparty_images + append_content_security_policy_directives(:img_src => %w[*]) + end + def preferred_editor editor = if params[:editor] params[:editor] diff --git a/app/controllers/changeset_controller.rb b/app/controllers/changeset_controller.rb index 1c658ccbd..898afae4a 100644 --- a/app/controllers/changeset_controller.rb +++ b/app/controllers/changeset_controller.rb @@ -28,7 +28,7 @@ class ChangesetController < ApplicationController cs = Changeset.from_xml(request.raw_post, true) # Assume that Changeset.from_xml has thrown an exception if there is an error parsing the xml - cs.user_id = current_user.id + cs.user = current_user cs.save_with_tags! # Subscribe user to changeset comments @@ -310,8 +310,8 @@ class ChangesetController < ApplicationController # Add a comment to a changeset def comment # Check the arguments are sane - raise OSM::APIBadUserInput.new("No id was given") unless params[:id] - raise OSM::APIBadUserInput.new("No text was given") if params[:text].blank? + raise OSM::APIBadUserInput, "No id was given" unless params[:id] + raise OSM::APIBadUserInput, "No text was given" if params[:text].blank? # Extract the arguments id = params[:id].to_i @@ -319,7 +319,7 @@ class ChangesetController < ApplicationController # Find the changeset and check it is valid changeset = Changeset.find(id) - raise OSM::APIChangesetNotYetClosedError.new(changeset) if changeset.is_open? + raise OSM::APIChangesetNotYetClosedError, changeset if changeset.is_open? # Add a comment to the changeset comment = changeset.comments.create(:changeset => changeset, @@ -344,15 +344,15 @@ class ChangesetController < ApplicationController # Adds a subscriber to the changeset def subscribe # Check the arguments are sane - raise OSM::APIBadUserInput.new("No id was given") unless params[:id] + raise OSM::APIBadUserInput, "No id was given" unless params[:id] # Extract the arguments id = params[:id].to_i # Find the changeset and check it is valid changeset = Changeset.find(id) - raise OSM::APIChangesetNotYetClosedError.new(changeset) if changeset.is_open? - raise OSM::APIChangesetAlreadySubscribedError.new(changeset) if changeset.subscribers.exists?(current_user.id) + raise OSM::APIChangesetNotYetClosedError, changeset if changeset.is_open? + raise OSM::APIChangesetAlreadySubscribedError, changeset if changeset.subscribers.exists?(current_user.id) # Add the subscriber changeset.subscribers << current_user @@ -365,15 +365,15 @@ class ChangesetController < ApplicationController # Removes a subscriber from the changeset def unsubscribe # Check the arguments are sane - raise OSM::APIBadUserInput.new("No id was given") unless params[:id] + raise OSM::APIBadUserInput, "No id was given" unless params[:id] # Extract the arguments id = params[:id].to_i # Find the changeset and check it is valid changeset = Changeset.find(id) - raise OSM::APIChangesetNotYetClosedError.new(changeset) if changeset.is_open? - raise OSM::APIChangesetNotSubscribedError.new(changeset) unless changeset.subscribers.exists?(current_user.id) + raise OSM::APIChangesetNotYetClosedError, changeset if changeset.is_open? + raise OSM::APIChangesetNotSubscribedError, changeset unless changeset.subscribers.exists?(current_user.id) # Remove the subscriber changeset.subscribers.delete(current_user) @@ -386,7 +386,7 @@ class ChangesetController < ApplicationController # Sets visible flag on comment to false def hide_comment # Check the arguments are sane - raise OSM::APIBadUserInput.new("No id was given") unless params[:id] + raise OSM::APIBadUserInput, "No id was given" unless params[:id] # Extract the arguments id = params[:id].to_i @@ -405,7 +405,7 @@ class ChangesetController < ApplicationController # Sets visible flag on comment to true def unhide_comment # Check the arguments are sane - raise OSM::APIBadUserInput.new("No id was given") unless params[:id] + raise OSM::APIBadUserInput, "No id was given" unless params[:id] # Extract the arguments id = params[:id].to_i @@ -434,7 +434,7 @@ class ChangesetController < ApplicationController @comments = changeset.comments.includes(:author, :changeset).limit(comments_limit) else # Return comments - @comments = ChangesetComment.includes(:author, :changeset).where(:visible => :true).order("created_at DESC").limit(comments_limit).preload(:changeset) + @comments = ChangesetComment.includes(:author, :changeset).where(:visible => true).order("created_at DESC").limit(comments_limit).preload(:changeset) end # Render the result @@ -475,19 +475,19 @@ class ChangesetController < ApplicationController changesets else # shouldn't provide both name and UID - raise OSM::APIBadUserInput.new("provide either the user ID or display name, but not both") if user && name + raise OSM::APIBadUserInput, "provide either the user ID or display name, but not both" if user && 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 + raise OSM::APIBadUserInput, "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? + raise OSM::APINotFoundError if u.nil? # should be able to get changesets of public users only, or # our own changesets regardless of public-ness. @@ -496,7 +496,7 @@ class ChangesetController < ApplicationController # changesets if they're non-public setup_user_auth - raise OSM::APINotFoundError if current_user.nil? || current_user.id != u.id + raise OSM::APINotFoundError if current_user.nil? || current_user != u end changesets.where(:user_id => u.id) @@ -514,20 +514,20 @@ class ChangesetController < ApplicationController # check that we actually have 2 elements in the array times = time.split(/,/) - raise OSM::APIBadUserInput.new("bad time range") if times.size != 2 + raise OSM::APIBadUserInput, "bad time range" if times.size != 2 - from, to = times.collect { |t| DateTime.parse(t) } + from, to = times.collect { |t| Time.parse(t) } return changesets.where("closed_at >= ? and created_at <= ?", from, to) else # if there is no comma, assume its a lower limit on time - return changesets.where("closed_at >= ?", DateTime.parse(time)) + return changesets.where("closed_at >= ?", Time.parse(time)) end - # stupid DateTime seems to throw both of these for bad parsing, so + # stupid Time seems to throw both of these for bad parsing, so # we have to catch both and ensure the correct code path is taken. rescue ArgumentError => ex - raise OSM::APIBadUserInput.new(ex.message.to_s) + raise OSM::APIBadUserInput, ex.message.to_s rescue RuntimeError => ex - raise OSM::APIBadUserInput.new(ex.message.to_s) + raise OSM::APIBadUserInput, ex.message.to_s end ## @@ -563,7 +563,7 @@ class ChangesetController < ApplicationController if ids.nil? changesets elsif ids.empty? - raise OSM::APIBadUserInput.new("No changesets were given to search for") + raise OSM::APIBadUserInput, "No changesets were given to search for" else ids = ids.split(",").collect(&:to_i) changesets.where(:id => ids) @@ -584,7 +584,7 @@ class ChangesetController < ApplicationController if params[:limit].to_i > 0 && params[:limit].to_i <= 10000 params[:limit].to_i else - raise OSM::APIBadUserInput.new("Comments limit must be between 1 and 10000") + raise OSM::APIBadUserInput, "Comments limit must be between 1 and 10000" end else 100 diff --git a/app/controllers/diary_entry_controller.rb b/app/controllers/diary_entry_controller.rb index 1b57fa59b..88febbe2f 100644 --- a/app/controllers/diary_entry_controller.rb +++ b/app/controllers/diary_entry_controller.rb @@ -8,6 +8,7 @@ class DiaryEntryController < ApplicationController before_action :check_database_readable before_action :check_database_writable, :only => [:new, :edit, :comment, :hide, :hidecomment, :subscribe, :unsubscribe] before_action :require_administrator, :only => [:hide, :hidecomment] + before_action :allow_thirdparty_images, :only => [:new, :edit, :list, :view, :comments] def new @title = t "diary_entry.new.title" diff --git a/app/controllers/geocoder_controller.rb b/app/controllers/geocoder_controller.rb index 6ec2d46f8..6110baead 100644 --- a/app/controllers/geocoder_controller.rb +++ b/app/controllers/geocoder_controller.rb @@ -1,5 +1,3 @@ -# coding: utf-8 - class GeocoderController < ApplicationController require "cgi" require "uri" @@ -19,7 +17,6 @@ class GeocoderController < ApplicationController @sources.push "geonames_reverse" if defined?(GEONAMES_USERNAME) elsif @params[:query] if @params[:query] =~ /^\d{5}(-\d{4})?$/ - @sources.push "us_postcode" @sources.push "osm_nominatim" elsif @params[:query] =~ /^(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW])\s*[0-9][ABD-HJLNP-UW-Z]{2})$/i @sources.push "uk_postcode" @@ -58,31 +55,6 @@ class GeocoderController < ApplicationController end end - def search_us_postcode - # get query parameters - query = params[:query] - - # create result array - @results = [] - - # ask geocoder.us (they have a non-commercial use api) - response = fetch_text("http://rpc.geocoder.us/service/csv?zip=#{escape_query(query)}") - - # parse the response - unless response =~ /couldn't find this zip/ - data = response.split(/\s*,\s+/) # lat,long,town,state,zip - @results.push(:lat => data[0], :lon => data[1], - :zoom => POSTCODE_ZOOM, - :prefix => "#{data[2]}, #{data[3]},", - :name => data[4]) - end - - render :action => "results" - rescue StandardError => ex - @error = "Error contacting rpc.geocoder.us: #{ex}" - render :action => "error" - end - def search_uk_postcode # get query parameters query = params[:query] @@ -313,7 +285,7 @@ class GeocoderController < ApplicationController end def escape_query(query) - URI.escape(query, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]", false, "N")) + CGI.escape(query) end def normalize_params @@ -348,7 +320,7 @@ class GeocoderController < ApplicationController Float(captures[0]) lat = !captures[2].casecmp("s").zero? ? captures[0].to_f : -captures[0].to_f lon = !captures[5].casecmp("w").zero? ? captures[3].to_f : -captures[3].to_f - rescue + rescue StandardError lat = !captures[0].casecmp("s").zero? ? captures[1].to_f : -captures[1].to_f lon = !captures[3].casecmp("w").zero? ? captures[4].to_f : -captures[4].to_f end @@ -360,7 +332,7 @@ class GeocoderController < ApplicationController Float(captures[0]) lat = !captures[3].casecmp("s").zero? ? captures[0].to_f + captures[1].to_f / 60 : -(captures[0].to_f + captures[1].to_f / 60) lon = !captures[7].casecmp("w").zero? ? captures[4].to_f + captures[5].to_f / 60 : -(captures[4].to_f + captures[5].to_f / 60) - rescue + rescue StandardError lat = !captures[0].casecmp("s").zero? ? captures[1].to_f + captures[2].to_f / 60 : -(captures[1].to_f + captures[2].to_f / 60) lon = !captures[4].casecmp("w").zero? ? captures[5].to_f + captures[6].to_f / 60 : -(captures[5].to_f + captures[6].to_f / 60) end @@ -372,7 +344,7 @@ class GeocoderController < ApplicationController Float(captures[0]) lat = !captures[4].casecmp("s").zero? ? captures[0].to_f + (captures[1].to_f + captures[2].to_f / 60) / 60 : -(captures[0].to_f + (captures[1].to_f + captures[2].to_f / 60) / 60) lon = !captures[9].casecmp("w").zero? ? captures[5].to_f + (captures[6].to_f + captures[7].to_f / 60) / 60 : -(captures[5].to_f + (captures[6].to_f + captures[7].to_f / 60) / 60) - rescue + rescue StandardError lat = !captures[0].casecmp("s").zero? ? captures[1].to_f + (captures[2].to_f + captures[3].to_f / 60) / 60 : -(captures[1].to_f + (captures[2].to_f + captures[3].to_f / 60) / 60) lon = !captures[5].casecmp("w").zero? ? captures[6].to_f + (captures[7].to_f + captures[8].to_f / 60) / 60 : -(captures[6].to_f + (captures[7].to_f + captures[8].to_f / 60) / 60) end diff --git a/app/controllers/message_controller.rb b/app/controllers/message_controller.rb index 9b39f1c05..3952b67ca 100644 --- a/app/controllers/message_controller.rb +++ b/app/controllers/message_controller.rb @@ -7,6 +7,7 @@ class MessageController < ApplicationController before_action :lookup_this_user, :only => [:new] before_action :check_database_readable before_action :check_database_writable, :only => [:new, :reply, :mark] + before_action :allow_thirdparty_images, :only => [:new, :read] # Allow the user to write a new message to another user. This action also # deals with the sending of that message to the other user when the user @@ -18,8 +19,8 @@ class MessageController < ApplicationController flash[:error] = t "message.new.limit_exceeded" else @message = Message.new(message_params) - @message.to_user_id = @this_user.id - @message.from_user_id = current_user.id + @message.recipient = @this_user + @message.sender = current_user @message.sent_on = Time.now.getutc if @message.save @@ -38,7 +39,7 @@ class MessageController < ApplicationController def reply message = Message.find(params[:message_id]) - if message.to_user_id == current_user.id + if message.recipient == current_user message.update(:message_read => true) @message = Message.new( @@ -64,8 +65,8 @@ class MessageController < ApplicationController @title = t "message.read.title" @message = Message.find(params[:message_id]) - if @message.to_user_id == current_user.id || @message.from_user_id == current_user.id - @message.message_read = true if @message.to_user_id == current_user.id + if @message.recipient == current_user || @message.sender == current_user + @message.message_read = true if @message.recipient == current_user @message.save else flash[:notice] = t "message.read.wrong_user", :user => current_user.display_name diff --git a/app/controllers/node_controller.rb b/app/controllers/node_controller.rb index 3eb127cb1..29651bceb 100644 --- a/app/controllers/node_controller.rb +++ b/app/controllers/node_controller.rb @@ -41,7 +41,7 @@ class NodeController < ApplicationController new_node = Node.from_xml(request.raw_post) unless new_node && new_node.id == node.id - raise OSM::APIBadUserInput.new("The id in the url (#{node.id}) is not the same as provided in the xml (#{new_node.id})") + raise OSM::APIBadUserInput, "The id in the url (#{node.id}) is not the same as provided in the xml (#{new_node.id})" end node.update_from(new_node, current_user) @@ -56,7 +56,7 @@ class NodeController < ApplicationController new_node = Node.from_xml(request.raw_post) unless new_node && new_node.id == node.id - raise OSM::APIBadUserInput.new("The id in the url (#{node.id}) is not the same as provided in the xml (#{new_node.id})") + raise OSM::APIBadUserInput, "The id in the url (#{node.id}) is not the same as provided in the xml (#{new_node.id})" end node.delete_with_history!(new_node, current_user) render :plain => node.version.to_s @@ -65,13 +65,13 @@ class NodeController < ApplicationController # Dump the details on many nodes whose ids are given in the "nodes" parameter. def nodes unless params["nodes"] - raise OSM::APIBadUserInput.new("The parameter nodes is required, and must be of the form nodes=id[,id[,id...]]") + raise OSM::APIBadUserInput, "The parameter nodes is required, and must be of the form nodes=id[,id[,id...]]" end ids = params["nodes"].split(",").collect(&:to_i) if ids.empty? - raise OSM::APIBadUserInput.new("No nodes were given to search for") + raise OSM::APIBadUserInput, "No nodes were given to search for" end doc = OSM::API.new.get_xml_doc diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb index f577dc2f2..92f63e304 100644 --- a/app/controllers/notes_controller.rb +++ b/app/controllers/notes_controller.rb @@ -20,10 +20,10 @@ class NotesController < ApplicationController if params[:bbox] bbox = BoundingBox.from_bbox_params(params) else - raise OSM::APIBadUserInput.new("No l was given") unless params[:l] - raise OSM::APIBadUserInput.new("No r was given") unless params[:r] - raise OSM::APIBadUserInput.new("No b was given") unless params[:b] - raise OSM::APIBadUserInput.new("No t was given") unless params[:t] + raise OSM::APIBadUserInput, "No l was given" unless params[:l] + raise OSM::APIBadUserInput, "No r was given" unless params[:r] + raise OSM::APIBadUserInput, "No b was given" unless params[:b] + raise OSM::APIBadUserInput, "No t was given" unless params[:t] bbox = BoundingBox.from_lrbt_params(params) end @@ -56,9 +56,9 @@ class NotesController < ApplicationController raise OSM::APIAccessDenied if Acl.no_note_comment(request.remote_ip) # Check the arguments are sane - raise OSM::APIBadUserInput.new("No lat was given") unless params[:lat] - raise OSM::APIBadUserInput.new("No lon was given") unless params[:lon] - raise OSM::APIBadUserInput.new("No text was given") if params[:text].blank? + raise OSM::APIBadUserInput, "No lat was given" unless params[:lat] + raise OSM::APIBadUserInput, "No lon was given" unless params[:lon] + raise OSM::APIBadUserInput, "No text was given" if params[:text].blank? # Extract the arguments lon = OSM.parse_float(params[:lon], OSM::APIBadUserInput, "lon was not a number") @@ -69,7 +69,7 @@ class NotesController < ApplicationController Note.transaction do # Create the note @note = Note.create(:lat => lat, :lon => lon) - raise OSM::APIBadUserInput.new("The note is outside this world") unless @note.in_world? + raise OSM::APIBadUserInput, "The note is outside this world" unless @note.in_world? # Save the note @note.save! @@ -92,8 +92,8 @@ class NotesController < ApplicationController raise OSM::APIAccessDenied if Acl.no_note_comment(request.remote_ip) # Check the arguments are sane - raise OSM::APIBadUserInput.new("No id was given") unless params[:id] - raise OSM::APIBadUserInput.new("No text was given") if params[:text].blank? + raise OSM::APIBadUserInput, "No id was given" unless params[:id] + raise OSM::APIBadUserInput, "No text was given" if params[:text].blank? # Extract the arguments id = params[:id].to_i @@ -103,7 +103,7 @@ class NotesController < ApplicationController @note = Note.find(id) raise OSM::APINotFoundError unless @note raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible? - raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed? + raise OSM::APINoteAlreadyClosedError, @note if @note.closed? # Add a comment to the note Note.transaction do @@ -121,7 +121,7 @@ class NotesController < ApplicationController # Close a note def close # Check the arguments are sane - raise OSM::APIBadUserInput.new("No id was given") unless params[:id] + raise OSM::APIBadUserInput, "No id was given" unless params[:id] # Extract the arguments id = params[:id].to_i @@ -131,7 +131,7 @@ class NotesController < ApplicationController @note = Note.find_by(:id => id) raise OSM::APINotFoundError unless @note raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible? - raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed? + raise OSM::APINoteAlreadyClosedError, @note if @note.closed? # Close the note and add a comment Note.transaction do @@ -151,7 +151,7 @@ class NotesController < ApplicationController # Reopen a note def reopen # Check the arguments are sane - raise OSM::APIBadUserInput.new("No id was given") unless params[:id] + raise OSM::APIBadUserInput, "No id was given" unless params[:id] # Extract the arguments id = params[:id].to_i @@ -161,7 +161,7 @@ class NotesController < ApplicationController @note = Note.find_by(:id => id) raise OSM::APINotFoundError unless @note raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible? || current_user.moderator? - raise OSM::APINoteAlreadyOpenError.new(@note) unless @note.closed? || !@note.visible? + raise OSM::APINoteAlreadyOpenError, @note unless @note.closed? || !@note.visible? # Reopen the note and add a comment Note.transaction do @@ -206,7 +206,7 @@ class NotesController < ApplicationController # Read a note def show # Check the arguments are sane - raise OSM::APIBadUserInput.new("No id was given") unless params[:id] + raise OSM::APIBadUserInput, "No id was given" unless params[:id] # Find the note and check it is valid @note = Note.find(params[:id]) @@ -226,7 +226,7 @@ class NotesController < ApplicationController # Delete (hide) a note def destroy # Check the arguments are sane - raise OSM::APIBadUserInput.new("No id was given") unless params[:id] + raise OSM::APIBadUserInput, "No id was given" unless params[:id] # Extract the arguments id = params[:id].to_i @@ -256,7 +256,7 @@ class NotesController < ApplicationController # Return a list of notes matching a given string def search # Check the arguments are sane - raise OSM::APIBadUserInput.new("No query string was given") unless params[:q] + raise OSM::APIBadUserInput, "No query string was given" unless params[:q] # Get any conditions that need to be applied @notes = closed_condition(Note.all) @@ -310,7 +310,7 @@ class NotesController < ApplicationController if params[:limit].to_i > 0 && params[:limit].to_i <= 10000 params[:limit].to_i else - raise OSM::APIBadUserInput.new("Note limit must be between 1 and 10000") + raise OSM::APIBadUserInput, "Note limit must be between 1 and 10000" end else 100 diff --git a/app/controllers/oauth_controller.rb b/app/controllers/oauth_controller.rb index 4bb129ba4..734783a35 100644 --- a/app/controllers/oauth_controller.rb +++ b/app/controllers/oauth_controller.rb @@ -38,6 +38,8 @@ class OauthController < ApplicationController protected def oauth1_authorize + append_content_security_policy_directives(:form_action => %w[*]) + if @token.invalidated? @message = t "oauth.oauthorize_failure.invalid" render :action => "authorize_failure" diff --git a/app/controllers/old_controller.rb b/app/controllers/old_controller.rb index 3815f5ae0..9adf141d9 100644 --- a/app/controllers/old_controller.rb +++ b/app/controllers/old_controller.rb @@ -19,7 +19,7 @@ class OldController < ApplicationController # the .where() method used in the lookup_old_element_versions # call won't throw an error if no records are found, so we have # to do that ourselves. - raise OSM::APINotFoundError.new if @elements.empty? + raise OSM::APINotFoundError if @elements.empty? doc = OSM::API.new.get_xml_doc diff --git a/app/controllers/relation_controller.rb b/app/controllers/relation_controller.rb index 97e832049..25532a95c 100644 --- a/app/controllers/relation_controller.rb +++ b/app/controllers/relation_controller.rb @@ -36,7 +36,7 @@ class RelationController < ApplicationController new_relation = Relation.from_xml(request.raw_post) unless new_relation && new_relation.id == relation.id - raise OSM::APIBadUserInput.new("The id in the url (#{relation.id}) is not the same as provided in the xml (#{new_relation.id})") + raise OSM::APIBadUserInput, "The id in the url (#{relation.id}) is not the same as provided in the xml (#{new_relation.id})" end relation.update_from new_relation, current_user @@ -91,7 +91,6 @@ class RelationController < ApplicationController # create XML. doc = OSM::API.new.get_xml_doc visible_nodes = {} - visible_members = { "Node" => {}, "Way" => {}, "Relation" => {} } changeset_cache = {} user_display_name_cache = {} @@ -100,25 +99,22 @@ class RelationController < ApplicationController doc.root << node.to_xml_node(changeset_cache, user_display_name_cache) visible_nodes[node.id] = node - visible_members["Node"][node.id] = true end ways.each do |way| next unless way.visible? # should be unnecessary if data is consistent. doc.root << way.to_xml_node(visible_nodes, changeset_cache, user_display_name_cache) - visible_members["Way"][way.id] = true end relations.each do |rel| next unless rel.visible? # should be unnecessary if data is consistent. - doc.root << rel.to_xml_node(nil, changeset_cache, user_display_name_cache) - visible_members["Relation"][rel.id] = true + doc.root << rel.to_xml_node(changeset_cache, user_display_name_cache) end # finally add self and output - doc.root << relation.to_xml_node(visible_members, changeset_cache, user_display_name_cache) + doc.root << relation.to_xml_node(changeset_cache, user_display_name_cache) render :xml => doc.to_s else @@ -128,13 +124,13 @@ class RelationController < ApplicationController def relations unless params["relations"] - raise OSM::APIBadUserInput.new("The parameter relations is required, and must be of the form relations=id[,id[,id...]]") + raise OSM::APIBadUserInput, "The parameter relations is required, and must be of the form relations=id[,id[,id...]]" end ids = params["relations"].split(",").collect(&:to_i) if ids.empty? - raise OSM::APIBadUserInput.new("No relations were given to search for") + raise OSM::APIBadUserInput, "No relations were given to search for" end doc = OSM::API.new.get_xml_doc diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 4b8b2f402..0d40b6691 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -91,7 +91,7 @@ class SearchController < ApplicationController end relations.each do |rel| - doc.root << rel.to_xml_node(nil, changeset_cache, user_display_name_cache) + doc.root << rel.to_xml_node(changeset_cache, user_display_name_cache) end render :xml => doc.to_s diff --git a/app/controllers/site_controller.rb b/app/controllers/site_controller.rb index c727f86d9..74dbc41f5 100644 --- a/app/controllers/site_controller.rb +++ b/app/controllers/site_controller.rb @@ -120,9 +120,9 @@ class SiteController < ApplicationController def id append_content_security_policy_directives( - :connect_src => %w[taginfo.openstreetmap.org *.mapillary.com], - :img_src => %w[*], - :script_src => %w[dev.virtualearth.net] + :connect_src => %w[*], + :img_src => %w[* blob:], + :script_src => %w[dev.virtualearth.net 'unsafe-eval'] ) render "id", :layout => false diff --git a/app/controllers/trace_controller.rb b/app/controllers/trace_controller.rb index eaeb4f5d0..105405ccf 100644 --- a/app/controllers/trace_controller.rb +++ b/app/controllers/trace_controller.rb @@ -112,7 +112,7 @@ class TraceController < ApplicationController begin do_create(params[:trace][:gpx_file], params[:trace][:tagstring], params[:trace][:description], params[:trace][:visibility]) - rescue => ex + rescue StandardError => ex logger.debug ex end @@ -149,9 +149,9 @@ class TraceController < ApplicationController if Acl.no_trace_download(request.remote_ip) head :forbidden elsif request.format == Mime[:xml] - send_file(trace.xml_file, :filename => "#{trace.id}.xml", :type => request.format.to_s, :disposition => "attachment") + send_data(trace.xml_file.read, :filename => "#{trace.id}.xml", :type => request.format.to_s, :disposition => "attachment") elsif request.format == Mime[:gpx] - send_file(trace.xml_file, :filename => "#{trace.id}.gpx", :type => request.format.to_s, :disposition => "attachment") + send_data(trace.xml_file.read, :filename => "#{trace.id}.gpx", :type => request.format.to_s, :disposition => "attachment") else send_file(trace.trace_name, :filename => "#{trace.id}#{trace.extension_name}", :type => trace.mime_type, :disposition => "attachment") end @@ -263,15 +263,7 @@ class TraceController < ApplicationController trace = Trace.visible.find(params[:id]) if trace.user == current_user - new_trace = Trace.from_xml(request.raw_post) - - unless new_trace && new_trace.id == trace.id - raise OSM::APIBadUserInput.new("The id in the url (#{trace.id}) is not the same as provided in the xml (#{new_trace.id})") - end - - trace.description = new_trace.description - trace.tags = new_trace.tags - trace.visibility = new_trace.visibility + trace.update_from_xml(request.raw_post) trace.save! head :ok @@ -298,9 +290,9 @@ class TraceController < ApplicationController if trace.public? || trace.user == current_user if request.format == Mime[:xml] - send_file(trace.xml_file, :filename => "#{trace.id}.xml", :type => request.format.to_s, :disposition => "attachment") + send_data(trace.xml_file.read, :filename => "#{trace.id}.xml", :type => request.format.to_s, :disposition => "attachment") elsif request.format == Mime[:gpx] - send_file(trace.xml_file, :filename => "#{trace.id}.gpx", :type => request.format.to_s, :disposition => "attachment") + send_data(trace.xml_file.read, :filename => "#{trace.id}.gpx", :type => request.format.to_s, :disposition => "attachment") else send_file(trace.trace_name, :filename => "#{trace.id}#{trace.extension_name}", :type => trace.mime_type, :disposition => "attachment") end diff --git a/app/controllers/user_blocks_controller.rb b/app/controllers/user_blocks_controller.rb index 45cd53728..d5820568e 100644 --- a/app/controllers/user_blocks_controller.rb +++ b/app/controllers/user_blocks_controller.rb @@ -20,7 +20,7 @@ class UserBlocksController < ApplicationController end def show - if current_user && current_user.id == @user_block.user_id + if current_user && current_user == @user_block.user @user_block.needs_view = false @user_block.save! end @@ -37,8 +37,8 @@ class UserBlocksController < ApplicationController def create if @valid_params @user_block = UserBlock.new( - :user_id => @this_user.id, - :creator_id => current_user.id, + :user => @this_user, + :creator => current_user, :reason => params[:user_block][:reason], :ends_at => Time.now.getutc + @block_period.hours, :needs_view => params[:user_block][:needs_view] @@ -57,7 +57,7 @@ class UserBlocksController < ApplicationController def update if @valid_params - if @user_block.creator_id != current_user.id + if @user_block.creator != current_user flash[:error] = t("user_block.update.only_creator_can_edit") redirect_to :action => "edit" elsif @user_block.update_attributes( diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index d3ed53c1b..5c41a79dc 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -18,6 +18,7 @@ class UserController < ApplicationController around_action :api_call_handle_error, :only => [:api_read, :api_details, :api_gpx_files] before_action :lookup_user_by_id, :only => [:api_read] before_action :lookup_user_by_name, :only => [:set_status, :delete] + before_action :allow_thirdparty_images, :only => [:view, :account] def terms @legale = params[:legale] || OSM.ip_to_country(request.remote_ip) || DEFAULT_LEGALE @@ -99,7 +100,7 @@ class UserController < ApplicationController "lat" => m[2], "lon" => m[3] }.merge(editor)) end - rescue + rescue StandardError # Use default end @@ -202,6 +203,10 @@ class UserController < ApplicationController @title = t "user.new.title" @referer = params[:referer] || session[:referer] + append_content_security_policy_directives( + :form_action => %w[accounts.google.com *.facebook.com login.live.com github.com meta.wikimedia.org] + ) + if current_user # The user is logged in already, so don't show them the signup # page, instead send them to the home page @@ -411,8 +416,8 @@ class UserController < ApplicationController if @new_friend if request.post? friend = Friend.new - friend.user_id = current_user.id - friend.friend_user_id = @new_friend.id + friend.befriender = current_user + friend.befriendee = @new_friend if current_user.is_friends_with?(@new_friend) flash[:warning] = t "user.make_friend.already_a_friend", :name => @new_friend.display_name elsif friend.save @@ -723,7 +728,7 @@ class UserController < ApplicationController begin Notifier.email_confirm(user, user.tokens.create).deliver_now - rescue + rescue StandardError # Ignore errors sending email end else diff --git a/app/controllers/user_preference_controller.rb b/app/controllers/user_preference_controller.rb index 4b556aed0..16165513a 100644 --- a/app/controllers/user_preference_controller.rb +++ b/app/controllers/user_preference_controller.rb @@ -45,7 +45,7 @@ class UserPreferenceController < ApplicationController if preference = old_preferences.delete(pt["k"]) preference.v = pt["v"] elsif new_preferences.include?(pt["k"]) - raise OSM::APIDuplicatePreferenceError.new(pt["k"]) + raise OSM::APIDuplicatePreferenceError, pt["k"] else preference = current_user.preferences.build(:k => pt["k"], :v => pt["v"]) end diff --git a/app/controllers/user_roles_controller.rb b/app/controllers/user_roles_controller.rb index 2f5b5a84c..536790dc5 100644 --- a/app/controllers/user_roles_controller.rb +++ b/app/controllers/user_roles_controller.rb @@ -10,7 +10,7 @@ class UserRolesController < ApplicationController before_action :in_role, :only => [:revoke] def grant - @this_user.roles.create(:role => @role, :granter_id => current_user.id) + @this_user.roles.create(:role => @role, :granter => current_user) redirect_to :controller => "user", :action => "view", :display_name => @this_user.display_name end diff --git a/app/controllers/way_controller.rb b/app/controllers/way_controller.rb index 8e9e00b88..e48073e10 100644 --- a/app/controllers/way_controller.rb +++ b/app/controllers/way_controller.rb @@ -36,7 +36,7 @@ class WayController < ApplicationController new_way = Way.from_xml(request.raw_post) unless new_way && new_way.id == way.id - raise OSM::APIBadUserInput.new("The id in the url (#{way.id}) is not the same as provided in the xml (#{new_way.id})") + raise OSM::APIBadUserInput, "The id in the url (#{way.id}) is not the same as provided in the xml (#{new_way.id})" end way.update_from(new_way, current_user) @@ -81,14 +81,12 @@ class WayController < ApplicationController def ways unless params["ways"] - raise OSM::APIBadUserInput.new("The parameter ways is required, and must be of the form ways=id[,id[,id...]]") + raise OSM::APIBadUserInput, "The parameter ways is required, and must be of the form ways=id[,id[,id...]]" end ids = params["ways"].split(",").collect(&:to_i) - if ids.empty? - raise OSM::APIBadUserInput.new("No ways were given to search for") - end + raise OSM::APIBadUserInput, "No ways were given to search for" if ids.empty? doc = OSM::API.new.get_xml_doc diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index d27b47f27..a330eb5f9 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -3,9 +3,9 @@ module ApplicationHelper def linkify(text) if text.html_safe? - Rinku.auto_link(text, :urls, tag_options(:rel => "nofollow")).html_safe + Rinku.auto_link(text, :urls, tag_builder.tag_options(:rel => "nofollow")).html_safe else - Rinku.auto_link(text, :urls, tag_options(:rel => "nofollow")) + Rinku.auto_link(text, :urls, tag_builder.tag_options(:rel => "nofollow")) end end diff --git a/app/helpers/banner_helper.rb b/app/helpers/banner_helper.rb index 4e888173b..661369454 100644 --- a/app/helpers/banner_helper.rb +++ b/app/helpers/banner_helper.rb @@ -4,7 +4,7 @@ module BannerHelper enddate = v[:enddate] begin parsed = enddate && Date.parse(enddate) - rescue + rescue StandardError parsed = nil end !parsed.is_a?(Date) || (parsed.is_a?(Date) && parsed.past?) diff --git a/app/helpers/browse_helper.rb b/app/helpers/browse_helper.rb index 998ea405f..c4ce41b06 100644 --- a/app/helpers/browse_helper.rb +++ b/app/helpers/browse_helper.rb @@ -1,4 +1,4 @@ -require "uri" +require "cgi" module BrowseHelper def printable_name(object, version = false) @@ -114,9 +114,9 @@ module BrowseHelper # the correct page. lookup_us = lookup.tr(" ", "_") - if page = WIKI_PAGES[locale][type][lookup_us] rescue nil + if page = WIKI_PAGES.dig(locale, type, lookup_us) url = "http://wiki.openstreetmap.org/wiki/#{page}?uselang=#{locale}" - elsif page = WIKI_PAGES["en"][type][lookup_us] rescue nil + elsif page = WIKI_PAGES.dig("en", type, lookup_us) url = "http://wiki.openstreetmap.org/wiki/#{page}?uselang=#{locale}" end @@ -151,7 +151,7 @@ module BrowseHelper # Must break it up to correctly build the url value = Regexp.last_match(1) section = "#" + Regexp.last_match(2) - encoded_section = "#" + URI.encode(Regexp.last_match(2).gsub(/ +/, "_"), /[^A-Za-z0-9:_]/).tr("%", ".") + encoded_section = "#" + CGI.escape(Regexp.last_match(2).gsub(/ +/, "_")).tr("%", ".") else section = "" encoded_section = "" diff --git a/app/helpers/changeset_helper.rb b/app/helpers/changeset_helper.rb index cc008aab7..7eb389023 100644 --- a/app/helpers/changeset_helper.rb +++ b/app/helpers/changeset_helper.rb @@ -10,7 +10,7 @@ module ChangesetHelper end def changeset_details(changeset) - if changeset.closed_at > DateTime.now + if changeset.closed_at > Time.now action = :created time = distance_of_time_in_words_to_now(changeset.created_at) title = l(changeset.created_at) diff --git a/app/helpers/open_graph_helper.rb b/app/helpers/open_graph_helper.rb index ab7e230cb..11cfe5030 100644 --- a/app/helpers/open_graph_helper.rb +++ b/app/helpers/open_graph_helper.rb @@ -2,7 +2,7 @@ module OpenGraphHelper def opengraph_tags(title = nil) tags = { "og:site_name" => t("layouts.project_name.title"), - "og:title" => [t("layouts.project_name.title"), title].compact.join(" | "), + "og:title" => [title, t("layouts.project_name.title")].compact.join(" | "), "og:type" => "website", "og:image" => image_url("osm_logo_256.png", :protocol => "http"), "og:image:secure_url" => image_url("osm_logo_256.png", :protocol => "https"), diff --git a/app/helpers/title_helper.rb b/app/helpers/title_helper.rb index 8b1eb53b6..88a5a2a74 100644 --- a/app/helpers/title_helper.rb +++ b/app/helpers/title_helper.rb @@ -8,10 +8,10 @@ module TitleHelper def set_title(title = nil) if title @title = TitleHelper.coder.decode(title.gsub("", "\u202a").gsub("", "\u202c")) - response.headers["X-Page-Title"] = URI.escape(t("layouts.project_name.title") + " | " + @title) + response.headers["X-Page-Title"] = ERB::Util.u(@title + " | " + t("layouts.project_name.title")) else @title = title - response.headers["X-Page-Title"] = URI.escape(t("layouts.project_name.title")) + response.headers["X-Page-Title"] = ERB::Util.u(t("layouts.project_name.title")) end end end diff --git a/app/models/access_token.rb b/app/models/access_token.rb index f690c9754..e5ba2e240 100644 --- a/app/models/access_token.rb +++ b/app/models/access_token.rb @@ -1,3 +1,40 @@ +# == Schema Information +# +# Table name: oauth_tokens +# +# id :integer not null, primary key +# user_id :integer +# type :string(20) +# client_application_id :integer +# token :string(50) +# secret :string(50) +# authorized_at :datetime +# invalidated_at :datetime +# created_at :datetime +# updated_at :datetime +# allow_read_prefs :boolean default(FALSE), not null +# allow_write_prefs :boolean default(FALSE), not null +# allow_write_diary :boolean default(FALSE), not null +# allow_write_api :boolean default(FALSE), not null +# allow_read_gpx :boolean default(FALSE), not null +# allow_write_gpx :boolean default(FALSE), not null +# callback_url :string +# verifier :string(20) +# scope :string +# valid_to :datetime +# allow_write_notes :boolean default(FALSE), not null +# +# Indexes +# +# index_oauth_tokens_on_token (token) UNIQUE +# index_oauth_tokens_on_user_id (user_id) +# +# Foreign Keys +# +# oauth_tokens_client_application_id_fkey (client_application_id => client_applications.id) +# oauth_tokens_user_id_fkey (user_id => users.id) +# + class AccessToken < OauthToken belongs_to :user belongs_to :client_application diff --git a/app/models/acl.rb b/app/models/acl.rb index 529ccbe3b..095bad89b 100644 --- a/app/models/acl.rb +++ b/app/models/acl.rb @@ -1,3 +1,18 @@ +# == Schema Information +# +# Table name: acls +# +# id :integer not null, primary key +# address :inet +# k :string not null +# v :string +# domain :string +# +# Indexes +# +# acls_k_idx (k) +# + class Acl < ActiveRecord::Base validates :k, :presence => true diff --git a/app/models/changeset.rb b/app/models/changeset.rb index f41ad9955..37d26e0a7 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -1,3 +1,30 @@ +# == Schema Information +# +# Table name: changesets +# +# id :integer not null, primary key +# user_id :integer not null +# created_at :datetime not null +# min_lat :integer +# max_lat :integer +# min_lon :integer +# max_lon :integer +# closed_at :datetime not null +# num_changes :integer default(0), not null +# +# Indexes +# +# changesets_bbox_idx (min_lat,max_lat,min_lon,max_lon) +# changesets_closed_at_idx (closed_at) +# changesets_created_at_idx (created_at) +# changesets_user_id_created_at_idx (user_id,created_at) +# changesets_user_id_id_idx (user_id,id) +# +# Foreign Keys +# +# changesets_user_id_fkey (user_id => users.id) +# + class Changeset < ActiveRecord::Base require "xml/libxml" @@ -133,7 +160,7 @@ class Changeset < ActiveRecord::Base attr_writer :tags def add_tag_keyval(k, v) - @tags = {} unless @tags + @tags ||= {} # duplicate tags are now forbidden, so we can't allow values # in the hash to be overwritten. @@ -241,10 +268,10 @@ class Changeset < ActiveRecord::Base # bounding box, only the tags of the changeset. def update_from(other, user) # ensure that only the user who opened the changeset may modify it. - raise OSM::APIUserChangesetMismatchError.new unless user.id == user_id + raise OSM::APIUserChangesetMismatchError unless user.id == user_id # can't change a closed changeset - raise OSM::APIChangesetAlreadyClosedError.new(self) unless is_open? + raise OSM::APIChangesetAlreadyClosedError, self unless is_open? # copy the other's tags self.tags = other.tags diff --git a/app/models/changeset_comment.rb b/app/models/changeset_comment.rb index 2fedadff0..756fda14c 100644 --- a/app/models/changeset_comment.rb +++ b/app/models/changeset_comment.rb @@ -1,3 +1,24 @@ +# == Schema Information +# +# Table name: changeset_comments +# +# id :integer not null, primary key +# changeset_id :integer not null +# author_id :integer not null +# body :text not null +# created_at :datetime not null +# visible :boolean not null +# +# Indexes +# +# index_changeset_comments_on_created_at (created_at) +# +# Foreign Keys +# +# changeset_comments_author_id_fkey (author_id => users.id) +# changeset_comments_changeset_id_fkey (changeset_id => changesets.id) +# + class ChangesetComment < ActiveRecord::Base belongs_to :changeset belongs_to :author, :class_name => "User" diff --git a/app/models/changeset_tag.rb b/app/models/changeset_tag.rb index 7ffba0dc3..8d6cd45ac 100644 --- a/app/models/changeset_tag.rb +++ b/app/models/changeset_tag.rb @@ -1,3 +1,20 @@ +# == Schema Information +# +# Table name: changeset_tags +# +# changeset_id :integer not null, primary key +# k :string default(""), not null, primary key +# v :string default(""), not null +# +# Indexes +# +# changeset_tags_id_idx (changeset_id) +# +# Foreign Keys +# +# changeset_tags_id_fkey (changeset_id => changesets.id) +# + class ChangesetTag < ActiveRecord::Base self.primary_keys = "changeset_id", "k" diff --git a/app/models/client_application.rb b/app/models/client_application.rb index 85b6ba68a..67b86417a 100644 --- a/app/models/client_application.rb +++ b/app/models/client_application.rb @@ -1,3 +1,35 @@ +# == Schema Information +# +# Table name: client_applications +# +# id :integer not null, primary key +# name :string +# url :string +# support_url :string +# callback_url :string +# key :string(50) +# secret :string(50) +# user_id :integer +# created_at :datetime +# updated_at :datetime +# allow_read_prefs :boolean default(FALSE), not null +# allow_write_prefs :boolean default(FALSE), not null +# allow_write_diary :boolean default(FALSE), not null +# allow_write_api :boolean default(FALSE), not null +# allow_read_gpx :boolean default(FALSE), not null +# allow_write_gpx :boolean default(FALSE), not null +# allow_write_notes :boolean default(FALSE), not null +# +# Indexes +# +# index_client_applications_on_key (key) UNIQUE +# index_client_applications_on_user_id (user_id) +# +# Foreign Keys +# +# client_applications_user_id_fkey (user_id => users.id) +# + require "oauth" class ClientApplication < ActiveRecord::Base @@ -43,7 +75,7 @@ class ClientApplication < ActiveRecord::Base @oauth_client ||= OAuth::Consumer.new(key, secret) end - def create_request_token(params = {}) + def create_request_token(_params = {}) params = { :client_application => self, :callback_url => token_callback_url } permissions.each do |p| params[p] = true diff --git a/app/models/diary_comment.rb b/app/models/diary_comment.rb index 2796eb612..8a99c7b2c 100644 --- a/app/models/diary_comment.rb +++ b/app/models/diary_comment.rb @@ -1,3 +1,27 @@ +# == Schema Information +# +# Table name: diary_comments +# +# id :integer not null, primary key +# diary_entry_id :integer not null +# user_id :integer not null +# body :text not null +# created_at :datetime not null +# updated_at :datetime not null +# visible :boolean default(TRUE), not null +# body_format :enum default("markdown"), not null +# +# Indexes +# +# diary_comment_user_id_created_at_index (user_id,created_at) +# diary_comments_entry_id_idx (diary_entry_id,id) UNIQUE +# +# Foreign Keys +# +# diary_comments_diary_entry_id_fkey (diary_entry_id => diary_entries.id) +# diary_comments_user_id_fkey (user_id => users.id) +# + class DiaryComment < ActiveRecord::Base belongs_to :user belongs_to :diary_entry diff --git a/app/models/diary_entry.rb b/app/models/diary_entry.rb index 143ddc1dc..2a24d8002 100644 --- a/app/models/diary_entry.rb +++ b/app/models/diary_entry.rb @@ -1,3 +1,31 @@ +# == Schema Information +# +# Table name: diary_entries +# +# id :integer not null, primary key +# user_id :integer not null +# title :string not null +# body :text not null +# created_at :datetime not null +# updated_at :datetime not null +# latitude :float +# longitude :float +# language_code :string default("en"), not null +# visible :boolean default(TRUE), not null +# body_format :enum default("markdown"), not null +# +# Indexes +# +# diary_entry_created_at_index (created_at) +# diary_entry_language_code_created_at_index (language_code,created_at) +# diary_entry_user_id_created_at_index (user_id,created_at) +# +# Foreign Keys +# +# diary_entries_language_code_fkey (language_code => languages.code) +# diary_entries_user_id_fkey (user_id => users.id) +# + class DiaryEntry < ActiveRecord::Base belongs_to :user, :counter_cache => true belongs_to :language, :foreign_key => "language_code" diff --git a/app/models/diary_entry_subscription.rb b/app/models/diary_entry_subscription.rb index 8b96f6074..6d24c4598 100644 --- a/app/models/diary_entry_subscription.rb +++ b/app/models/diary_entry_subscription.rb @@ -1,3 +1,20 @@ +# == Schema Information +# +# Table name: diary_entry_subscriptions +# +# user_id :integer not null, primary key +# diary_entry_id :integer not null, primary key +# +# Indexes +# +# index_diary_entry_subscriptions_on_diary_entry_id (diary_entry_id) +# +# Foreign Keys +# +# diary_entry_subscriptions_diary_entry_id_fkey (diary_entry_id => diary_entries.id) +# diary_entry_subscriptions_user_id_fkey (user_id => users.id) +# + class DiaryEntrySubscription < ActiveRecord::Base self.primary_keys = "user_id", "diary_entry_id" diff --git a/app/models/friend.rb b/app/models/friend.rb index d740a711c..86da87b93 100644 --- a/app/models/friend.rb +++ b/app/models/friend.rb @@ -1,3 +1,22 @@ +# == Schema Information +# +# Table name: friends +# +# id :integer not null, primary key +# user_id :integer not null +# friend_user_id :integer not null +# +# Indexes +# +# friends_user_id_idx (user_id) +# user_id_idx (friend_user_id) +# +# Foreign Keys +# +# friends_friend_user_id_fkey (friend_user_id => users.id) +# friends_user_id_fkey (user_id => users.id) +# + class Friend < ActiveRecord::Base belongs_to :befriender, :class_name => "User", :foreign_key => :user_id belongs_to :befriendee, :class_name => "User", :foreign_key => :friend_user_id diff --git a/app/models/language.rb b/app/models/language.rb index 776182e63..67e98569b 100644 --- a/app/models/language.rb +++ b/app/models/language.rb @@ -1,3 +1,12 @@ +# == Schema Information +# +# Table name: languages +# +# code :string not null, primary key +# english_name :string not null +# native_name :string +# + class Language < ActiveRecord::Base self.primary_key = "code" diff --git a/app/models/message.rb b/app/models/message.rb index 2a0cea4a1..aff628e03 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -1,3 +1,29 @@ +# == Schema Information +# +# Table name: messages +# +# id :integer not null, primary key +# from_user_id :integer not null +# title :string not null +# body :text not null +# sent_on :datetime not null +# message_read :boolean default(FALSE), not null +# to_user_id :integer not null +# to_user_visible :boolean default(TRUE), not null +# from_user_visible :boolean default(TRUE), not null +# body_format :enum default("markdown"), not null +# +# Indexes +# +# messages_from_user_id_idx (from_user_id) +# messages_to_user_id_idx (to_user_id) +# +# Foreign Keys +# +# messages_from_user_id_fkey (from_user_id => users.id) +# messages_to_user_id_fkey (to_user_id => users.id) +# + require "validators" class Message < ActiveRecord::Base diff --git a/app/models/node.rb b/app/models/node.rb index f4367e459..c09fcbd67 100644 --- a/app/models/node.rb +++ b/app/models/node.rb @@ -1,3 +1,26 @@ +# == Schema Information +# +# Table name: current_nodes +# +# id :integer not null, primary key +# latitude :integer not null +# longitude :integer not null +# changeset_id :integer not null +# visible :boolean not null +# timestamp :datetime not null +# tile :integer not null +# version :integer not null +# +# Indexes +# +# current_nodes_tile_idx (tile) +# current_nodes_timestamp_idx (timestamp) +# +# Foreign Keys +# +# current_nodes_changeset_id_fkey (changeset_id => changesets.id) +# + class Node < ActiveRecord::Base require "xml/libxml" @@ -70,7 +93,7 @@ class Node < ActiveRecord::Base raise OSM::APIBadXMLError.new("node", pt, "Changeset id is missing") if pt["changeset"].nil? node.changeset_id = pt["changeset"].to_i - raise OSM::APIBadUserInput.new("The node is outside this world") unless node.in_world? + raise OSM::APIBadUserInput, "The node is outside this world" unless node.in_world? # version must be present unless creating raise OSM::APIBadXMLError.new("node", pt, "Version is required when updating") unless create || !pt["version"].nil? @@ -81,7 +104,7 @@ class Node < ActiveRecord::Base node.id = pt["id"].to_i # .to_i will return 0 if there is no number that can be parsed. # We want to make sure that there is no id with zero anyway - raise OSM::APIBadUserInput.new("ID of node cannot be zero when updating.") if node.id.zero? + raise OSM::APIBadUserInput, "ID of node cannot be zero when updating." if node.id.zero? end # We don't care about the time, as it is explicitly set on create/update/delete @@ -120,10 +143,10 @@ class Node < ActiveRecord::Base lock! check_consistency(self, new_node, user) ways = Way.joins(:way_nodes).where(:visible => true, :current_way_nodes => { :node_id => id }).order(:id) - raise OSM::APIPreconditionFailedError.new("Node #{id} is still used by ways #{ways.collect(&:id).join(',')}.") unless ways.empty? + raise OSM::APIPreconditionFailedError, "Node #{id} is still used by ways #{ways.collect(&:id).join(',')}." unless ways.empty? rels = Relation.joins(:relation_members).where(:visible => true, :current_relation_members => { :member_type => "Node", :member_id => id }).order(:id) - raise OSM::APIPreconditionFailedError.new("Node #{id} is still used by relations #{rels.collect(&:id).join(',')}.") unless rels.empty? + raise OSM::APIPreconditionFailedError, "Node #{id} is still used by relations #{rels.collect(&:id).join(',')}." unless rels.empty? self.changeset_id = new_node.changeset_id self.tags = {} @@ -205,7 +228,7 @@ class Node < ActiveRecord::Base attr_writer :tags def add_tag_key_val(k, v) - @tags = {} unless @tags + @tags ||= {} # duplicate tags are now forbidden, so we can't allow values # in the hash to be overwritten. diff --git a/app/models/node_tag.rb b/app/models/node_tag.rb index 5f2f9efc9..20065b993 100644 --- a/app/models/node_tag.rb +++ b/app/models/node_tag.rb @@ -1,3 +1,16 @@ +# == Schema Information +# +# Table name: current_node_tags +# +# node_id :integer not null, primary key +# k :string default(""), not null, primary key +# v :string default(""), not null +# +# Foreign Keys +# +# current_node_tags_id_fkey (node_id => current_nodes.id) +# + class NodeTag < ActiveRecord::Base self.table_name = "current_node_tags" self.primary_keys = "node_id", "k" diff --git a/app/models/note.rb b/app/models/note.rb index d2c36071d..b7f6928b8 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -1,3 +1,23 @@ +# == Schema Information +# +# Table name: notes +# +# id :integer not null, primary key +# latitude :integer not null +# longitude :integer not null +# tile :integer not null +# updated_at :datetime not null +# created_at :datetime not null +# status :enum not null +# closed_at :datetime +# +# Indexes +# +# notes_created_at_idx (created_at) +# notes_tile_status_idx (tile,status) +# notes_updated_at_idx (updated_at) +# + class Note < ActiveRecord::Base include GeoRecord diff --git a/app/models/note_comment.rb b/app/models/note_comment.rb index aa8635aad..f8450d0a3 100644 --- a/app/models/note_comment.rb +++ b/app/models/note_comment.rb @@ -1,3 +1,28 @@ +# == Schema Information +# +# Table name: note_comments +# +# id :integer not null, primary key +# note_id :integer not null +# visible :boolean not null +# created_at :datetime not null +# author_ip :inet +# author_id :integer +# body :text +# event :enum +# +# Indexes +# +# index_note_comments_on_body (to_tsvector('english'::regconfig, body)) +# index_note_comments_on_created_at (created_at) +# note_comments_note_id_idx (note_id) +# +# Foreign Keys +# +# note_comments_author_id_fkey (author_id => users.id) +# note_comments_note_id_fkey (note_id => notes.id) +# + class NoteComment < ActiveRecord::Base belongs_to :note, :foreign_key => :note_id, :touch => true belongs_to :author, :class_name => "User", :foreign_key => :author_id diff --git a/app/models/oauth2_token.rb b/app/models/oauth2_token.rb index 1e67194fe..3435b25a3 100644 --- a/app/models/oauth2_token.rb +++ b/app/models/oauth2_token.rb @@ -1,3 +1,40 @@ +# == Schema Information +# +# Table name: oauth_tokens +# +# id :integer not null, primary key +# user_id :integer +# type :string(20) +# client_application_id :integer +# token :string(50) +# secret :string(50) +# authorized_at :datetime +# invalidated_at :datetime +# created_at :datetime +# updated_at :datetime +# allow_read_prefs :boolean default(FALSE), not null +# allow_write_prefs :boolean default(FALSE), not null +# allow_write_diary :boolean default(FALSE), not null +# allow_write_api :boolean default(FALSE), not null +# allow_read_gpx :boolean default(FALSE), not null +# allow_write_gpx :boolean default(FALSE), not null +# callback_url :string +# verifier :string(20) +# scope :string +# valid_to :datetime +# allow_write_notes :boolean default(FALSE), not null +# +# Indexes +# +# index_oauth_tokens_on_token (token) UNIQUE +# index_oauth_tokens_on_user_id (user_id) +# +# Foreign Keys +# +# oauth_tokens_client_application_id_fkey (client_application_id => client_applications.id) +# oauth_tokens_user_id_fkey (user_id => users.id) +# + class Oauth2Token < AccessToken attr_accessor :state @@ -9,9 +46,9 @@ class Oauth2Token < AccessToken def to_query q = "access_token=#{token}&token_type=bearer" - q << "&state=#{URI.escape(state)}" if @state + q << "&state=#{CGI.escape(state)}" if @state q << "&expires_in=#{expires_in}" if expires_at - q << "&scope=#{URI.escape(scope)}" if scope + q << "&scope=#{CGI.escape(scope)}" if scope q end diff --git a/app/models/oauth2_verifier.rb b/app/models/oauth2_verifier.rb index a404d0c7a..3eca1038c 100644 --- a/app/models/oauth2_verifier.rb +++ b/app/models/oauth2_verifier.rb @@ -1,3 +1,40 @@ +# == Schema Information +# +# Table name: oauth_tokens +# +# id :integer not null, primary key +# user_id :integer +# type :string(20) +# client_application_id :integer +# token :string(50) +# secret :string(50) +# authorized_at :datetime +# invalidated_at :datetime +# created_at :datetime +# updated_at :datetime +# allow_read_prefs :boolean default(FALSE), not null +# allow_write_prefs :boolean default(FALSE), not null +# allow_write_diary :boolean default(FALSE), not null +# allow_write_api :boolean default(FALSE), not null +# allow_read_gpx :boolean default(FALSE), not null +# allow_write_gpx :boolean default(FALSE), not null +# callback_url :string +# verifier :string(20) +# scope :string +# valid_to :datetime +# allow_write_notes :boolean default(FALSE), not null +# +# Indexes +# +# index_oauth_tokens_on_token (token) UNIQUE +# index_oauth_tokens_on_user_id (user_id) +# +# Foreign Keys +# +# oauth_tokens_client_application_id_fkey (client_application_id => client_applications.id) +# oauth_tokens_user_id_fkey (user_id => users.id) +# + class Oauth2Verifier < OauthToken validates :user, :presence => true, :associated => true @@ -21,7 +58,7 @@ class Oauth2Verifier < OauthToken def to_query q = "code=#{token}" - q << "&state=#{URI.escape(state)}" if @state + q << "&state=#{CGI.escape(state)}" if @state q end diff --git a/app/models/oauth_nonce.rb b/app/models/oauth_nonce.rb index e0510dcbf..0952f068e 100644 --- a/app/models/oauth_nonce.rb +++ b/app/models/oauth_nonce.rb @@ -1,3 +1,18 @@ +# == Schema Information +# +# Table name: oauth_nonces +# +# id :integer not null, primary key +# nonce :string +# timestamp :integer +# created_at :datetime +# updated_at :datetime +# +# Indexes +# +# index_oauth_nonces_on_nonce_and_timestamp (nonce,timestamp) UNIQUE +# + # 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 diff --git a/app/models/oauth_token.rb b/app/models/oauth_token.rb index 9a3e7de9e..fd332723f 100644 --- a/app/models/oauth_token.rb +++ b/app/models/oauth_token.rb @@ -1,3 +1,40 @@ +# == Schema Information +# +# Table name: oauth_tokens +# +# id :integer not null, primary key +# user_id :integer +# type :string(20) +# client_application_id :integer +# token :string(50) +# secret :string(50) +# authorized_at :datetime +# invalidated_at :datetime +# created_at :datetime +# updated_at :datetime +# allow_read_prefs :boolean default(FALSE), not null +# allow_write_prefs :boolean default(FALSE), not null +# allow_write_diary :boolean default(FALSE), not null +# allow_write_api :boolean default(FALSE), not null +# allow_read_gpx :boolean default(FALSE), not null +# allow_write_gpx :boolean default(FALSE), not null +# callback_url :string +# verifier :string(20) +# scope :string +# valid_to :datetime +# allow_write_notes :boolean default(FALSE), not null +# +# Indexes +# +# index_oauth_tokens_on_token (token) UNIQUE +# index_oauth_tokens_on_user_id (user_id) +# +# Foreign Keys +# +# oauth_tokens_client_application_id_fkey (client_application_id => client_applications.id) +# oauth_tokens_user_id_fkey (user_id => users.id) +# + class OauthToken < ActiveRecord::Base belongs_to :client_application belongs_to :user diff --git a/app/models/old_node.rb b/app/models/old_node.rb index b103e5c73..9690dc46c 100644 --- a/app/models/old_node.rb +++ b/app/models/old_node.rb @@ -1,3 +1,29 @@ +# == Schema Information +# +# Table name: nodes +# +# node_id :integer not null, primary key +# latitude :integer not null +# longitude :integer not null +# changeset_id :integer not null +# visible :boolean not null +# timestamp :datetime not null +# tile :integer not null +# version :integer not null, primary key +# redaction_id :integer +# +# Indexes +# +# nodes_changeset_id_idx (changeset_id) +# nodes_tile_idx (tile) +# nodes_timestamp_idx (timestamp) +# +# Foreign Keys +# +# nodes_changeset_id_fkey (changeset_id => changesets.id) +# nodes_redaction_id_fkey (redaction_id => redactions.id) +# + class OldNode < ActiveRecord::Base include GeoRecord include ConsistencyValidations diff --git a/app/models/old_node_tag.rb b/app/models/old_node_tag.rb index f1df02c84..9e03d34f9 100644 --- a/app/models/old_node_tag.rb +++ b/app/models/old_node_tag.rb @@ -1,3 +1,17 @@ +# == Schema Information +# +# Table name: node_tags +# +# node_id :integer not null, primary key +# version :integer not null, primary key +# k :string default(""), not null, primary key +# v :string default(""), not null +# +# Foreign Keys +# +# node_tags_id_fkey (node_id => nodes.node_id) +# + class OldNodeTag < ActiveRecord::Base self.table_name = "node_tags" self.primary_keys = "node_id", "version", "k" diff --git a/app/models/old_relation.rb b/app/models/old_relation.rb index 0e85122a4..3470561ce 100644 --- a/app/models/old_relation.rb +++ b/app/models/old_relation.rb @@ -1,3 +1,25 @@ +# == Schema Information +# +# Table name: relations +# +# relation_id :integer default(0), not null, primary key +# changeset_id :integer not null +# timestamp :datetime not null +# version :integer not null, primary key +# visible :boolean default(TRUE), not null +# redaction_id :integer +# +# Indexes +# +# relations_changeset_id_idx (changeset_id) +# relations_timestamp_idx (timestamp) +# +# Foreign Keys +# +# relations_changeset_id_fkey (changeset_id => changesets.id) +# relations_redaction_id_fkey (redaction_id => redactions.id) +# + class OldRelation < ActiveRecord::Base include ConsistencyValidations include ObjectMetadata diff --git a/app/models/old_relation_member.rb b/app/models/old_relation_member.rb index 77a5a3786..a74637435 100644 --- a/app/models/old_relation_member.rb +++ b/app/models/old_relation_member.rb @@ -1,3 +1,23 @@ +# == Schema Information +# +# Table name: relation_members +# +# relation_id :integer default(0), not null, primary key +# member_type :enum not null +# member_id :integer not null +# member_role :string not null +# version :integer default(0), not null, primary key +# sequence_id :integer default(0), not null, primary key +# +# Indexes +# +# relation_members_member_idx (member_type,member_id) +# +# Foreign Keys +# +# relation_members_id_fkey (relation_id => relations.relation_id) +# + class OldRelationMember < ActiveRecord::Base self.table_name = "relation_members" self.primary_keys = "relation_id", "version", "sequence_id" diff --git a/app/models/old_relation_tag.rb b/app/models/old_relation_tag.rb index ad3b72734..052b60853 100644 --- a/app/models/old_relation_tag.rb +++ b/app/models/old_relation_tag.rb @@ -1,3 +1,17 @@ +# == Schema Information +# +# Table name: relation_tags +# +# relation_id :integer default(0), not null, primary key +# k :string default(""), not null, primary key +# v :string default(""), not null +# version :integer not null, primary key +# +# Foreign Keys +# +# relation_tags_id_fkey (relation_id => relations.relation_id) +# + class OldRelationTag < ActiveRecord::Base self.table_name = "relation_tags" self.primary_keys = "relation_id", "version", "k" diff --git a/app/models/old_way.rb b/app/models/old_way.rb index 63c4d8b65..baca05d33 100644 --- a/app/models/old_way.rb +++ b/app/models/old_way.rb @@ -1,3 +1,25 @@ +# == Schema Information +# +# Table name: ways +# +# way_id :integer default(0), not null, primary key +# changeset_id :integer not null +# timestamp :datetime not null +# version :integer not null, primary key +# visible :boolean default(TRUE), not null +# redaction_id :integer +# +# Indexes +# +# ways_changeset_id_idx (changeset_id) +# ways_timestamp_idx (timestamp) +# +# Foreign Keys +# +# ways_changeset_id_fkey (changeset_id => changesets.id) +# ways_redaction_id_fkey (redaction_id => redactions.id) +# + class OldWay < ActiveRecord::Base include ConsistencyValidations include ObjectMetadata diff --git a/app/models/old_way_node.rb b/app/models/old_way_node.rb index 23ff503ed..e1627d3fa 100644 --- a/app/models/old_way_node.rb +++ b/app/models/old_way_node.rb @@ -1,3 +1,21 @@ +# == Schema Information +# +# Table name: way_nodes +# +# way_id :integer not null, primary key +# node_id :integer not null +# version :integer not null, primary key +# sequence_id :integer not null, primary key +# +# Indexes +# +# way_nodes_node_idx (node_id) +# +# Foreign Keys +# +# way_nodes_id_fkey (way_id => ways.way_id) +# + class OldWayNode < ActiveRecord::Base self.table_name = "way_nodes" self.primary_keys = "way_id", "version", "sequence_id" diff --git a/app/models/old_way_tag.rb b/app/models/old_way_tag.rb index 69bd2b186..8fffebc25 100644 --- a/app/models/old_way_tag.rb +++ b/app/models/old_way_tag.rb @@ -1,3 +1,17 @@ +# == Schema Information +# +# Table name: way_tags +# +# way_id :integer default(0), not null, primary key +# k :string not null, primary key +# v :string not null +# version :integer not null, primary key +# +# Foreign Keys +# +# way_tags_id_fkey (way_id => ways.way_id) +# + class OldWayTag < ActiveRecord::Base self.table_name = "way_tags" self.primary_keys = "way_id", "version", "k" diff --git a/app/models/redaction.rb b/app/models/redaction.rb index 04f002e36..b835864db 100644 --- a/app/models/redaction.rb +++ b/app/models/redaction.rb @@ -1,3 +1,20 @@ +# == Schema Information +# +# Table name: redactions +# +# id :integer not null, primary key +# title :string +# description :text +# created_at :datetime +# updated_at :datetime +# user_id :integer not null +# description_format :enum default("markdown"), not null +# +# Foreign Keys +# +# redactions_user_id_fkey (user_id => users.id) +# + ## # Redaction represents a record associated with a particular # action on the database to hide revisions from the history diff --git a/app/models/relation.rb b/app/models/relation.rb index d2490dbae..157794cd6 100644 --- a/app/models/relation.rb +++ b/app/models/relation.rb @@ -1,3 +1,22 @@ +# == Schema Information +# +# Table name: current_relations +# +# id :integer not null, primary key +# changeset_id :integer not null +# timestamp :datetime not null +# visible :boolean not null +# version :integer not null +# +# Indexes +# +# current_relations_timestamp_idx (timestamp) +# +# Foreign Keys +# +# current_relations_changeset_id_fkey (changeset_id => changesets.id) +# + class Relation < ActiveRecord::Base require "xml/libxml" @@ -60,7 +79,7 @@ class Relation < ActiveRecord::Base relation.id = pt["id"].to_i # .to_i will return 0 if there is no number that can be parsed. # We want to make sure that there is no id with zero anyway - raise OSM::APIBadUserInput.new("ID of relation cannot be zero when updating.") if relation.id.zero? + raise OSM::APIBadUserInput, "ID of relation cannot be zero when updating." if relation.id.zero? end # We don't care about the timestamp nor the visibility as these are either @@ -92,7 +111,7 @@ class Relation < ActiveRecord::Base member["role"] ||= "" # Allow the upload to not include this, in which case we default to an empty string. relation.add_member(member["type"].classify, member["ref"], member["role"]) end - raise OSM::APIBadUserInput.new("Some bad xml in relation") if relation.nil? + raise OSM::APIBadUserInput, "Some bad xml in relation" if relation.nil? relation end @@ -103,25 +122,13 @@ class Relation < ActiveRecord::Base doc end - def to_xml_node(visible_members = nil, changeset_cache = {}, user_display_name_cache = {}) + def to_xml_node(changeset_cache = {}, user_display_name_cache = {}) el = XML::Node.new "relation" el["id"] = id.to_s add_metadata_to_xml_node(el, self, changeset_cache, user_display_name_cache) relation_members.each do |member| - p = 0 - - if visible_members - # if there is a list of visible members then use that to weed out deleted segments - p = 1 if visible_members[member.member_type][member.member_id] - else - # otherwise, manually go to the db to check things - p = 1 if member.member.visible? - end - - next unless p - member_el = XML::Node.new "member" member_el["type"] = member.member_type.downcase member_el["ref"] = member.member_id.to_s @@ -155,7 +162,7 @@ class Relation < ActiveRecord::Base end def add_tag_keyval(k, v) - @tags = {} unless @tags + @tags ||= {} # duplicate tags are now forbidden, so we can't allow values # in the hash to be overwritten. @@ -187,7 +194,7 @@ class Relation < ActiveRecord::Base check_consistency(self, new_relation, user) # This will check to see if this relation is used by another relation rel = RelationMember.joins(:relation).find_by("visible = ? AND member_type = 'Relation' and member_id = ? ", true, id) - raise OSM::APIPreconditionFailedError.new("The relation #{new_relation.id} is used in relation #{rel.relation.id}.") unless rel.nil? + raise OSM::APIPreconditionFailedError, "The relation #{new_relation.id} is used in relation #{rel.relation.id}." unless rel.nil? self.changeset_id = new_relation.changeset_id self.tags = {} @@ -202,7 +209,7 @@ class Relation < ActiveRecord::Base lock! check_consistency(self, new_relation, user) unless new_relation.preconditions_ok?(members) - raise OSM::APIPreconditionFailedError.new("Cannot update relation #{id}: data or member data is invalid.") + raise OSM::APIPreconditionFailedError, "Cannot update relation #{id}: data or member data is invalid." end self.changeset_id = new_relation.changeset_id self.changeset = new_relation.changeset @@ -216,7 +223,7 @@ class Relation < ActiveRecord::Base def create_with_history(user) check_create_consistency(self, user) unless preconditions_ok? - raise OSM::APIPreconditionFailedError.new("Cannot create relation: data or member data is invalid.") + raise OSM::APIPreconditionFailedError, "Cannot create relation: data or member data is invalid." end self.version = 0 self.visible = true @@ -253,7 +260,7 @@ class Relation < ActiveRecord::Base # and check that it is OK to use. unless element && element.visible? && element.preconditions_ok? - raise OSM::APIPreconditionFailedError.new("Relation with id #{id} cannot be saved due to #{m[0]} with id #{m[1]}") + raise OSM::APIPreconditionFailedError, "Relation with id #{id} cannot be saved due to #{m[0]} with id #{m[1]}" end hash[m[1]] = true end @@ -270,7 +277,7 @@ class Relation < ActiveRecord::Base old_id = id.to_i if old_id < 0 new_id = id_map[type.downcase.to_sym][old_id] - raise OSM::APIBadUserInput.new("Placeholder #{type} not found for reference #{old_id} in relation #{self.id.nil? ? placeholder_id : self.id}.") if new_id.nil? + raise OSM::APIBadUserInput, "Placeholder #{type} not found for reference #{old_id} in relation #{self.id.nil? ? placeholder_id : self.id}." if new_id.nil? [type, new_id, role] else [type, id, role] diff --git a/app/models/relation_member.rb b/app/models/relation_member.rb index e5c783f5c..3e5cdfca2 100644 --- a/app/models/relation_member.rb +++ b/app/models/relation_member.rb @@ -1,3 +1,22 @@ +# == Schema Information +# +# Table name: current_relation_members +# +# relation_id :integer not null, primary key +# member_type :enum not null +# member_id :integer not null +# member_role :string not null +# sequence_id :integer default(0), not null, primary key +# +# Indexes +# +# current_relation_members_member_idx (member_type,member_id) +# +# Foreign Keys +# +# current_relation_members_id_fkey (relation_id => current_relations.id) +# + class RelationMember < ActiveRecord::Base self.table_name = "current_relation_members" self.primary_keys = "relation_id", "sequence_id" diff --git a/app/models/relation_tag.rb b/app/models/relation_tag.rb index 382606795..5dc609987 100644 --- a/app/models/relation_tag.rb +++ b/app/models/relation_tag.rb @@ -1,3 +1,16 @@ +# == Schema Information +# +# Table name: current_relation_tags +# +# relation_id :integer not null, primary key +# k :string default(""), not null, primary key +# v :string default(""), not null +# +# Foreign Keys +# +# current_relation_tags_id_fkey (relation_id => current_relations.id) +# + class RelationTag < ActiveRecord::Base self.table_name = "current_relation_tags" self.primary_keys = "relation_id", "k" diff --git a/app/models/request_token.rb b/app/models/request_token.rb index c0f019486..335a735bc 100644 --- a/app/models/request_token.rb +++ b/app/models/request_token.rb @@ -1,3 +1,40 @@ +# == Schema Information +# +# Table name: oauth_tokens +# +# id :integer not null, primary key +# user_id :integer +# type :string(20) +# client_application_id :integer +# token :string(50) +# secret :string(50) +# authorized_at :datetime +# invalidated_at :datetime +# created_at :datetime +# updated_at :datetime +# allow_read_prefs :boolean default(FALSE), not null +# allow_write_prefs :boolean default(FALSE), not null +# allow_write_diary :boolean default(FALSE), not null +# allow_write_api :boolean default(FALSE), not null +# allow_read_gpx :boolean default(FALSE), not null +# allow_write_gpx :boolean default(FALSE), not null +# callback_url :string +# verifier :string(20) +# scope :string +# valid_to :datetime +# allow_write_notes :boolean default(FALSE), not null +# +# Indexes +# +# index_oauth_tokens_on_token (token) UNIQUE +# index_oauth_tokens_on_user_id (user_id) +# +# Foreign Keys +# +# oauth_tokens_client_application_id_fkey (client_application_id => client_applications.id) +# oauth_tokens_user_id_fkey (user_id => users.id) +# + class RequestToken < OauthToken attr_accessor :provided_oauth_verifier diff --git a/app/models/trace.rb b/app/models/trace.rb index eed09dbe5..214b0b647 100644 --- a/app/models/trace.rb +++ b/app/models/trace.rb @@ -1,3 +1,30 @@ +# == Schema Information +# +# Table name: gpx_files +# +# id :integer not null, primary key +# user_id :integer not null +# visible :boolean default(TRUE), not null +# name :string default(""), not null +# size :integer +# latitude :float +# longitude :float +# timestamp :datetime not null +# description :string default(""), not null +# inserted :boolean not null +# visibility :enum default("public"), not null +# +# Indexes +# +# gpx_files_timestamp_idx (timestamp) +# gpx_files_user_id_idx (user_id) +# gpx_files_visible_visibility_idx (visible,visibility) +# +# Foreign Keys +# +# gpx_files_user_id_fkey (user_id => users.id) +# + class Trace < ActiveRecord::Base self.table_name = "gpx_files" @@ -172,13 +199,12 @@ class Trace < ActiveRecord::Base el1 end - # Read in xml as text and return it's Node object representation - def self.from_xml(xml, create = false) + def update_from_xml(xml, create = false) p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR) doc = p.parse doc.find("//osm/gpx_file").each do |pt| - return Trace.from_xml_node(pt, create) + return update_from_xml_node(pt, create) end raise OSM::APIBadXMLError.new("trace", xml, "XML doesn't contain an osm/gpx_file element.") @@ -186,34 +212,31 @@ class Trace < ActiveRecord::Base raise OSM::APIBadXMLError.new("trace", xml, ex.message) end - def self.from_xml_node(pt, create = false) - trace = Trace.new - + def update_from_xml_node(pt, create = false) raise OSM::APIBadXMLError.new("trace", pt, "visibility missing") if pt["visibility"].nil? - trace.visibility = pt["visibility"] + self.visibility = pt["visibility"] unless create raise OSM::APIBadXMLError.new("trace", pt, "ID is required when updating.") if pt["id"].nil? - trace.id = pt["id"].to_i + id = pt["id"].to_i # .to_i will return 0 if there is no number that can be parsed. # We want to make sure that there is no id with zero anyway - raise OSM::APIBadUserInput.new("ID of trace cannot be zero when updating.") if trace.id.zero? + raise OSM::APIBadUserInput, "ID of trace cannot be zero when updating." if id.zero? + raise OSM::APIBadUserInput, "The id in the url (#{self.id}) is not the same as provided in the xml (#{id})" unless self.id == id end # We don't care about the time, as it is explicitly set on create/update/delete # We don't care about the visibility as it is implicit based on the action # and set manually before the actual delete - trace.visible = true + self.visible = true description = pt.find("description").first raise OSM::APIBadXMLError.new("trace", pt, "description missing") if description.nil? - trace.description = description.content + self.description = description.content - pt.find("tag").each do |tag| - trace.tags.build(:tag => tag.content) + self.tags = pt.find("tag").collect do |tag| + Tracetag.new(:tag => tag.content) end - - trace end def xml_file diff --git a/app/models/tracepoint.rb b/app/models/tracepoint.rb index 9485b8a14..445688c55 100644 --- a/app/models/tracepoint.rb +++ b/app/models/tracepoint.rb @@ -1,3 +1,25 @@ +# == Schema Information +# +# Table name: gps_points +# +# altitude :float +# trackid :integer not null +# latitude :integer not null +# longitude :integer not null +# gpx_id :integer not null +# timestamp :datetime +# tile :integer +# +# Indexes +# +# points_gpxid_idx (gpx_id) +# points_tile_idx (tile) +# +# Foreign Keys +# +# gps_points_gpx_id_fkey (gpx_id => gpx_files.id) +# + class Tracepoint < ActiveRecord::Base include GeoRecord diff --git a/app/models/tracetag.rb b/app/models/tracetag.rb index 9d2195920..1a4fbd398 100644 --- a/app/models/tracetag.rb +++ b/app/models/tracetag.rb @@ -1,3 +1,21 @@ +# == Schema Information +# +# Table name: gpx_file_tags +# +# gpx_id :integer default(0), not null +# tag :string not null +# id :integer not null, primary key +# +# Indexes +# +# gpx_file_tags_gpxid_idx (gpx_id) +# gpx_file_tags_tag_idx (tag) +# +# Foreign Keys +# +# gpx_file_tags_gpx_id_fkey (gpx_id => gpx_files.id) +# + class Tracetag < ActiveRecord::Base self.table_name = "gpx_file_tags" diff --git a/app/models/user.rb b/app/models/user.rb index 63c9527c7..678bbad9d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,3 +1,48 @@ +# == Schema Information +# +# Table name: users +# +# email :string not null +# id :integer not null, primary key +# pass_crypt :string not null +# creation_time :datetime not null +# display_name :string default(""), not null +# data_public :boolean default(FALSE), not null +# description :text default(""), not null +# home_lat :float +# home_lon :float +# home_zoom :integer default(3) +# nearby :integer default(50) +# pass_salt :string +# image_file_name :text +# email_valid :boolean default(FALSE), not null +# new_email :string +# creation_ip :string +# languages :string +# status :enum default("pending"), not null +# terms_agreed :datetime +# consider_pd :boolean default(FALSE), not null +# auth_uid :string +# preferred_editor :string +# terms_seen :boolean default(FALSE), not null +# description_format :enum default("markdown"), not null +# image_fingerprint :string +# changesets_count :integer default(0), not null +# traces_count :integer default(0), not null +# diary_entries_count :integer default(0), not null +# image_use_gravatar :boolean default(FALSE), not null +# image_content_type :string +# auth_provider :string +# +# Indexes +# +# users_auth_idx (auth_provider,auth_uid) UNIQUE +# users_display_name_idx (display_name) UNIQUE +# users_display_name_lower_idx (lower((display_name)::text)) +# users_email_idx (email) UNIQUE +# users_email_lower_idx (lower((email)::text)) +# + class User < ActiveRecord::Base require "xml/libxml" diff --git a/app/models/user_block.rb b/app/models/user_block.rb index eb0daba65..4f9cf1128 100644 --- a/app/models/user_block.rb +++ b/app/models/user_block.rb @@ -1,3 +1,29 @@ +# == Schema Information +# +# Table name: user_blocks +# +# id :integer not null, primary key +# user_id :integer not null +# creator_id :integer not null +# reason :text not null +# ends_at :datetime not null +# needs_view :boolean default(FALSE), not null +# revoker_id :integer +# created_at :datetime +# updated_at :datetime +# reason_format :enum default("markdown"), not null +# +# Indexes +# +# index_user_blocks_on_user_id (user_id) +# +# Foreign Keys +# +# user_blocks_moderator_id_fkey (creator_id => users.id) +# user_blocks_revoker_id_fkey (revoker_id => users.id) +# user_blocks_user_id_fkey (user_id => users.id) +# + class UserBlock < ActiveRecord::Base validate :moderator_permissions diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb index 7c65a5899..69b0e9dde 100644 --- a/app/models/user_preference.rb +++ b/app/models/user_preference.rb @@ -1,3 +1,16 @@ +# == Schema Information +# +# Table name: user_preferences +# +# user_id :integer not null, primary key +# k :string not null, primary key +# v :string not null +# +# Foreign Keys +# +# user_preferences_user_id_fkey (user_id => users.id) +# + class UserPreference < ActiveRecord::Base self.primary_keys = "user_id", "k" diff --git a/app/models/user_role.rb b/app/models/user_role.rb index 967850145..adf569a03 100644 --- a/app/models/user_role.rb +++ b/app/models/user_role.rb @@ -1,3 +1,24 @@ +# == Schema Information +# +# Table name: user_roles +# +# id :integer not null, primary key +# user_id :integer not null +# role :enum not null +# created_at :datetime +# updated_at :datetime +# granter_id :integer not null +# +# Indexes +# +# user_roles_id_role_unique (user_id,role) UNIQUE +# +# Foreign Keys +# +# user_roles_granter_id_fkey (granter_id => users.id) +# user_roles_user_id_fkey (user_id => users.id) +# + class UserRole < ActiveRecord::Base belongs_to :user belongs_to :granter, :class_name => "User" diff --git a/app/models/user_token.rb b/app/models/user_token.rb index faa540e67..0d1e16e8a 100644 --- a/app/models/user_token.rb +++ b/app/models/user_token.rb @@ -1,3 +1,23 @@ +# == Schema Information +# +# Table name: user_tokens +# +# id :integer not null, primary key +# user_id :integer not null +# token :string not null +# expiry :datetime not null +# referer :text +# +# Indexes +# +# user_tokens_token_idx (token) UNIQUE +# user_tokens_user_id_idx (user_id) +# +# Foreign Keys +# +# user_tokens_user_id_fkey (user_id => users.id) +# + class UserToken < ActiveRecord::Base belongs_to :user diff --git a/app/models/way.rb b/app/models/way.rb index 9586094ff..1954f744c 100644 --- a/app/models/way.rb +++ b/app/models/way.rb @@ -1,3 +1,22 @@ +# == Schema Information +# +# Table name: current_ways +# +# id :integer not null, primary key +# changeset_id :integer not null +# timestamp :datetime not null +# visible :boolean not null +# version :integer not null +# +# Indexes +# +# current_ways_timestamp_idx (timestamp) +# +# Foreign Keys +# +# current_ways_changeset_id_fkey (changeset_id => changesets.id) +# + class Way < ActiveRecord::Base require "xml/libxml" @@ -58,7 +77,7 @@ class Way < ActiveRecord::Base way.id = pt["id"].to_i # .to_i will return 0 if there is no number that can be parsed. # We want to make sure that there is no id with zero anyway - raise OSM::APIBadUserInput.new("ID of way cannot be zero when updating.") if way.id.zero? + raise OSM::APIBadUserInput, "ID of way cannot be zero when updating." if way.id.zero? end # We don't care about the timestamp nor the visibility as these are either @@ -138,12 +157,12 @@ class Way < ActiveRecord::Base attr_writer :tags def add_nd_num(n) - @nds = [] unless @nds + @nds ||= [] @nds << n.to_i end def add_tag_keyval(k, v) - @tags = {} unless @tags + @tags ||= {} # duplicate tags are now forbidden, so we can't allow values # in the hash to be overwritten. @@ -166,7 +185,7 @@ class Way < ActiveRecord::Base lock! check_consistency(self, new_way, user) unless new_way.preconditions_ok?(nds) - raise OSM::APIPreconditionFailedError.new("Cannot update way #{id}: data is invalid.") + raise OSM::APIPreconditionFailedError, "Cannot update way #{id}: data is invalid." end self.changeset_id = new_way.changeset_id @@ -181,7 +200,7 @@ class Way < ActiveRecord::Base def create_with_history(user) check_create_consistency(self, user) unless preconditions_ok? - raise OSM::APIPreconditionFailedError.new("Cannot create way: data is invalid.") + raise OSM::APIPreconditionFailedError, "Cannot create way: data is invalid." end self.version = 0 self.visible = true @@ -205,7 +224,7 @@ class Way < ActiveRecord::Base if db_nds.length < new_nds.length missing = new_nds - db_nds.collect(&:id) - raise OSM::APIPreconditionFailedError.new("Way #{id} requires the nodes with id in (#{missing.join(',')}), which either do not exist, or are not visible.") + raise OSM::APIPreconditionFailedError, "Way #{id} requires the nodes with id in (#{missing.join(',')}), which either do not exist, or are not visible." end end @@ -222,7 +241,7 @@ class Way < ActiveRecord::Base lock! check_consistency(self, new_way, user) rels = Relation.joins(:relation_members).where(:visible => true, :current_relation_members => { :member_type => "Way", :member_id => id }).order(:id) - raise OSM::APIPreconditionFailedError.new("Way #{id} is still used by relations #{rels.collect(&:id).join(',')}.") unless rels.empty? + raise OSM::APIPreconditionFailedError, "Way #{id} is still used by relations #{rels.collect(&:id).join(',')}." unless rels.empty? self.changeset_id = new_way.changeset_id self.changeset = new_way.changeset @@ -242,7 +261,7 @@ class Way < ActiveRecord::Base nds.map! do |node_id| if node_id < 0 new_id = id_map[:node][node_id] - raise OSM::APIBadUserInput.new("Placeholder node not found for reference #{node_id} in way #{id.nil? ? placeholder_id : id}") if new_id.nil? + raise OSM::APIBadUserInput, "Placeholder node not found for reference #{node_id} in way #{id.nil? ? placeholder_id : id}" if new_id.nil? new_id else node_id diff --git a/app/models/way_node.rb b/app/models/way_node.rb index 30d901356..5c09cd740 100644 --- a/app/models/way_node.rb +++ b/app/models/way_node.rb @@ -1,3 +1,21 @@ +# == Schema Information +# +# Table name: current_way_nodes +# +# way_id :integer not null, primary key +# node_id :integer not null +# sequence_id :integer not null, primary key +# +# Indexes +# +# current_way_nodes_node_idx (node_id) +# +# Foreign Keys +# +# current_way_nodes_id_fkey (way_id => current_ways.id) +# current_way_nodes_node_id_fkey (node_id => current_nodes.id) +# + class WayNode < ActiveRecord::Base self.table_name = "current_way_nodes" self.primary_keys = "way_id", "sequence_id" diff --git a/app/models/way_tag.rb b/app/models/way_tag.rb index 99d435d33..8ef75f38e 100644 --- a/app/models/way_tag.rb +++ b/app/models/way_tag.rb @@ -1,3 +1,16 @@ +# == Schema Information +# +# Table name: current_way_tags +# +# way_id :integer not null, primary key +# k :string default(""), not null, primary key +# v :string default(""), not null +# +# Foreign Keys +# +# current_way_tags_id_fkey (way_id => current_ways.id) +# + class WayTag < ActiveRecord::Base self.table_name = "current_way_tags" self.primary_keys = "way_id", "k" diff --git a/app/views/changeset/list.atom.builder b/app/views/changeset/list.atom.builder index ace586ae5..a3b7a2240 100644 --- a/app/views/changeset/list.atom.builder +++ b/app/views/changeset/list.atom.builder @@ -62,7 +62,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])} = #{auto_link(h(tag[1]))}" + tr.td << "#{h(tag[0])} = #{linkify(h(tag[1]))}" end end end diff --git a/app/views/diary_entry/list.html.erb b/app/views/diary_entry/list.html.erb index 756464aa2..d6af432fb 100644 --- a/app/views/diary_entry/list.html.erb +++ b/app/views/diary_entry/list.html.erb @@ -34,19 +34,21 @@ <%= render :partial => 'diary_list_entry', :collection => @entries %> <% end %> - <% if @entries.size < @page_size -%> - <%= t('diary_entry.list.older_entries') %> - <% else -%> - <%= link_to t('diary_entry.list.older_entries'), @params.merge(:page => @page + 1 ) %> - <% end -%> - - | - - <% if @page > 1 -%> - <%= link_to t('diary_entry.list.newer_entries'), @params.merge(:page => @page - 1) %> - <% else -%> - <%= t('diary_entry.list.newer_entries') %> - <% end -%> + <% end %> <% unless params[:friends] or params[:nearby] -%> diff --git a/app/views/layouts/_head.html.erb b/app/views/layouts/_head.html.erb index 377d55e9d..bf9f78b43 100644 --- a/app/views/layouts/_head.html.erb +++ b/app/views/layouts/_head.html.erb @@ -7,7 +7,6 @@ <%= stylesheet_link_tag "print-#{dir}", :media => "print" %> <%= stylesheet_link_tag "leaflet-all", :media => "screen, print" %> <% [57, 60, 72, 76, 114, 120, 144, 152, 180].each do |size| -%> @@ -18,7 +17,7 @@ <%= favicon_link_tag "favicon-96x96.png", :rel => "icon", :sizes => "96x96", :type => "image/png" %> <%= favicon_link_tag "android-chrome-192x192.png", :rel => "icon", :sizes => "192x192", :type => "image/png" %> <%= favicon_link_tag "favicon-16x16.png", :rel => "icon", :sizes => "16x16", :type => "image/png" %> - <%= tag("link", { :rel => "mask-icon", :href => asset_path("tag-icon.svg"), :color => "#7ebc6f" }) %> + <%= tag("link", { :rel => "mask-icon", :href => asset_path("tab-icon.svg"), :color => "#7ebc6f" }) %> <%= tag("link", { :rel => "manifest", :href => asset_path("manifest.json") }) %> <%= tag("meta", { :name => "msapplication-config", :content => asset_path("browserconfig.xml") }) %> <%= tag("meta", { :name => "msapplication-TileColor", :content => "#00a300" }) %> @@ -33,10 +32,10 @@ <%= opengraph_tags(@title) %> <% if flash[:piwik_goal] -%> <%= tag("meta", :name => "piwik-goal", :content => flash[:piwik_goal]) %> - <% end -%> + <% end -%> <%= style_rules %> <%= yield :head %> <%= yield :auto_discovery_link_tag %> <%= csrf_meta_tag %> - <%= t 'layouts.project_name.title' %><%= ' | ' + @title if @title %> + <%= @title + ' | ' if @title %><%= t 'layouts.project_name.title' %> <% end %> diff --git a/app/views/user/account.html.erb b/app/views/user/account.html.erb index 752d1cd01..169e5662a 100644 --- a/app/views/user/account.html.erb +++ b/app/views/user/account.html.erb @@ -11,7 +11,7 @@ <% end %> <%= error_messages_for current_user %> -<%= form_for current_user, :url => { :action => :account }, :html => { :multipart => true, :id => 'accountForm', :class => 'standard-form', :autocomplete => :off } do |f| %> +<%= form_for current_user, :url => { :action => :account }, :method => :post, :html => { :multipart => true, :id => 'accountForm', :class => 'standard-form', :autocomplete => :off } do |f| %>
@@ -123,7 +123,7 @@ <%= t 'user.account.replace image' %> <%= t 'user.account.image size hint' %> - <%= f.file_field :image, :onchange => "$('#image_action_new').prop('checked', true)" %> + <%= f.file_field :image %> <% else %>
  • @@ -132,7 +132,7 @@ <%= t 'user.account.new image' %> <%= t 'user.account.image size hint' %> - <%= f.file_field :image, :onchange => "$('#image_action_new').prop('checked', true)" %> + <%= f.file_field :image %>
  • <% end %>
  • diff --git a/app/views/user/reset_password.html.erb b/app/views/user/reset_password.html.erb index 4cb94374a..895bd98b6 100644 --- a/app/views/user/reset_password.html.erb +++ b/app/views/user/reset_password.html.erb @@ -2,7 +2,7 @@

    <%= t 'user.reset_password.heading', :user => current_user.display_name %>

    <% end %> -<%= error_messages_for :user %> +<%= error_messages_for current_user %> <%= form_tag do %> <%= hidden_field_tag(:token, params[:token]) %> diff --git a/app/views/user/save.html.erb b/app/views/user/save.html.erb deleted file mode 100644 index 7134a167f..000000000 --- a/app/views/user/save.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= current_user.email %> diff --git a/config/banners.yml b/config/banners.yml index 7bdf169bf..ce53c3f02 100644 --- a/config/banners.yml +++ b/config/banners.yml @@ -1,6 +1,18 @@ -sotm2017: - id: sotm2017 - alt: State of the Map 2017 - link: http://2017.stateofthemap.org/ - img: banners/banner-sotm-2017.png - enddate: 2017-aug-27 +sotmasia2017: + id: sotmasia2017 + alt: State of the Map Asia 2017 + link: http://stateofthemap.asia/ + img: banners/sotmasia-2017-banner.png + enddate: 2017-sep-25 +sotmus2017: + id: sotmus2017 + alt: State of the Map US 2017 + link: https://2017.stateofthemap.us/ + img: banners/banner-sotmus2017.png + enddate: 2017-oct-20 +osmfmembership2017: + id: osmfmembership2017 + alt: Join the OpenStreetMap Foundation + link: https://blog.openstreetmap.org/2017/09/25/join-the-openstreetmap-foundation-now-and-help-shape-the-future-of-the-project/ + img: banners/osmf-membership-drive-2017.png + enddate: 2017-nov-11 diff --git a/config/environment.rb b/config/environment.rb index 171198560..cac531577 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,5 +1,5 @@ # Load the Rails application. -require File.expand_path("../application", __FILE__) +require_relative "application" # Initialize the Rails application. Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb index 9101bb1eb..8e7213a9d 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -12,6 +12,20 @@ Rails.application.configure do # Show full error reports. config.consider_all_requests_local = true + # Enable/disable caching. By default caching is disabled. + if Rails.root.join("tmp", "caching-dev.txt").exist? + config.action_controller.perform_caching = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + "Cache-Control" => "public, max-age=#{2.days.seconds.to_i}" + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false diff --git a/config/environments/production.rb b/config/environments/production.rb index e421abc58..c4c98ad48 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -14,6 +14,11 @@ Rails.application.configure do config.consider_all_requests_local = false config.action_controller.perform_caching = true + # Attempt to read encrypted secrets from `config/secrets.yml.enc`. + # Requires an encryption key in `ENV["RAILS_MASTER_KEY"]` or + # `config/secrets.yml.key`. + config.read_encrypted_secrets = true + # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? @@ -57,7 +62,7 @@ Rails.application.configure do # Use a real queuing backend for Active Job (and separate queues per environment) # config.active_job.queue_adapter = :resque - # config.active_job.queue_name_prefix = "rails50_#{Rails.env}" + # config.active_job.queue_name_prefix = "openstreetmap_#{Rails.env}" config.action_mailer.perform_caching = false # Configure caching of static assets diff --git a/config/initializers/banners.rb b/config/initializers/banners.rb index 5c83c045d..8eda290c5 100644 --- a/config/initializers/banners.rb +++ b/config/initializers/banners.rb @@ -1,5 +1,5 @@ begin BANNERS = YAML.load_file(Rails.root.join("config", "banners.yml")).deep_symbolize_keys -rescue +rescue StandardError BANNERS = {}.freeze end diff --git a/config/initializers/secure_headers.rb b/config/initializers/secure_headers.rb index 59fe4225d..f30a4b86c 100644 --- a/config/initializers/secure_headers.rb +++ b/config/initializers/secure_headers.rb @@ -1,5 +1,5 @@ if defined?(CSP_REPORT_URL) - policy = { + csp_policy = { :default_src => %w['self'], :child_src => %w['self'], :connect_src => %w['self'], @@ -9,19 +9,26 @@ if defined?(CSP_REPORT_URL) :img_src => %w['self' data: www.gravatar.com *.wp.com *.tile.openstreetmap.org *.tile.thunderforest.com *.openstreetmap.fr], :media_src => %w['none'], :object_src => %w['self'], - :plugin_types => %w['none'], + :plugin_types => %w[], :script_src => %w['self'], :style_src => %w['self' 'unsafe-inline'], :report_uri => [CSP_REPORT_URL] } - policy[:script_src] << PIWIK["location"] if defined?(PIWIK) + csp_policy[:img_src] << PIWIK["location"] if defined?(PIWIK) + csp_policy[:script_src] << PIWIK["location"] if defined?(PIWIK) else - policy = SecureHeaders::OPT_OUT + csp_policy = SecureHeaders::OPT_OUT end +cookie_policy = { + :secure => SecureHeaders::OPT_OUT, + :httponly => SecureHeaders::OPT_OUT +} + SecureHeaders::Configuration.default do |config| config.hsts = "max-age=0" config.csp = SecureHeaders::OPT_OUT - config.csp_report_only = policy + config.csp_report_only = csp_policy + config.cookies = cookie_policy end diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index 0f9e89970..8a0fd8f03 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -2,6 +2,8 @@ if defined?(MEMCACHE_SERVERS) Rails.application.config.session_store :mem_cache_store, :memcache_server => MEMCACHE_SERVERS, :namespace => "rails:session", :key => "_osm_session" -else +elsif Rails.application.config.cache_store != :null_store Rails.application.config.session_store :cache_store, :key => "_osm_session" +else + Rails.application.config.session_store :cookie_store, :key => "_osm_session" end diff --git a/config/initializers/streaming.rb b/config/initializers/streaming.rb deleted file mode 100644 index 0c27ba2e7..000000000 --- a/config/initializers/streaming.rb +++ /dev/null @@ -1,23 +0,0 @@ -# Hack ActionController::DataStreaming to allow streaming from a file handle -module ActionController - module DataStreaming - alias old_send_file send_file - - def send_file(file, options = {}) - if file.is_a?(File) || file.is_a?(Tempfile) - headers["Content-Length"] ||= file.size.to_s - - options[:filename] ||= File.basename(file.path) unless options[:url_based_filename] - send_file_headers! options - - self.status = options[:status] || 200 - self.content_type = options[:content_type] if options.key?(:content_type) - self.response_body = file - else - headers["Content-Length"] ||= File.size(file).to_s - - old_send_file(file, options) - end - end - end -end diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb index 33725e95f..cf733efd1 100644 --- a/config/initializers/wrap_parameters.rb +++ b/config/initializers/wrap_parameters.rb @@ -5,7 +5,7 @@ # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. ActiveSupport.on_load(:action_controller) do - wrap_parameters format: [:json] if respond_to?(:wrap_parameters) + wrap_parameters format: [:json] end # To enable root element in JSON for ActiveRecord objects. diff --git a/config/locales/af.yml b/config/locales/af.yml index e66a0cdf8..c0989fcfc 100644 --- a/config/locales/af.yml +++ b/config/locales/af.yml @@ -2,6 +2,7 @@ # Exported from translatewiki.net # Export driver: phpyaml # Author: Arnobarnard +# Author: Biggs ZA # Author: Firefishy # Author: Fwolff # Author: Naudefj @@ -15,20 +16,37 @@ af: models: acl: Toegangsbeheerlys changeset: Wysigingstel + changeset_tag: Wysigingstel-merker country: Land diary_comment: Dagboekopmerking diary_entry: Dagboekinskrywing friend: Vriend language: Taal message: Boodskap - node: Node + node: Knooppunt + node_tag: Knooppuntmerker notifier: Kennisgewer - old_node: Ou Node + old_node: Ou Knooppunt + old_node_tag: Ou knooppuntmerker + old_relation: Ou Verband + old_relation_member: Ou Verbandslid + old_relation_tag: Ou Verbandsmerker + old_way: Ou pad + old_way_node: Ou weg-knooppunt + old_way_tag: Ou weg-merker + relation: Verband + relation_member: Verbandslid + relation_tag: Verbandsmerker session: Sessie trace: Spoor + tracepoint: Natrekpunt + tracetag: Natrekmerker user: Gebruiker user_preference: Gebruikersvoorkeure + user_token: Gebruikerskoepon way: Weg + way_node: Weg-knooppunt + way_tag: Weg-merker attributes: diary_comment: body: Teks @@ -48,57 +66,147 @@ af: size: Grootte latitude: Breedtegraad longitude: Lengtegraad - public: Openbaar + public: Publiek description: Beskrywing message: - sender: Afsender + sender: Sender title: Onderwerp body: Teks recipient: Ontvanger user: email: E-pos - active: Aktief - display_name: Vertoon Naam + active: Bedrywig + display_name: Skermnaam description: Beskrywing languages: Tale pass_crypt: Wagwoord editor: + default: Verstek (tans %{name}) + potlatch: + name: Potknip 1 + description: Potknip 1 (aanlynredigeerder) id: name: iD + description: iD (aanlynredigeerder) + potlatch2: + name: Potknip 2 + description: Potknip 2 (aanlynredigeerder) + remote: + name: Afstandsbeheer + description: Afstandsbeheer (JOSM of Merkaartor) browse: + created: Geskep + closed: Gesluit + created_html: Geskep %{time} gelede + closed_html: Geslote %{time} gelede + created_by_html: Geskep %{time} gelede deur %{user} + deleted_by_html: Geskrap %{time} gelede deur %{user} + edited_by_html: Geredigeer %{time} gelede deur %{user} + closed_by_html: Gesluit %{time} gelede deur %{user} version: Weergawe + in_changeset: Wysigingsstel + anonymous: anoniem + no_comment: (geen kommentaar) + part_of: Deel van download_xml: Laai XML af - view_history: Sien geskiedenis - view_details: Sien detail + view_history: Beskou Geskiedenis + view_details: Bekyk Detail location: 'Ligging:' changeset: + title: 'Wysigingsstel: %{id}' + belongs_to: Skrywer + node: Knooppunte (%{count}) + node_paginated: Knooppunte (%{x}-%{y} van %{count}) + way: Weë (%{count}) + way_paginated: Weë (%{x}-%{y} van %{count}) + relation: Verwantskappe (%{count}) + relation_paginated: Verwantskappe (%{x}-%{y} of %{count}) + comment: Kommentaar (%{count}) + hidden_commented_by: Verskuilde kommentaar deur %{user} %{when} + ago + commented_by: Kommentaar deur %{user} %{when} ago + changesetxml: Wysigingsstel XML + osmchangexml: osmWysiging XML + feed: + title: Wysigingsstel %{id} + title_comment: Wysigingstel %{id} - %{comment} + join_discussion: Meld aan en gesels saam discussion: Bespreking + node: + title: 'Knooppunt: %{name}' + history_title: 'Knooppuntgeskiedenis: %{name}' + way: + title: 'Weg: %{name}' + history_title: 'Weggeskiedenis: %{name}' + nodes: Knooppunte + also_part_of: + one: gedeelte van weg %{related_ways} + other: gedeelte van weë %{related_ways} + relation: + title: 'Verwantskap: %{name}' + history_title: 'Verwantskapgeskiedenis: %{name}' + members: Lede relation_member: entry_role: '%{type} %{name} as %{role}' type: - node: Node + node: Knooppunt way: Weg relation: Verwantskap containing_relation: entry: Verwantskap %{relation_name} entry_role: Verwantskap %{relation_name} (as %{relation_role}) not_found: - sorry: 'Jammer, %{type} #%{id} kan nie gevind word nie.' + sorry: 'Jammer, %{type} #%{id} blyk onverkrygbaar.' type: - node: node + node: knooppunt way: weg relation: verwantskap - changeset: veranderingstel + changeset: wysigingstel + note: nota timeout: - sorry: Jammer, dit het te lank geneem om data vir die %{type} met die id %{id} + sorry: Jammer, die gegewens vir die %{type} met die id %{id} neem te lank om op te soek. type: - node: node + node: knooppunt + way: weg + relation: verband + changeset: wysigingstel + note: nota + redacted: + redaction: Redigering %{id} + message_html: Weergawe %{version} van hierdie %{type} kan nie vertoon word nie, + synde dit geredigeer is. Raadpleeg asseblief %{redaction_link} vir besonderhede. + type: + node: knooppunt + way: weg + relation: verband start_rjs: + feature_warning: Laai tans %{num_features} kenmerke wat u internetblaaier kan + vertraag of laat hang. Is u seker u wil hierdie data vertoon? load_data: Laai data - loading: Laai... + loading: Laai tans… tag_details: - tags: Oortjies + tags: Merkers + wiki_link: + key: Die wiki-beskrywingsblad vir %{key} tag + tag: Die wikibeskrywingsblad vir die %{key}=%{value} merker + wikidata_link: Die %{page} item op Wikidata + wikipedia_link: Die bladsy %{page} op Wikipedia + telephone_link: Skakel %{phone_number} + note: + title: 'Nota: %{id}' + new_note: Nuwe Nota + description: Beskrywing + open_by_anonymous: Anoniem het %{when} ago + geskep + commented_by: Kommentaar deur %{user} %{when} ago + commented_by_anonymous: Kommentaar deur anoniem %{when} + ago + query: + title: Bevraagteken Gidsbakens + introduction: Klik op die kaart om nabye bakens te ontdek. + nearby: Nabye kenmerke + enclosing: Omsluitende kenmerke changeset: changeset_paging_nav: showing_page: Bladsy %{page} @@ -106,26 +214,47 @@ af: previous: « Vorige changeset: anonymous: Anoniem - no_edits: (geen wysigings) + no_edits: (geen redigerings) + view_changeset_details: Bekyk die wysigingsstel se besonderhede changesets: id: ID - saved_at: Gestoor op + saved_at: Gebêre op user: Gebruiker comment: Opmerking area: Gebied + list: + title: Wysigingsstel + empty: Geen wysigingstelle gevind nie. + empty_area: Geen wysigingstelle in hierdie gebied. + empty_user: Geen wysigingstelle deur hierdie gebruiker. + no_more: Geen meer wysigingstelle gevind nie. + no_more_area: Geen wysigingstelle in hierdie gebied nie. + no_more_user: Geen ander wysigingstelle deur hierdie gebruiker nie. + load_more: Laai nog + timeout: + sorry: Jammer, die lys wysigingstelle wat u versoek het, neem lank om uit te + haal. + rss: + title_all: OpenStreetMap bespreking oor wysigingstelle + commented_at_html: '%{when} gelede bygewerk' + commented_at_by_html: '%{when} gelede deur %{user} bygewerk' + full: Volledige bespreking diary_entry: new: title: Nuwe dagboekinskrywing + publish_button: Publiseer list: title: Gebruikersdagboeke - user_title: Dagboek van %{user} + title_friends: Dagboeke van vriende + title_nearby: Gebruikers in die omgewing se dagboeke + user_title: '%{user} se dagboek' in_language_title: Dagboekinkrywings in %{language} new: Nuwe dagboekinskrywing - new_title: Plaas nuwe artikel in u dagboek + new_title: Maak 'n nuwe inskrywing in jou dagboek no_entries: Geen dagboekinskrywings nie recent_entries: Onlangse dagboekinskrywings - older_entries: Ouer inskrywings - newer_entries: Nuwer inskrywings + older_entries: Vorige Inskrywings + newer_entries: Jonger inskrywings edit: title: Wysig dagboekinskrywing subject: 'Onderwerp:' @@ -134,111 +263,139 @@ af: location: 'Ligging:' latitude: 'Breedtegraad:' longitude: 'Lengtegraad:' - use_map_link: gebruik kaart + use_map_link: benut kaart save_button: Stoor marker_text: Ligging van dagboekinskrywing view: title: '%{user} se dagboek | %{title}' - user_title: Dagboek van %{user} - leave_a_comment: Los 'n opmerking - login_to_leave_a_comment: U moet eers %{login_link} alvorens u kommentaar kan - lewer + user_title: '%{user} se dagboek' + leave_a_comment: Lewer kommentaar + login_to_leave_a_comment: '%{login_link} om kommentaar te lewer' login: Meld aan save_button: Stoor no_such_entry: - title: Die opgevraagde dagboekinskrywing bestaan nie - heading: Die inskrywing met id %{id} bestaan nie - 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. + title: Geen só 'n dagboekinskrywing + heading: 'Geen inskrywing met die id: %{id}' + body: Jammer, geen dagboekinskrywing of kommentaar met die id %{id} bestaan + nie. Gaan u spelling na, of u het moontlik op 'n foutiewe skakel geklik. diary_entry: - posted_by: Gepos deur %{link_user} op %{created} in %{language_link} - comment_link: Lewer kommentaar op hierdie bydrae - reply_link: Antwoord op hierdie bydrae + posted_by: Plasing deur %{link_user} op %{created} in %{language_link} + comment_link: Lewer hierop kommentaar + reply_link: Antwoord hierop comment_count: - one: 1 reaksie - other: '%{count} reaksies' - edit_link: Wysig hierdie inskrywing - hide_link: Versteek die inskrywing - confirm: Bevestig + zero: Geen opmerkings + one: '%{count} opmerking' + other: '%{count} opmerkings' + edit_link: Redigeer hierdie inskrywing + hide_link: Steek dié inskrywing weg + confirm: Bekragtig diary_comment: comment_from: Kommentaar van %{link_user} op %{comment_created_at} - hide_link: Versteek die opmerking - confirm: Bevestig + hide_link: Steek die opmerking weg + confirm: Bekragtig location: location: 'Ligging:' view: Wys - edit: Wysig + edit: Redigeer feed: user: - title: OpenStreetMap dagboekinskrywings van %{user} - description: Onlangse OpenStreetMap dagboekinskrywings van %{user} + title: OpenStreetMap-dagboekinskrywings deur %{user} + description: Onlangse OpenStreetMap-dagboekinskrywings deur %{user} language: title: OpenStreetMap dagboekinskrywings in %{language_name} - description: Onlangse dagboekinskrywings van OpenStreetMap-gebruikers in %{language_name} + description: Onlangse dagboekinskrywings deur OpenStreetMap-gebruikers in + %{language_name} all: - title: OpenStreetMap dagboekinskrywings - description: Onlangse dagboekinskrywings van OpenStreetMap-gebruikers + title: OpenStreetMap-dagboekinskrywings + description: Onlangse dagboekinskrywings deur OpenStreetMap-gebruikers comments: + post: Plasing when: Wanneer + comment: Kommentaar + ago: '%{ago} gelede' + newer_comments: Jongste Kommentaar + older_comments: Ouer Kommentaar export: + title: Voer Uit start: - area_to_export: Area om te eksporteer - manually_select: Kies 'n ander gebied handmatig - format_to_export: Lêerformaat + area_to_export: Area om uit te voer + manually_select: Kies self 'n ander area + format_to_export: Formaat om uit te voer osm_xml_data: OpenStreetMap XML-data - embeddable_html: HTML-kode + map_image: Kaartbeeld (wys standaardlaag) + embeddable_html: Versteekbare HTML-kode licence: Lisensie - export_details: OpenStreetMap se data is gelisensieer onder die Creative - Commons Erkenning-Insgelyks Deel 2.0 lisensie. + export_details: OpenStreetMap se data word ingevolge die + (ODbL) gelisensieer. + too_large: + advice: 'Ingeval die uitvoering hierbo misluk, oorweeg asseblief een van die + volgende bronne:' + body: Hierdie gebied is te groot om as OpenStreenMap XML Data uitgevoer te + word. Verdiep asseblief die kamerablik of kies 'n kleiner gebied. Wend andersins + een van die bronne hieronder aan om massadata af te laai. + planet: + title: Planeet OSM options: Voorkeure format: Formaat scale: Skaal max: maksimum - image_size: 'Prentgrootte:' - zoom: Zoom + image_size: Beeldgrootte + zoom: Vergroot add_marker: Plaas 'n merker op die kaart latitude: 'Breedte:' longitude: 'Lengte:' - output: Afvoer - export_button: Eksporteer + output: Uitset + paste_html: Plak HTML om in die webblad te versteek + export_button: Uitvoer geocoder: search: title: - latlon: Resultate vanaf intern - us_postcode: Resultate vanaf Geocoder.us - uk_postcode: Resultate vanaf NPEMap / - FreeThe Postcode - ca_postcode: Resultate vanaf Geocoder.CA - osm_nominatim: Resultate vanaf OpenStreetMap + latlon: Uitslae vooruitspruitend intern + uk_postcode: Uitslae vanaf NPEMap / FreeThe + Postcode + ca_postcode: Uitslae vanaf Geocoder.CA + osm_nominatim: Uitslae vanaf OpenStreetMap Nominatim - geonames: Resultate vanaf GeoNames - geonames_reverse: Resultate vanaf GeoNames + geonames: Uitslae vanaf GeoNames + geonames_reverse: Uitslae vanaf GeoNames search_osm_nominatim: prefix: aerialway: - cable_car: Kabelkar + cable_car: Sweefspoor aeroway: + aerodrome: Vliegveld gate: Hek + helipad: Helikopterplatform + runway: Aanloopbaan + taxiway: Rybaan + terminal: Terminaal amenity: + animal_shelter: Dierebeskermingsvereniging arts_centre: Kunssentrum atm: OTM bank: Bank bar: Kroeg - bench: Bank + bbq: Braai + bench: Bankie bicycle_parking: Fietsparkering - bicycle_rental: Fietsverhuring + bicycle_rental: Fietshuur + biergarten: Biertuin + boat_rental: Boothuur brothel: Bordeel bureau_de_change: Wisselkantoor bus_station: Bushalte cafe: Kafee - car_rental: Motorverhuring + car_rental: Motorverhuurder + car_sharing: Saam-ry car_wash: Karwas - casino: Casino - cinema: Bioskoop + casino: Dobbelhuis + charging_station: Herlaaistasie + childcare: Kindersorg + cinema: Rolprentteater clinic: Kliniek + clock: Klok college: Kollege - community_centre: Gemeenskap-sentrum + community_centre: Gemeenskapsentrum courthouse: Hof crematorium: Krematorium dentist: Tandarts @@ -249,12 +406,15 @@ af: embassy: Ambassade emergency_phone: Noodtelefoon fast_food: Wegneemetes - ferry_terminal: Veerterminaal + ferry_terminal: Pontterminaal fire_hydrant: Brandkraan fire_station: Brandweerstasie + food_court: Kosarea fountain: Fontein fuel: Brandstof + gambling: Dobbelary grave_yard: Begraafplaas + gym: Fiksheidsentrum / Gim health_centre: Gesondheidsentrum hospital: Hospitaal hunting_stand: Jagtoring @@ -263,20 +423,23 @@ af: library: Biblioteek market: Mark marketplace: Markplein + monastery: Monnikeklooster + motorcycle_parking: Motorfietsparkering nightclub: Nagklub nursery: Kleuterskool - nursing_home: Verpleeghuis + nursing_home: Verpleging- en versorgingshuis office: Kantoor - parking: Parkade + parking: Parkering + parking_entrance: Parkeeringang pharmacy: Apteek - place_of_worship: Plek van aanbidding + place_of_worship: Plek van Aanbidding police: Polisie post_box: Posbus post_office: Poskantoor preschool: Kleuterskool prison: Tronk pub: Kroeg - public_building: Openbare gebou + public_building: Openbare Gebou reception_area: Ontvangsarea recycling: Herwinningspunt restaurant: Restaurant @@ -285,22 +448,30 @@ af: school: Skool shelter: Skuiling shop: Winkel + shower: Stort + social_centre: Maatskaplike Sentrum social_club: Sosiale klub - studio: Studio + studio: Ateljee swimming_pool: Swembad taxi: Taxi - telephone: Openbare telefoon + telephone: Openbare Telefoon theatre: Teater toilets: Toilette townhall: Stadsaal university: Universiteit veterinary: Veearts - waste_basket: Asblik + village_hall: Dorpsaal + waste_basket: Snippermandjie + waste_disposal: Stortingsterrein youth_centre: Jeugsentrum boundary: administrative: Administratiewe grens - national_park: Nasionale park + national_park: Nasionale Park + protected_area: Beskermingsgebied bridge: + aqueduct: Waterbrug + suspension: Hangbrug + viaduct: Viaduk "yes": Brug building: "yes": Gebou @@ -309,36 +480,52 @@ af: carpenter: Skrynwerker electrician: Elektrisiën gardener: Tuinier + painter: Verwer photographer: Fotograaf plumber: Loodgieter shoemaker: Skoenmaker + tailor: Snyer + "yes": Handwerkwinkel + emergency: + ambulance_station: Ambulansstasie + defibrillator: Defibrillator + landing_site: Noodlandingsarea + phone: Noodtelefoon highway: + abandoned: Verlate Snelweg bridleway: Ruiterpad + bus_guideway: Toegewyde busbaan bus_stop: Bushalte construction: Snelweg in aanbou cycleway: Fietspad + elevator: Hysbak emergency_access_point: Noodtoeganspunt footway: Voetpad ford: Drif + milestone: Mylpaal motorway: Snelweg motorway_junction: Snelwegknooppunt path: Pad - pedestrian: Voetpad + pedestrian: Voetgangerspad platform: Platform - primary: Primêre pad - primary_link: Primêre pad + primary: Primêre Pad + primary_link: Primêre Pad + proposed: Voorgestelde pad raceway: Renbaan residential: Residensiële straat + rest_area: Rusarea road: Pad - secondary: Sekondêre pad - secondary_link: Sekondêre pad + secondary: Sekondêre Pad + secondary_link: Sekondêre Pad service: Dienspad - services: Snelweg Dienste - speed_camera: Spoedkamera + services: Snelwegdienste + speed_camera: Snelheidskamera steps: Trappe - street_lamp: Straatlamp - tertiary: Tersiêre pad + street_lamp: Straatlig + tertiary: Tersiêre Pad + tertiary_link: Tersiêre pad track: Spoor + traffic_signals: Verkeerstekens trail: Wandelpad trunk: Hoofroete trunk_link: Hoofroete @@ -348,102 +535,165 @@ af: historic: archaeological_site: Argeologiese werf battlefield: Slagveld + boundary_stone: Grenspaal building: Historiese gebou + bunker: Bomskuiling castle: Kasteel church: Kerk + city_gate: Stadspoort + citywalls: Stadsmure + fort: Fort + heritage: Erfenisterrein house: Huis icon: Ikoon manor: Landgoed memorial: Gedenkteken mine: Myn monument: Monument + roman_road: Romeinse pad ruins: Ruïnes + stone: Steen + tomb: Graf tower: Toring - wayside_cross: Kruis langs die pad - wayside_shrine: Altaar langs die pad + wayside_cross: Padkruis + wayside_shrine: Padaltaar wreck: Wrak + junction: + "yes": Verkeersaansluiting landuse: allotments: Volkstuine + basin: Kom cemetery: Begraafplaas - commercial: Kommersiële gebied + commercial: Handelsarea + conservation: Natuurbewaring construction: Konstruksie farm: Plaas farmland: Plaasgrond farmyard: Plaaswerf forest: Woud + garages: Vulstasies grass: Gras - industrial: Industriële gebied + industrial: Nywerheidsgebied landfill: Stortingsterrein + meadow: Vleiweiding military: Militêre gebied mine: Myn - quarry: Steengroewe + orchard: Vrugteboord + quarry: Steengroef railway: Spoorweg + recreation_ground: Ontspanningsterrein reservoir: Reservoir residential: Woongebied retail: Kleinhandel vineyard: Wingerd + "yes": Landgebruik leisure: - beach_resort: Strandoort - fishing: Visvangarea + beach_resort: Strandoord + bird_hide: Voëlkykhuisie + club: Klub + dog_park: Hondepark + fishing: Visvanggebied + fitness_centre: Fiksheidsentrum garden: Tuin golf_course: Gholfbaan - ice_rink: Ysbaan + horse_riding: Perdry + ice_rink: Ysskaatsbaan marina: Marina - miniature_golf: Minigolf + miniature_golf: Mini-gholf nature_reserve: Natuurreservaat park: Park pitch: Sportveld playground: Speelgrond - sports_centre: Sport-sentrum + recreation_ground: Ontspanningsterrein + resort: Oord + sauna: Sauna + slipway: Glybaan + sports_centre: Sportsentrum stadium: Stadion swimming_pool: Swembad track: Atletiekbaan water_park: Waterspeelpark + "yes": Vrye tyd + man_made: + lighthouse: Vuurtoring + pipeline: Pypleiding + tower: Toring + works: Fabriek + "yes": Mensgemaak + military: + airfield: Miliêre vliegveld + barracks: Barakke + bunker: Bomskuiling + mountain_pass: + "yes": Bergpas natural: bay: Baai beach: Strand cape: Kaap cave_entrance: Grotingang - cliff: Kloof + cliff: Krans crater: Krater + dune: Duin + fell: Heuwel fjord: Fjord forest: Woud geyser: Geiser glacier: Gletser + grassland: Grasveld heath: Heide hill: Heuwel island: Eiland land: Land marsh: Moeras + moor: Vleiland mud: Modder peak: Piek point: Punt reef: Rif - ridge: Bergkam - rock: Rotse - scree: Puin + ridge: Bergrif + rock: Rots + saddle: Saal + sand: Sand + scree: Berghellingspuin scrub: Struikgewas spring: Bron + stone: Steen strait: Seestraat tree: Boom valley: Vallei - volcano: Vulkaan + volcano: Vuurspuwende Berg water: Water - wetland: Moeras + wetland: Vleiland wood: Bos + office: + accountant: Boekhouer + administrative: Administrasie + architect: Argitek + company: Maatskappy + estate_agent: Eiendomsagent + insurance: Versekeringskantoor + lawyer: Prokureur + telecommunication: Telekommunikasiekantoor + travel_agent: Reisagent + "yes": Kantoor place: + allotments: Toekennings + block: Blokkeer airport: Lughawe city: Stad country: Land county: Distrik farm: Plaas - hamlet: Dorpie + hamlet: Gehuggie house: Huis houses: Huise island: Eiland islet: Eilandjie + isolated_dwelling: Geïsoleerde woning locality: Ligging + moor: Vleiland municipality: Munisipaliteit + neighbourhood: Woonbuurt postcode: Poskode region: Streek sea: See @@ -451,33 +701,43 @@ af: subdivision: Onderverdeling suburb: Voorstad town: Dorp - unincorporated_area: Uitgesluite Ruimte - village: Dorp + unincorporated_area: Uitgeslote Ruimte + village: Gehug + "yes": Plek railway: + abandoned: Verlate Spoorweg construction: Spoor in aanbou - disused_station: Ongebruikte spoorwegstasie + disused: Spoorweg in onbruik + disused_station: Spoorwegstasie in onbruik funicular: Kabelspoorweg halt: Treinhalte historic_station: Historiese spoorwegstasie junction: Spoorwegkruising level_crossing: Spooroorgang + light_rail: Ligte spoor + miniature: Miniatuur spoorweg monorail: Monospoor narrow_gauge: Smalspoorweg - platform: Spoorweg-platform + platform: Spoorwegperron preserved: Historiese spoorweg + proposed: Voorgestelde spoorlyn station: Spoorwegstasie - subway: Metrostasie + subway: Duikwegspoor subway_entrance: Ondergrondse spoorwegingang switch: Spoogwegpunte + tram: Tremspoor tram_stop: Tremhalte shop: + antiques: Antiek / Oudhede art: Kunswinkel bakery: Bakkery beauty: Skoonheidssalon + beverages: Drankwinkel bicycle: Fietswinkel books: Boekwinkel + boutique: Boutique butcher: Slagter - car: Motorwinkel + car: Motorhandelaar car_parts: Motoronderdele car_repair: Motorherstel carpet: Mat-/tapytwinkel @@ -485,13 +745,17 @@ af: chemist: Apteek clothes: Klerewinkel computer: Rekenaarwinkel - convenience: Gemakswinkel - copyshop: Fotokopie-winkel - cosmetics: Kosmetiesewinkel + confectionery: Banketbakkery + convenience: Geriefswinkel + copyshop: Fotostaatwinkel + cosmetics: Kosmetiekwinkel + deli: Deli + department_store: Afdelingswinkel discount: Afslagwinkel - doityourself: Doen-dit-self-winkel + doityourself: Doen-Dit-Self-winkel dry_cleaning: Droogskoonmaker electronics: Elektronikawinkel + estate_agent: Eiendomsagent farm: Plaaswinkel fashion: Modewinkel fish: Viswinkel @@ -501,15 +765,16 @@ af: furniture: Meubels gallery: Galery garden_centre: Kwekery/Tuinsentrum - general: Algemene winkel - gift: Geskenkwinkel - grocery: Kruideniersware-winkel + general: Algemene Handelaar + gift: Geskenkewinkel + greengrocer: Groentehandelaar + grocery: Kruidenierswinkel hairdresser: Haarkapper - hardware: Hardwarewinkel - hifi: Hi-Fi + hardware: Hardewarewinkel + hifi: Hoëtrou insurance: Versekering jewelry: Juwelierswinkel - kiosk: Kioskwinkel + kiosk: Kiosk laundry: Wassery mall: Winkelsentrum market: Mark @@ -519,27 +784,33 @@ af: newsagent: Nuusagent optician: Oogkundige organic: Organiese koswinkel - outdoor: Buitelug-winkel + outdoor: Buitelugwinkel pet: Troeteldierwinkel + pharmacy: Apteek photo: Fotowinkel salon: Skoonheidssalon + second_hand: Tweedehandswinkel shoes: Skoenwinkel shopping_centre: Winkelsentrum sports: Sportwinkel - stationery: Skryfbehoeftes-winkel + stationery: Skryfbehoeftewinkel supermarket: Supermark + tailor: Snyer toys: Speelgoedwinkel - travel_agency: Reisburo - video: Video-winkel + travel_agency: Reisagentskap + video: Videowinkel + "yes": Winkel tourism: alpine_hut: Berghut + apartment: Woonstel artwork: Kunswerk - attraction: Attraksie + attraction: Trekpleister bed_and_breakfast: Bed en Ontbyt cabin: Hut camp_site: Kampterrein caravan_site: Karavaanpark chalet: Chalet + gallery: Galery guest_house: Gastehuis hostel: Jeugherberg hotel: Hotel @@ -551,20 +822,32 @@ af: viewpoint: Uitkykpunt zoo: Dieretuin tunnel: + culvert: Duiksloot "yes": Tonnel waterway: + artificial: Kunstmatige waterweg boatyard: Skeepswerf canal: Kanaal dam: Dam + derelict_canal: Verlate Kanaal ditch: Sloot dock: Dokke drain: Afvoerkanaal lock: Sluis lock_gate: Sluisdeur + mooring: Kaai rapids: Stroomversnelling river: Rivier stream: Stroom + wadi: Droë woestynrivierbedding waterfall: Waterval + weir: Stuwal + "yes": Waterweg + admin_levels: + level4: Staatsgrens + level5: Streekgrens + level8: Stadsgrens + level9: Dorpsgrens description: title: geonames: Ligging vanaf GeoNames @@ -574,101 +857,167 @@ af: places: Plekke results: no_results: Geen resultate gevind nie - more_results: Meer resultate + more_results: Nog resultate layouts: logo: alt_text: OpenStreetMap-logo - home: tuis + home: Keer terug na tuisoord logout: Meld af log_in: Meld aan - log_in_tooltip: Teken aan met 'n bestaande rekening + log_in_tooltip: Teken met 'n bestaande rekening aan sign_up: Registreer - sign_up_tooltip: Skep 'n rekening vir wysigings - edit: Wysig + start_mapping: Begin Karteer + sign_up_tooltip: Skep 'n rekening vir redigeerregte + edit: Redigeer history: Geskiedenis - export: Eksporteer + export: Voer uit data: Data + export_data: Voer data uit gps_traces: GPS-spore - gps_traces_tooltip: Beheer GPS-spore + gps_traces_tooltip: Bestuur GPS-spore user_diaries: Gebruikersdagboeke user_diaries_tooltip: Wys gebruikersdagboeke - tag_line: Die vrye wiki-wêreldkaart + edit_with: Redigeer met %{editor} + tag_line: Die Vrye Wiki-Wêreldkaart intro_header: Welkom by OpenStreetMap! - intro_text: OpenStreetMap is 'n kaart van die wêreld, geskep deur gewone mense. - Dis gratis om te gebruik onder 'n oop lisensie. - intro_2_create_account: Skep gebruikerrekening - osm_read_only: Die OpenStreetMap-databasis kan op die oomblik slegs gelees word - aangesien noodsaaklik onderhoud tans uitgevoer word. + intro_text: OpenStreetMap is wêreldkaart deur gewone mense geskep. Die gebruik + daarvan is gratis en val onder 'n oop-lisensie. + intro_2_create_account: Skep 'n gebruikerrekening + partners_partners: vennote + osm_offline: Instandhouding word tans op die OpenStreetMap-databasis uitgevoer; + derhalwe is dit tans vanlyn tot en met die instandhouding afgehandel is. + osm_read_only: Aangesien noodsaaklik onderhoud tans op die OpenStreetMap-databasis + uitgevoer word, bied dit tans slegs leesregte. donate: Ondersteun OpenStreetMap deur aan die Hardeware Opgradeer-fonds te %{link}. help: Hulp about: Aangaande copyright: Kopiereg community: Gemeenskap + community_blogs: Gemeenskapblogs + foundation: Stigting foundation_title: Die OpenStreetMap-stigting make_a_donation: - title: Ondersteun OpenStreetMap met 'n geldelike donasie - text: Maak 'n donasie - learn_more: Meer inligting + title: Ondersteun OpenStreetMap met 'n geldelike skenking + text: Skenk aan die projek + learn_more: Kom meer te wete more: Meer license_page: foreign: - title: Oor hierdie vertaling + title: Aangaande dié vertaling + native: + title: Aangaande dié blad + mapping_link: begin karteer + legal_babble: + title_html: Kopiereg en Lisensie + intro_2_html: |- + Dit staan u vry om ons data te kopieer, versprei, versend of aan te maps, mits u erkenning aan OpenStreetMap en die bydraers gee. Indien u ons data wysig of daarop voortbou, mag u dit slegs in terme van dieselfde lisensie versprei. Die volledige legal + code verduidelik u regte en verantwoordelikhede. + credit_title_html: Hoe om na OpenStreetMap te verwys + contributors_title_html: Ons bydraers + infringement_title_html: Kopieregoortreding welcome_page: title: Welkom! + basic_terms: + title: Grondliggende begrippe vir kartering + paragraph_1_html: OpenStreetMap bevat 'n gedeelte van ons eie vakbegrippe. Hier + is 'n paar wat handig te pas sal kom. + rules: + title: Reëls! + questions: + title: Enige vrae? + start_mapping: Begin Karteer + add_a_note: + title: Geen tyd om te redigeer? Voeg 'n opmerking by! + fixthemap: + how_to_help: + title: Hoe om te help + join_the_community: + title: Sluit by die gemeenskap aan + other_concerns: + title: Andere aangeleenthede help_page: + welcome: + url: /welkom mailing_lists: title: Poslyste + forums: + title: Forums + wiki: + url: http://wiki.openstreetmap.org/ + title: wiki.openstreetmap.org + about_page: + next: Volgende + local_knowledge_title: Plaaslike Kennis + community_driven_title: Gemeenskapsgedrewe + legal_title: Wetlik + partners_title: Vennote notifier: diary_comment_notification: - subject: '[OpenStreetMap] %{user} het kommentaar op u dagboekinskrywing gelewer' + subject: '[OpenStreetMap] %{user} het ''n kommentaar oor ''n dagboekinskrywing + gemaak.' hi: Hallo %{to_user}, + header: '%{from_user} het kommentaar oor die OpenStreetMap dagboekinskrywing + met die tema %{subject} gelewer:' message_notification: hi: Hallo %{to_user}, friend_notification: + hi: Hallo %{to_user}, subject: '[OpenStreetMap] %{user} het u as ''n vriend bygevoeg' gpx_notification: greeting: Hallo, your_gpx_file: Dit lyk soos jou GPX-lêer with_description: met die beskrywing - and_the_tags: 'en die volgende etikette:' - and_no_tags: en geen etikette. + and_the_tags: 'en die volgende merkers:' + and_no_tags: en geen merkers nie. failure: - more_info_2: 'hulle kan gevind word by:' + more_info_2: 'hulle kan gevind word te:' signup_confirm: subject: '[OpenStreetMap] Welkom by OpenStreetMap' + greeting: Hallo! + created: Iemand (hopelik u) het pas 'n rekening op %{site_url} geskep. + confirm: 'Voordat ons iets doen, verlang ons ''n bevestiging dat dié versoek + inderdaad van u afkomstig is. As dit so is, klik op die onderstaande skakel + om u rekening te bevestig:' + welcome: Nadat u u rekening bevestig het, bied ons u graag addisionele inligting + sodat u kan wegtrek. email_confirm: subject: '[OpenStreetMap] Bevestig u e-posadres' email_confirm_plain: greeting: Hallo, email_confirm_html: greeting: Hallo, - hopefully_you: Iemand (hopelik u) wil graag sy e-posadres op %{server_url} verander - na %{new_address}. - click_the_link: As dit u is, kliek op die onderstaande skakel om die verandering + hopefully_you: Iemand (hopelik u) wil graag hul e-posadres op %{server_url} + verander na %{new_address}. + click_the_link: As dit u is, klik die onderstaande skakel om die verandering te bevestig. lost_password: - subject: '[OpenStreetMap] Versoek herstel van wagwoord' + subject: '[OpenStreetMap] Rig wagwoordherstel versoek' lost_password_plain: greeting: Hallo, - click_the_link: As dit u is, kliek op die onderstaande skakel om die wagwoord - te herstel. + click_the_link: As dit u is, klik die onderstaande skakel om u wagwoord te herstel. lost_password_html: greeting: Hallo, + note_comment_notification: + anonymous: '''n Anonieme gebruiker' + greeting: Hallo, + changeset_comment_notification: + hi: Hallo %{to_user}, + greeting: Hallo, message: inbox: - title: Inboks - my_inbox: My inboks - outbox: uitboks - from: Vanaf + title: In-vakkie + my_inbox: My in-vakkie + outbox: uit-vakkie + from: Van subject: Onderwerp date: Datum - no_messages_yet: U het nog geen boodskappe nie. Hoekom kontak u nie sommige - van die %{people_mapping_nearby_link} nie? + no_messages_yet: U het nog geen boodskappe nie. Waarom tree u nie met sommige + van die %{people_mapping_nearby_link} in verbinding nie? people_mapping_nearby: nabygeleë karteerders message_summary: unread_button: Merk as ongelees read_button: Merk as gelees - reply_button: Antwoord + reply_button: Beantwoord delete_button: Verwyder new: title: Stuur boodskap @@ -676,56 +1025,62 @@ af: subject: Onderwerp body: Teks send_button: Stuur - back_to_inbox: Terug na inboks + back_to_inbox: Terug na in-vakkie message_sent: Boodskap is gestuur no_such_message: - title: Die boodskap bestaan nie - heading: Die boodskap bestaan nie + title: Geen so 'n boodskap nie + heading: Geen so 'n boodskap nie outbox: - title: Uitboks + title: Uit-vakkie my_inbox: My %{inbox_link} - inbox: inboks - outbox: uitboks + inbox: in-vakkie + outbox: uit-vakkie to: Aan subject: Onderwerp date: Datum - no_sent_messages: U het nog geen boodskappe gestuur nie. Hoekom kontak u nie - sommige van die %{people_mapping_nearby_link} nie? + no_sent_messages: U het nog geen boodskappe gestuur nie. Waarom tree u nie met + sommige van die %{people_mapping_nearby_link} in verbinding nie? people_mapping_nearby: nabygeleë karteerders read: title: Lees boodskap from: Van subject: Onderwerp date: Datum - reply_button: Antwoord + reply_button: Beantwoord unread_button: Merk as ongelees + delete_button: Skrap + back: Terug to: Aan sent_message_summary: delete_button: Verwyder mark: - as_read: Boodskap gemerk as gelees - as_unread: Boodskap gemerk as ongelees + as_read: Boodskap as gelees gemerk + as_unread: Boodskap as ongelees gemerk delete: deleted: Boodskap is verwyder site: index: - permalink: Permanente skakel - shortlink: Kort skakel + permalink: Perma-skakel + shortlink: Kortskakel edit: user_page_link: gebruikersbladsy anon_edits_link_text: Lees waarom dit die geval is. sidebar: - search_results: Soekresultate + search_results: Soekuitslae close: Sluit search: search: Soek - get_directions_title: Kry aanwysings tussen twee punte - where_am_i: Waar is ek? + get_directions: Kry rigtingaanwysings + get_directions_title: Kry rigtingaanwysings tussen twee punte + from: Vanaf + to: Na + where_am_i: Waar bevind ek my? submit_text: Soek key: table: entry: motorway: Snelweg + main_road: Hoofweg trunk: Hoofroete primary: Primêre pad secondary: Sekondêre pad @@ -733,6 +1088,7 @@ af: track: Spoor bridleway: Ruiterpad cycleway: Fietspad + cycleway_national: Nasionale fietsroete footway: Voetpad rail: Spoorweg subway: Ondergrondse spoorweg @@ -740,11 +1096,11 @@ af: - Ligte spoor - trem cable: - - Kabelkar + - Sweefspoor - stoelhyser runway: - Lughawe aanloopbaan - - taxibaan + - vliegtuigrybaan apron: - Lughaweplatform - terminaal @@ -757,98 +1113,117 @@ af: common: - Gemeen - weiland - retail: Winkelgebied - industrial: Industriële gebied + retail: Handelsgebied + industrial: Nywerheidsgebied commercial: Kommersiële gebied heathland: Heide lake: - Meer - reservoir farm: Plaas - brownfield: Braakveld terrein + brownfield: Braakveldterrein cemetery: Begraafplaas allotments: Volkstuine pitch: Sportveld - centre: Sport-sentrum + centre: Sportsentrum reserve: Natuurreservaat military: Militêre gebied school: - Skool - universiteit - building: Belangrike gebou + building: Betekenisvolle gebou station: Spoorwegstasie summit: - Piek - piek tunnel: Strepieomhulsel = tonnel bridge: Swartomhulsel = brug - private: Privaat toegang + private: Privaat-toegang destination: Bestemmingsverkeer - construction: Paaie onder konstruksie + construction: Paaie in aanbou + bicycle_shop: Fietswinkel + bicycle_parking: Fietsparkering + toilets: Toilette + richtext_area: + edit: Redigeer + preview: Voorskou + markdown_help: + headings: Opskrifte + heading: Opskrif + unordered: Ongeordende lys + ordered: Geordende lys + first: Eerste item + second: Tweede item + link: Skakel + text: Teks + image: Beeld + alt: Alternatiewe teks + url: URL trace: create: upload_trace: Laai GPS-spore op edit: - title: Wysig spoor %{name} + title: Redigeer tans spoor %{name} heading: Wysig spoor %{name} filename: 'Lêernaam:' - download: aflaai + download: laai af uploaded_at: 'Opgelaai op:' points: 'Punte:' start_coord: 'Beginkoördinaat:' map: kaart - edit: wysig + edit: redigeer owner: 'Eienaar:' description: 'Beskrywing:' - tags: 'Etikette:' - tags_help: met kommas geskei - save_button: Stoor wysigings + tags: 'Merkers:' + tags_help: komma afgebaken + save_button: Stoor Wysigings visibility: 'Sigbaarheid:' visibility_help: wat beteken dit? trace_form: upload_gpx: 'Laai GPX-lêer op:' description: 'Beskrywing:' - tags: 'Etikette:' - tags_help: met kommas geskei + tags: 'Merkers:' + tags_help: komma afgebaken visibility: 'Sigbaarheid:' visibility_help: wat beteken dit? upload_button: Laai op help: Hulp trace_header: + upload_trace: Laai 'n GPS-spoor op see_all_traces: Wys alle spore see_your_traces: Sien al u spore trace_optionals: - tags: Etikette + tags: Merkers view: title: Besigtig spoor %{name} heading: Besigtig spoor %{name} - pending: BESIG + pending: HANGEND filename: 'Lêernaam:' download: laai af uploaded: 'Opgelaai op:' points: 'Punte:' start_coordinates: 'Beginkoördinaat:' map: kaart - edit: wysig + edit: redigeer owner: 'Eienaar:' description: 'Beskrywing:' - tags: 'Etikette:' + tags: 'Merkers:' none: Geen edit_track: Wysig hierdie spoor delete_track: Verwyder hierdie spoor - trace_not_found: Spoor nie gevind nie! + trace_not_found: Spoor onverkrygbaar! visibility: 'Sigbaarheid:' trace_paging_nav: showing_page: Bladsy %{page} trace: - pending: BESIG + pending: HANGEND count_points: '%{count} punte' ago: '%{time_in_words_ago} gelede' more: meer - trace_details: Wys spoor besonderhede + trace_details: Wys Besonderhede van die Spoor view_map: Wys kaart - edit: wysig - edit_map: Wysig kaart + edit: redigeer + edit_map: Redigeer Kaart public: OPENBAAR identifiable: IDENTIFISEERBAAR private: PRIVAAT @@ -859,48 +1234,68 @@ af: public_traces: Openbare GPS-spore your_traces: U GPS-spore public_traces_from: Openbare GPS-spore van %{user} - tagged_with: geëtiketteer met %{tags} + tagged_with: gemerk met %{tags} delete: - scheduled_for_deletion: Spoor is geskeduleer vir verwydering + scheduled_for_deletion: Spoor is vir verwydering geoormerk make_public: made_public: Spoor is openbaar gemaak oauth: oauthorize: allow_read_prefs: lees u gebruikersvoorkeure. allow_write_prefs: verander jou gebruikersvoorkeure. - allow_write_api: die kaart wysig. + allow_write_api: wysig die kaart. allow_write_gpx: laai GPS-spore op. + allow_write_notes: wysig opmerkings. + grant_access: Verleen toegang + oauthorize_success: + title: Magtigingsversoek toegestaan + allowed: U het die program %{app_name} toegang tot u rekening verleen. + verification: Die bevestigingskode is %{code} + oauthorize_failure: + title: Magtigingsversoek het misluk + denied: U het die program %{app_name} toegang tot u rekening geweier. + invalid: Die magtigingsteken is ongeldig. + revoke: + flash: U het die teken vir %{application} teruggetrek. + permissions: + missing: U het nie die program toegang tot hierdie fasilititeit verleen nie. oauth_clients: new: title: Registreer 'n nuwe toepassing submit: Registreer edit: - title: Wysig u toepassing - submit: Wysig + title: Redigeer u program + submit: Redigeer show: + title: OAuth-besonderhede vir %{app_name} + secret: 'Verbruikersgeheim:' + url: Versoek teken-URL + access_url: 'Toegangsteken URL:' authorize_url: 'Magtig URL:' - edit: Wysig details - allow_read_prefs: lees hulle gebruikersvoorkeure. - allow_write_diary: skep dagboekinskrywings, lewer kommentaar en maak vriende. + edit: Redigeer Besonderhede + confirm: Is u seker? + allow_read_prefs: lees hul gebruikersvoorkeure. + allow_write_diary: skep dagboekinskrywings, maak opmerkings en maak vriende. allow_write_api: wysig die kaart. allow_write_gpx: laai GPS-spore op. index: - title: My OAuth-details - application: Toepassingnaam + title: My OAuth-gegewens + application: Programnaam issued_at: Uitgereik op revoke: Herroep! - my_apps: My kliënt-toepassing - register_new: Registreer u toepassing + my_apps: My Kliënt-programme + register_new: Registreer u program form: name: Naam required: Verplig url: Toepassing-URL support_url: Ondersteunings-URL - allow_read_prefs: lees hulle gebruikersvoorkeure. + allow_read_prefs: lees hul gebruikersvoorkeure. allow_write_prefs: verander hulle gebruikersvoorkeure. - allow_write_diary: skep dagboekinskrywings, lewer kommentaar en maak vriende. + allow_write_diary: skep dagboekinskrywings, lewer kommentaar en ontmoet vriende. + allow_write_api: wysig die kaart. not_found: - sorry: Jammer, die %{type} kon nie gevind word nie. + sorry: Jammer, die %{type} blyk onverkrygbaar te wees. user: login: title: Meld aan @@ -910,17 +1305,18 @@ af: remember: Onthou my lost password link: Wagwoord vergeet? login_button: Meld aan + register now: Skryf nou in auth failure: Jammer, kon nie met hierdie inligting aanmeld nie. logout: title: Teken af - heading: Teken van OpenStreetMap af + heading: Meld van OpenStreetMap af logout_button: Teken af lost_password: - title: Wagwoord vergeet + title: Wagwoord verloor heading: Wagwoord vergeet? email address: 'E-posadres:' new password button: Herstel wagwoord - notice email cannot find: Kon nie die e-posadres vind nie, jammer. + notice email cannot find: E-posadres is ongelukkig onverkrygbaar, jammer. reset_password: title: Herstel wagwoord heading: Herstel wagwoord vir %{user} @@ -929,19 +1325,29 @@ af: reset: Herstel wagwoord flash changed: U wagwoord is verander. new: - title: Skep 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 Creative Commons-lisensie - (by-sa) gelisensieer word (nie-eksklusief). + title: Teken aan + about: + header: Gratis en redigeerbaar + html:

    Anders as ander kaarte, skep mense soos jy OpenStreetMap geheel en + al; daarbenewens is dit gratis vir enigeen om te herstel, by te werk, af + te laai en te benut.

    Registreer om 'n bydrae te lewer. Ons sal dan + u registrasie per e-pos bevestig.

    + license_agreement: Wanneer u u rekening bevestig, sal u ooreenkomstig die bepalings + vir bydraers moet toestem. email address: 'E-posadres:' - confirm email address: 'Bevestig E-posadres:' - not displayed publicly: Word nie publiek vertoon nie (sien geheimhoudingbeleid) - display name: 'Vertoon naam:' + confirm email address: 'Bevestig e-posadres:' + not displayed publicly: U adres word nie openbaar gemaak nie; raadpleeg ons + privaatheidsbeleid + vir verdere inligting. + display name: 'Skermnaam:' + display name description: U gebruikernaam wat openbaar verskyn. U kan dit wel + later nog onder voorkeure wysig. password: 'Wagwoord:' confirm password: 'Bevestig wagwoord:' - continue: Gaan voort + use external auth: Gebruik andersins 'n derde party om mee aan te meld + continue: Teken aan terms accepted: Dankie dat u die nuwe bydraerooreenkoms aanvaar het! terms: title: Bydraerooreenkoms @@ -951,24 +1357,24 @@ af: legale_names: france: Frankryk italy: Italië - rest_of_world: Res van die wêreld + rest_of_world: Die res van die wêreld no_such_user: - title: Gebruiker bestaan nie + title: Geen so 'n gebruiker nie heading: Die gebruiker %{user} bestaan nie - body: Daar is geen gebruiker met die naam %{user} nie. Kontroleer u spelling, - of die skakel waarop u gekliek het is verkeerd. + body: Daar is geen gebruiker met die naam %{user} nie. Gaan u spelling na, of + u het moontlik op 'n foutiewe skakel geklik. view: - my diary: My dagboek + my diary: My Dagboek new diary entry: nuwe dagboekinskrywing - my edits: My wysigings - my traces: My spore - my settings: My voorkeure + my edits: My Redigerings + my traces: My Spore + my settings: My Instellings oauth settings: Oauth-instellings - blocks on me: blokkades op my - blocks by me: blokkades deur my - send message: Stuur boodskap + blocks on me: Versperrings vir u + blocks by me: Versperrings deur u + send message: Stuur Boodskap diary: Dagboek - edits: Wysigings + edits: Redigerings traces: Spore remove as friend: Verwyder as vriend add as friend: Voeg by as vriend @@ -980,16 +1386,16 @@ af: spam score: 'SPAM-telling:' description: Beskrywing user location: Ligging van gebruiker - 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}. - settings_link_text: voorkeure + if set location: Stel u tuisligging by %{settings_link} in om gebruikers naby + u te sien. + settings_link_text: instellings your friends: U vriende no friends: U het nog geen vriende bygevoeg nie. km away: '%{count}km vêr' m away: '%{count}m vêr' nearby users: Ander nabygeleë gebruikers - no nearby users: Daar is nog geen gebruikers wat erken dat hulle nabygeleë karterinswerk - doen nie. + no nearby users: Daar is nog geen ander gebruikers wat erken dat hulle kaarte + in die nabye gebied afrond nie. role: administrator: Hierdie gebruiker is 'n administrateur moderator: Hierdie gebruiker is 'n moderator @@ -997,66 +1403,77 @@ af: administrator: Ken adminregte toe moderator: Ken moderatorregte toe revoke: - administrator: Trek adminregte terug - moderator: Trek moderatorregte terug - block_history: wys blokkades ontvang - moderator_history: wys blokkades uitgedeel - create_block: blokkeer die gebruiker - activate_user: aktiveer hierdie gebruiker - deactivate_user: deaktiveer hierdie gebruiker - confirm_user: bevestig hierdie gebruiker - hide_user: versteek hierdie gebruiker - unhide_user: maak die gebruiker weer sigbaar - delete_user: skrap die gebruiker + administrator: Herroep adminregte + moderator: Herroep moderatorregte + block_history: Aktiewe Versperrings + moderator_history: Uitgevoerde Versperrings + create_block: Versper hierdie gebruiker + activate_user: Aktiveer hierdie gebruiker + deactivate_user: Deaktiveer hierdie gebruiker + confirm_user: Bevestig dié Gebruiker + hide_user: Versteek hierdie gebruiker + unhide_user: Wys hierdie gebruiker + delete_user: Skrap dié Gebruiker confirm: Bevestig popup: your location: U ligging nearby mapper: Nabygeleë karteerder friend: Vriend account: - title: Wysig rekening - my settings: My voorkeure + title: Redigeer rekening + my settings: My instellings current email address: 'Huidige e-posadres:' new email address: 'Nuwe e-posadres:' - email never displayed publicly: (word nie openbaar gemaak nie) + email never displayed publicly: (word nooit openbaar vertoon nie) public editing: - heading: 'Openbaar wysigings:' - enabled: Geaktiveer. U is nie anoniem nie en kan inligting wysig. - enabled link text: wat is dit? - disabled link text: hoekom kan ek niks wysig nie? + heading: 'Openbare redigerings:' + enabled: Geaktiveer. Nie anoniem nie en kan tog data redigeer. + enabled link text: wat is dié? + disabled link text: hoekom kan ek nie redigeer nie? contributor terms: - link text: wat is dit? + link text: wat is dié? profile description: 'Profielbeskrywing:' - preferred languages: 'Voorkeur tale:' + preferred languages: 'Verkose Tale:' image: 'Beeld:' - new image: Voeg beeld by + new image: Voeg 'n beeld by replace image: Vervang die huidige beeld home location: 'Tuisligging:' - no home location: U het nog nie u huis se ligging ingevoer nie. + no home location: U het nog geen tuisligging ingelees nie. latitude: 'Breedtegraad:' longitude: 'Lengtegraad:' - update home location on click: Opdateer tuisligging wanneer ek op die kaart - kliek? - save changes button: Stoor wysigings - make edits public button: Maak al my wysigings openbaar + update home location on click: Werk tuisligging by wanneer ek op die kaart klik? + save changes button: Stoor Wysigings + make edits public button: Stel al my redigerings openbaar return to profile: Terug na profiel - flash update success: U gebruikersinligting is verander. + flash update success: Gebruikersbesonderhede suksesvol bygewerk. confirm: - heading: Kontroleer u e-pos! - press confirm button: Kliek op "Bevestig" hieronder om u rekening aktiveer. + heading: Gaan u e-pos na! + introduction_1: Ons het u 'n e-pos ter bevestiging getuur. + introduction_2: Klik op die skakel in die e-pos en bevestig u rekening, dan + sal u kan karteer. + press confirm button: Klik 'bevestig' hieronder om u rekening te aktiveer. button: Bevestig + success: U rekening is bevestig. Dankie dat u aangeteken het! + already active: Hierdie rekening is reeds bevestig. + unknown token: Die bevestigingskode het reeds verval of bestaan nie. + reconfirm_html: Sou u van ons verlang om weer die e-pos ter bevestiging te stuur, + klik hier. + confirm_resend: + failure: Die gebruiker %{name} is nie gevind nie. confirm_email: - heading: Bevestig verandering van e-posadres + heading: Bevestig 'n verandering van e-posadres + press confirm button: Klik op die volgende knoppie om u e-posadres te bevestig. button: Bevestig - success: U e-posadres verandering is bevestig! + success: Die verandering van u e-posadres is bevestig! set_home: flash success: U tuisligging is suksesvol gestoor make_friend: + button: As vriend byvoeg success: '%{name} is nou u vriend!' failed: Jammer, kon nie %{name} as 'n vriend byvoeg nie. already_a_friend: U is reeds met %{name} bevriend. remove_friend: - success: '%{name} is uit u lys van vriende verwyder.' + success: '%{name} is uit u vriendekring verwyder.' not_a_friend: '%{name} is nie een van u vriende nie.' list: title: Gebruikers @@ -1064,7 +1481,7 @@ af: summary: '%{name} geskep vanaf %{ip_address} op %{date}' summary_no_ip: '%{name} geskep op %{date}' confirm: Bevestig geselekteerde gebruikers - hide: Versteek geselekteerde gebruikers + hide: Versteek verkose gebruikers empty: Geen gebruikers gevind nie suspended: webmaster: webmeester @@ -1080,92 +1497,123 @@ af: user_block: not_found: sorry: Jammer, die gebruiker met ID %{id} kon nie gevind word nie. - back: Terug na die indeks + back: Terug na die register new: - heading: Skep blokkade op %{name} - submit: Skep blokkade - back: Wys alle blokkades + heading: Skep versperring op %{name} + submit: Skep versperring + back: Wys alle versperrings edit: - title: Wysig blokkade op %{name} - heading: Wysig blokkade op %{name} - submit: Opdateer blokkade - show: Wys hierdie blokkade - back: Wys alle blokkades + title: Redigeer versperring op %{name} + heading: Redigeer versperring op %{name} + submit: Werk versperring by + show: Wys dié versperring + back: Wys alle versperrings create: - try_contacting: Kontak asseblief die gebruiker en gee hom 'n redelike tyd om - te reageer alvorens u hom blokkeer. - try_waiting: Gee die gebruikers asseblief 'n redelike tyd om te reageer voordat - u 'n blokkade instel. - flash: Het gebruiker %{name} geblokkeer. + try_contacting: Probeer eers met die gebruiker in verbinding tree voordat u + hulle versper, en gun hulle 'n billike tyd om te antwoord. + try_waiting: Gun asseblief die gebruiker billik tyd om te antwoord voordat u + hulle versper. + flash: Het gebruiker %{name} versper. update: - success: Die blokkade is opgedateer. + success: Versperring bygewerk. index: - title: Gebruikersblokkades - heading: Lys van gebruikersblokkades - empty: Daar is nog geen blokkades ingestel nie. + title: Gebruikerversperrings + heading: Lys van gebruikersversperrings + empty: Daar is nog geen versperrings ingestel nie. revoke: - confirm: Is u seker u wil hierdie blokkade herroep? + confirm: Is u seker u wil hierdie versperring herroep? revoke: Herroep! - flash: Hierdie blokkade is herroep. + flash: Hierdie versperring is herroep. period: one: 1 uur other: '%{count} ure' partial: show: Wys - edit: Wysig + edit: Redigeer revoke: Herroep! confirm: Is u seker? - display_name: Geblokkeerde gebruiker + display_name: Versperde gebruiker creator_name: Skepper - reason: Rede vir blokkade + reason: Rede vir die versperring status: Status revoker_name: Herroep deur not_revoked: (nie herroep nie) + next: Volgende » + previous: « Vorige helper: - time_future: Verval oor %{time}. + time_future: Tyd oor %{time} verstreke. until_login: Aktief totdat die gebruiker aanmeld. - time_past: Het %{time} gelede verval. + time_past: Tyd is %{time} gelede verstreke. blocks_on: - title: Blokkades op %{name} - heading: Lys van blokkades teen %{name} - empty: '%{name} is nog nooit geblokkeer nie.' + title: Versperrings op %{name} + heading: Lys van versperrings teen %{name} + empty: '%{name} is nog nooit versper nie.' blocks_by: - title: Blokkades deur %{name} - heading: Lys van blokkades deur %{name} - empty: '%{name} het nog geen blokkades uitgevoer nie.' + title: Versperrings deur %{name} + heading: Lys van versperrings deur %{name} + empty: '%{name} het nog niks versper nie.' show: - title: '%{block_on} geblokkeer deur %{block_by}' - heading: '%{block_on} geblokkeer deur %{block_by}' - time_future: Verval oor %{time} - time_past: Het %{time} gelede verval + title: '%{block_on} word deur %{block_by} versper' + heading: '%{block_on} word deur %{block_by} versper' + time_future: Tyd oor %{time} verstreke. + time_past: Tyd is %{time} gelede verstreke status: Status show: Wys - edit: Wysig + edit: Redigeer revoke: Herroep! confirm: Is u seker? - reason: 'Rede vir blokkade:' - back: Wys alle blokkades + reason: 'Rede agter die versperring:' + back: Wys alle versperrings revoker: 'Herroep deur:' - needs_view: Die gebruiker moet aanmeld alvorens hierdie blokkade verwyder sal - word. + needs_view: Die gebruiker moet aanmeld alvorens hierdie versperring verwyder + sal word. javascripts: share: title: Deel + key: + title: Kaartsleutel + tooltip: Kaartsleutel map: zoom: - in: Zoom in + in: Zoem in + out: Zoem uit locate: title: Wys my ligging base: cycle_map: Fietskaart site: - edit_disabled_tooltip: Zoom in om die kaart te wysig - createnote_disabled_tooltip: Zoom in om 'n nota by die kaart te voeg - map_data_zoom_in_tooltip: Zoom in om kaartdata te sien + edit_disabled_tooltip: Zoem in om die kaart te wysig + createnote_disabled_tooltip: Zoem in om 'n nota by die kaart te voeg + map_data_zoom_in_tooltip: Zoem in om kaartdata te sien + changesets: + show: + comment: Opmerking + subscribe: Inskryf + unsubscribe: Kanselleer subskripsie + hide_comment: verskuil + unhide_comment: bring weer aan die lig directions: engines: graphhopper_bicycle: Fiets (GraphHopper) + graphhopper_car: Kar (GraphHopper) mapquest_bicycle: Fiets (MapQuest) mapquest_car: Kar (MapQuest) osrm_car: Kar (OSRM) + mapzen_bicycle: Fiets (Mapzen) + mapzen_car: Motor (Mapzen) + time: Tyd + query: + node: Knooppunt + way: Weg + relation: Verwantskap + nothing_found: Geen eienskappe gevind nie + context: + directions_from: Ringtingaanwysings vanaf hier + directions_to: Ringtingaanwysings hierheen + add_note: Voeg 'n nota hier by + show_address: Wys adres + centre_map: Stel kaartmiddelpunt hier in + redaction: + edit: + description: Beskrywing ... diff --git a/config/locales/aln.yml b/config/locales/aln.yml index 7d3a63378..6d8730d99 100644 --- a/config/locales/aln.yml +++ b/config/locales/aln.yml @@ -239,7 +239,6 @@ aln: search: title: latlon: Rezultatet prej Internal - us_postcode: Rezultatet prej Geocoder.us uk_postcode: Rezultatet prej NPEMap / FreeThe Postcode ca_postcode: Rezultatet prej Geocoder.CA diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 7872d1c7b..a0dfc880c 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -401,7 +401,6 @@ ar: search: title: latlon: نتائج داخليًا - us_postcode: نتائج من Geocoder.us uk_postcode: نتائج من NPEMap / FreeThe Postcode ca_postcode: نتائج من Geocoder.CA @@ -1246,6 +1245,7 @@ ar: date: التاريخ reply_button: رد unread_button: علّم كغير مقروءة + delete_button: احذف back: رجوع to: إلى wrong_user: "\uFEFFأنت مسجل دخول باسم '%{user}' ولكن الرسالة التي طلبت قراءتها diff --git a/config/locales/arz.yml b/config/locales/arz.yml index f9a4e88ba..a32b4ecb8 100644 --- a/config/locales/arz.yml +++ b/config/locales/arz.yml @@ -210,7 +210,6 @@ arz: search: title: latlon: نتائج داخليًا - us_postcode: نتائج من Geocoder.us uk_postcode: نتائج من NPEMap / FreeThe Postcode ca_postcode: نتائج من Geocoder.CA diff --git a/config/locales/ast.yml b/config/locales/ast.yml index 97a3ceb30..24e334d08 100644 --- a/config/locales/ast.yml +++ b/config/locales/ast.yml @@ -40,7 +40,7 @@ ast: tracetag: Etiqueta de traza user: Usuariu user_preference: Preferencia d'usuariu - user_token: Token d'usuariu + user_token: Pase d'usuariu way: Vía way_node: Nuedu de vía way_tag: Etiqueta de vía @@ -170,16 +170,16 @@ ast: note: nota redacted: redaction: Redaición de %{id} - message_html: La versión %{version} de %{type} nun se pue amosar porque ta redactada. + message_html: La versión %{version} de %{type} nun puede amosase porque se redactó. Por favor consulta %{redaction_link} pa más detalles. type: node: nuedu way: vía relation: rellación start_rjs: - feature_warning: Cargando %{num_features} carauterístiques, que puen facer que'l - navegador vaya lentu o nun respuenda. ¿Ta seguru de que quier amosar estos - datos? + feature_warning: Cargando %{num_features} carauterístiques, que pueden facer + que'l navegador vaya lentu o nun respuenda. ¿Tas seguru de que quies amosar + estos datos? load_data: Cargar datos loading: Cargando... tag_details: @@ -230,25 +230,25 @@ ast: comment: Comentariu area: Área list: - title: Conxuntos de cambios + title: Conxuntos de cambeos title_user: Conxuntos de cambeos de %{user} - title_friend: Conxuntos de cambios de los tos collacios - title_nearby: Conxuntos de cambios d'usuarios cercanos - empty: Nun s'alcontró dengún conxuntu de cambios. - empty_area: Nun hai conxuntos de cambios nesti área. - empty_user: Nun hai conxuntos de cambios d'esti usuariu. - no_more: Nun s'alcontraron más conxuntos de cambios. - no_more_area: Nun hai más conxuntos de cambios nesti área. - no_more_user: Nun hai más conxuntos de cambios d'esti usuariu. + title_friend: Conxuntos de cambeos de los tos collacios + title_nearby: Conxuntos de cambeos d'usuarios cercanos + empty: Nun s'alcontró nengún conxuntu de cambeos. + empty_area: Nun hai conxuntos de cambeos nesti área. + empty_user: Nun hai conxuntos de cambeos d'esti usuariu. + no_more: Nun s'alcontraron más conxuntos de cambeos. + no_more_area: Nun hai más conxuntos de cambeos nesti área. + no_more_user: Nun hai más conxuntos de cambeos d'esti usuariu. load_more: Cargar más timeout: sorry: Llevó demasiao tiempu baxar la llista de conxuntos de cambeos que pidisti. rss: - title_all: Alderique del conxuntu de cambios d'OpenStreetMap - title_particular: 'Alderique del conxuntu de cambios #%{changeset_id} d''OpenStreetMap' + title_all: Alderique del conxuntu de cambeos d'OpenStreetMap + title_particular: 'Alderique del conxuntu de cambeos #%{changeset_id} d''OpenStreetMap' comment: 'Comentariu nuevu sobro''l conxuntu de cambios #%{changeset_id} de %{author}' - commented_at_html: Anovado hai %{when} + commented_at_html: Anovao hai %{when} commented_at_by_html: Anovao hai %{when} por %{user} full: Alderique completu diary_entry: @@ -288,8 +288,8 @@ ast: no_such_entry: title: Nun esiste la entrada del diariu heading: 'Nun esiste la entrada con id: %{id}' - body: Sentímoslo, nun hai denguna entrada del diariu cola id %{id}. Comprueba - la escritura o si calcasti nun enllaz enquivocáu. + body: Sentímoslo, nun hai nenguna entrada del diariu cola id %{id}. Comprueba + la escritura o si primisti nun enllaz enquivocáu. diary_entry: posted_by: Unviáu por %{link_user} el %{created} en %{language_link} comment_link: Comentar esta entrada @@ -312,20 +312,20 @@ ast: feed: user: title: Entraes nel diariu d'OpenStreetMap de %{user} - description: Entraes recientes de %{user} nel diariu d'OpenStreetMap + description: Entraes recién de %{user} nel diariu d'OpenStreetMap language: title: Entraes nel diariu d'OpenStreetMap en %{language_name} - description: Entraes recientes nel diariu d'usuarios d'OpenStreetMap en %{language_name} + description: Entraes recién nel diariu d'usuarios d'OpenStreetMap en %{language_name} all: title: Entraes nel diariu d'OpenStreetMap - description: Entraes recientes nel diariu d'usuarios d'OpenStreetMap + description: Entraes recién nel diariu d'usuarios d'OpenStreetMap comments: has_commented_on: '%{display_name} comentó nes siguientes entraes del diariu' post: Publicar when: Cuándo comment: Comentariu ago: hai %{ago} - newer_comments: Comentarios nuevos + newer_comments: Comentarios más nuevos older_comments: Comentarios anteriores export: title: Esportar @@ -335,13 +335,13 @@ ast: format_to_export: Formatu a esportar osm_xml_data: Datos XML d'OpenStreetMap map_image: Imaxe del mapa (amuesa la capa estándar) - embeddable_html: HTML empotrable + embeddable_html: HTML pa embrivir licence: Llicencia - export_details: Los datos d'OpenStreetMap tan llicenciaos embaxo la llicencia + export_details: Los datos d'OpenStreetMap tan llicenciaos baxo la llicencia Open Data Commons Open Database (ODbL). too_large: - advice: 'Si falla la esportación anterior, por favor, piense n''utilizar una - de les fontes de la llista siguiente:' + advice: 'Si falla la esportación anterior, considera utilizar una de les fontes + de la llista siguiente:' body: Esti área ye abondo grande pa esportase como Datos XML d'OpenStreetMap. Acerca'l mapa o esbilla un área menor, o usa una de les fontes siguientes pa descargar cantidaes grandes de datos. @@ -373,13 +373,12 @@ ast: latitude: 'Llat:' longitude: 'Llon:' output: Salida - paste_html: Pegar el HTML pa empotrar nun sitiu web + paste_html: Pegar el HTML pa embrivir nun sitiu web export_button: Esportar geocoder: search: title: latlon: Resultaos internos - us_postcode: Resultaos de Geocoder.us uk_postcode: Resultaos de NPEMap / FreeThe Postcode ca_postcode: Resultaos de Geocoder.CA @@ -424,7 +423,7 @@ ast: car_rental: Alquiler de coches car_sharing: Compartir coche car_wash: Llaváu de coches - casino: Casino + casino: Casinu charging_station: Estación de carga childcare: Ludoteca cinema: Cine @@ -435,8 +434,8 @@ ast: courthouse: Xulgáu crematorium: Crematoriu dentist: Dentista - doctors: Ambulatoriu - dormitory: Dormitoriu + doctors: Médicos + dormitory: Residencia drinking_water: Agua potable driving_school: Autoescuela embassy: Embaxada @@ -445,27 +444,27 @@ ast: ferry_terminal: Terminal de ferry fire_hydrant: Boca d'incendios fire_station: Bomberos - food_court: Zona de restaurantes + food_court: Zona de restoranes fountain: Fonte fuel: Combustible gambling: Xuegos d'azar grave_yard: Cementeriu - gym: Ximnasiu / Fitness + gym: Ximnasiu health_centre: Centru de salú hospital: Hospital hunting_stand: Puestu de caza ice_cream: Xelaos - kindergarten: Guardería + kindergarten: Xardín d'infancia library: Biblioteca market: Mercáu marketplace: Mercáu monastery: Monasteriu motorcycle_parking: Aparcamientu pa motocicletes nightclub: Sala de fiestes - nursery: Preescolar - nursing_home: Residencia asistencial + nursery: Guardería + nursing_home: Residencia asistida office: Oficina - parking: Aparcaderu + parking: Aparcamientu parking_entrance: Entrada d'aparcamientu pharmacy: Farmacia place_of_worship: Llugar de cultu @@ -476,10 +475,10 @@ ast: prison: Cárcel pub: Pub public_building: Edificiu públicu - reception_area: Llugar de recepción + reception_area: Área de recepción recycling: Puntu llimpiu - restaurant: Restaurán - retirement_home: Residencia de mayores + restaurant: Restorán + retirement_home: Residencia de xubilaos sauna: Sauna school: Escuela shelter: Abellugu @@ -494,11 +493,11 @@ ast: telephone: Teléfonu públicu theatre: Teatru toilets: Servicios - townhall: Casa conceyu + townhall: Casa del conceyu university: Universidá vending_machine: Venta automática veterinary: Ciruxía veterinaria - village_hall: Casa de la villa + village_hall: Sala polivalente waste_basket: Papelera waste_disposal: Contenedor pa basories youth_centre: Centru de mocedá @@ -532,50 +531,50 @@ ast: landing_site: Llugar de aterrizaxe d'emerxencia phone: Teléfonu d'emerxencia highway: - abandoned: Autopista abandonada + abandoned: Estrada abandonada bridleway: Caleya bus_guideway: Carril bus con guía bus_stop: Parada d'autobús - construction: Carretera en construcción - cycleway: Sienda ciclista + construction: Estrada en construcción + cycleway: Pista pa bicicletes elevator: Ascensor - emergency_access_point: Puntu de llocalización d'emerxencia - footway: Sienda + emergency_access_point: Accesu d'emerxencia + footway: Senderu ford: Vau - living_street: Cai residencial - milestone: Finxu - motorway: Autopista - motorway_junction: Enllaz d'autopista - motorway_link: Autopista + living_street: Rúa residencial + milestone: Moyón + motorway: Autoestrada + motorway_junction: Encruz d'autoestrada + motorway_link: Enllaz d'autovía path: Camín - pedestrian: Vía peatonal + pedestrian: Camín peonil platform: Andén - primary: Carretera primaria - primary_link: Enllaz de carretera primaria - proposed: Carretera propuesta + primary: Estrada primaria + primary_link: Estrada primaria + proposed: Estrada propuesta raceway: Pista de carreres - residential: Cai residencial + residential: Rúa rest_area: Área de descansu - road: Carretera - secondary: Carretera secundaria - secondary_link: Enllaz de carretera secundaria - service: Carretera de serviciu - services: Servicios n'autopista + road: Estrada + secondary: Estrada secundaria + secondary_link: Estrada secundaria + service: Estrada de serviciu + services: Área de serviciu speed_camera: Radar steps: Escaleres street_lamp: Farola - tertiary: Carretera terciaria - tertiary_link: Carretera terciaria + tertiary: Estrada terciaria + tertiary_link: Estrada terciaria track: Pista - traffic_signals: Semáforos - trail: Camín - trunk: Carretera nacional - trunk_link: Enllaz de carretera nacional - unclassified: Carretera ensin clasificar - unsurfaced: Carretera ensin asfaltar - "yes": Carretera + traffic_signals: Señales de tráficu + trail: Senderu + trunk: Estrada nacional + trunk_link: Estrada nacional + unclassified: Estrada ensin clasificar + unsurfaced: Estrada ensin asfaltar + "yes": Estrada historic: - archaeological_site: Llugar arqueolóxicu + archaeological_site: Xacimientu arqueolóxicu battlefield: Campu de batalla boundary_stone: Finxu building: Edificiu históricu @@ -589,7 +588,7 @@ ast: house: Casa icon: Iconu manor: Casona - memorial: Monumentu + memorial: Memorial mine: Mina monument: Monumentu roman_road: Via romana @@ -598,27 +597,27 @@ ast: tomb: Sepulcru tower: Torre wayside_cross: Cruceru - wayside_shrine: Ermita + wayside_shrine: Santuariu de camín wreck: Naufraxu junction: "yes": Interseición landuse: - allotments: Güertes recreatives - basin: Conca - brownfield: Terrén en derribu + allotments: Güertos recreativos + basin: Cuenca + brownfield: Solar derribáu cemetery: Cementeriu - commercial: Área comercial + commercial: Área de negocios conservation: Conservación construction: Construcción - farm: Casería - farmland: Tierres de llabor - farmyard: Corral + farm: Granxa + farmland: Tierra de llabranza + farmyard: Antoxana forest: Área forestal garages: Garaxes grass: Yerba - greenfield: Plan d'espansión + greenfield: Terrén pa urbanizar industrial: Área industrial - landfill: Vertederu + landfill: Basureru meadow: Prau military: Área militar mine: Mina @@ -630,33 +629,33 @@ ast: reservoir_watershed: Cuenca del banzáu residential: Área residencial retail: Área comercial - road: Área de carretera + road: Zona d'estrada village_green: Prau municipal - vineyard: Viña + vineyard: Viñéu "yes": Usu del terrén leisure: - beach_resort: Turismu de playa + beach_resort: Complexu playeru bird_hide: Observatoriu d'aves club: Club common: Terrén común dog_park: Parque pa perros fishing: Área de pesca - fitness_centre: Centru de fitness + fitness_centre: Ximnasiu (fitness) fitness_station: Ximnasiu garden: Xardín golf_course: Campu de golf - horse_riding: Equitación + horse_riding: Hípica ice_rink: Pista de xelu marina: Puertu deportivu miniature_golf: Mini golf nature_reserve: Reserva natural park: Parque - pitch: Campu deportivu + pitch: Campu de deportes playground: Xuegos infantiles recreation_ground: Campu recreativu - resort: Urbanización pa vacaciones + resort: Centru de vacaciones sauna: Sauna - slipway: Rampla de botadura + slipway: Varaderu sports_centre: Centru deportivu stadium: Estadiu swimming_pool: Piscina @@ -668,7 +667,7 @@ ast: pipeline: Tubería tower: Torre works: Fábrica - "yes": Fecho pol home + "yes": Artificial military: airfield: Aeródromu militar barracks: Cuartel @@ -676,25 +675,25 @@ ast: mountain_pass: "yes": Puertu de montaña natural: - bay: Golfu + bay: Badea beach: Playa cape: Cabu cave_entrance: Boca de cueva cliff: Cantil - crater: Crater + crater: Cráter dune: Duna fell: Braña fjord: Fiordu forest: Área forestal geyser: Guéiser glacier: Glaciar - grassland: Prau + grassland: Pradería heath: Berezal hill: Llomba island: Islla land: Tierra - marsh: Llamuerga - moor: Amarradera + marsh: Basa + moor: Granda mud: Barru peak: Picu point: Puntu @@ -705,12 +704,12 @@ ast: sand: Sable scree: Llera scrub: Cotollal - spring: Fonte + spring: Naciente stone: Piedra strait: Estrechu tree: Árbol valley: Valle - volcano: Volcan + volcano: Volcán water: Agua wetland: Llamuerga wood: Viesca @@ -729,12 +728,12 @@ ast: travel_agent: Axencia de viaxes "yes": Oficina place: - allotments: Güertes recreatives + allotments: Güertos recreativos block: Bloque airport: Aeropuertu city: Ciudá country: País - county: Condáu, conceyu + county: Condáu farm: Casería hamlet: Aldea house: Casa @@ -743,17 +742,17 @@ ast: islet: Castru de mar isolated_dwelling: Vivienda aisllada locality: Llocalidá - moor: Amarradera + moor: Granda municipality: Conceyu - neighbourhood: Vecindá + neighbourhood: Barriu postcode: Códigu postal - region: Fastera, provincia + region: Rexón sea: Mar - state: Estáu, comunidá autónoma + state: Estáu o provincia subdivision: Subdivisión - suburb: Barriu + suburb: Suburbiu town: Villa - unincorporated_area: Área ensin conceyu + unincorporated_area: Área ensin incorporar village: Pueblu "yes": Llugar railway: @@ -764,7 +763,7 @@ ast: funicular: Tren funicular halt: Parada de tren historic_station: Estación de ferrocarril históricu - junction: Disvíu de ferrocarril + junction: Encruz ferroviariu level_crossing: Pasu a nivel light_rail: Ferrocarril llixeru miniature: Ferrocarril en miniatura @@ -773,16 +772,16 @@ ast: platform: Andén de ferrocarril preserved: Ferrocarril conserváu proposed: Ferrocarril propuestu - spur: Apartaderu industrial + spur: Ramal ferroviariu station: Estación de tren stop: Apeaderu subway: Metro subway_entrance: Entrada de metro - switch: Aguyes de ferrocarril + switch: Aguya de ferrocarril tram: Tranvía tram_stop: Parada de tranvía shop: - alcohol: Venta de bébores + alcohol: Venta de llicores antiques: Antigüedaes art: Venta d'arte bakery: Panadería @@ -792,41 +791,41 @@ ast: books: Llibrería boutique: Boutique butcher: Carnicería - car: Automóvil + car: Concesionariu car_parts: Repuestos d'automóvil car_repair: Taller d'automóviles carpet: Alfombres - charity: Rastru solidariu + charity: Tienda benéfica chemist: Droguería clothes: Tienda de ropa computer: Tienda d'informática confectionery: Confitería convenience: Alimentación copyshop: Copistería - cosmetics: Perfumería - deli: Tienda gourmet + cosmetics: Tienda de cosmética + deli: Delicatessen department_store: Grandes almacenes - discount: Productos con descuentu + discount: Tienda de descuentos doityourself: Bricolax dry_cleaning: Tintorería electronics: Tienda d'electrónica estate_agent: Axencia inmobiliaria farm: Tienda de casería fashion: Tienda de modes - fish: Pescaos + fish: Pescadería florist: Floristería food: Comestibles funeral_directors: Servicios funerarios furniture: Muebles - gallery: Venta d'arte + gallery: Galería d'arte garden_centre: Xardinería general: Mercancía xeneral gift: Tienda de regalos greengrocer: Frutería - grocery: Frutería + grocery: Tienda d'alimentación hairdresser: Peluquería hardware: Ferretería - hifi: Soníu + hifi: Hi-Fi insurance: Seguros jewelry: Xoyería kiosk: Quioscu @@ -835,29 +834,29 @@ ast: market: Mercáu mobile_phone: Tienda de telefonía móvil motorcycle: Venta de motos - music: Discos + music: Tienda de música newsagent: Prensa optician: Óptica organic: Comida ecolóxica - outdoor: Aire llibre - pet: Paxarería + outdoor: Deportes d'aire llibre + pet: Tienda d'animales pharmacy: Farmacia photo: Fotografía salon: Cuidaos corporales second_hand: Tienda d'oxetos usaos shoes: Zapatería shopping_centre: Centru comercial - sports: Deportes + sports: Tienda de deportes stationery: Papelería supermarket: Supermercáu tailor: Sastrería toys: Xuguetería travel_agency: Axencia de viaxes video: Videu club - wine: Venta de bébores + wine: Venta de llicores "yes": Tienda tourism: - alpine_hut: Refuxu de montaña + alpine_hut: Refuxu de monte apartment: Apartamentu artwork: Obra d'arte attraction: Interés turísticu @@ -867,13 +866,13 @@ ast: caravan_site: Camping pa caravanes chalet: Xalé gallery: Galería - guest_house: Agospiamientu + guest_house: Pensión hostel: Albergue hotel: Hotel information: Información motel: Motel museum: Muséu - picnic_site: Área recreativa + picnic_site: Área de picnic theme_park: Parque temáticu viewpoint: Mirador zoo: Zoo @@ -881,11 +880,11 @@ ast: culvert: Cañu "yes": Túnel waterway: - artificial: Vía acuática artificial + artificial: Vía d'agua artificial boatyard: Astilleru canal: Canal dam: Presa - derelict_canal: Canal abandonáu + derelict_canal: Canal abandonada ditch: Riega dock: Dársena drain: Desagüe @@ -896,7 +895,7 @@ ast: river: Ríu stream: Regatu wadi: Riera - waterfall: Saltu d'agua + waterfall: Tabayón weir: Banzáu "yes": Cursu d'agua admin_levels: @@ -909,9 +908,9 @@ ast: level10: Frontera de barriu description: title: - osm_nominatim: Llugar de OpenStreetMap + osm_nominatim: Llugar según OpenStreetMap Nominatim - geonames: Llugar de GeoNames + geonames: Llugar según GeoNames types: cities: Ciudaes towns: Villes @@ -925,27 +924,27 @@ ast: home: Dir al llugar d'entamu logout: Salir log_in: Aniciar sesión - log_in_tooltip: Entrar nuna cuenta esistente - sign_up: Dase d'alta + log_in_tooltip: Entrar con una cuenta esistiente + sign_up: Rexistrase start_mapping: Principiar col mapéu - sign_up_tooltip: Crear una cuenta pa editar + sign_up_tooltip: Crea una cuenta pa editar edit: Editar history: Historial export: Esportar data: Datos export_data: Esportar datos gps_traces: Traces GPS - gps_traces_tooltip: Xestionar traces de GPS + gps_traces_tooltip: Alministrar traces de GPS user_diaries: Diarios d'usuariu user_diaries_tooltip: Ver los diarios d'usuariu edit_with: Editar con %{editor} - tag_line: El wikimapamundi llibre - intro_header: ¡Bienveníos a OpenStreetMap! + tag_line: El Wiki Mapamundi llibre + intro_header: ¡Afáyate n'OpenStreetMap! intro_text: OpenStreetMap ye un mapa del mundu, creáu por persones como tu y d'usu llibre baxo una llicencia abierta. intro_2_create_account: Crear una cuenta d'usuariu - partners_html: L'agospiamientu tien l'encontu de %{ucl}, %{ic} y %{bytemark}, - y otros %{partners}. + partners_html: L'agospiamientu tien l'encontu de %{ucl}, %{bytemark}, %{ic}, y + otros %{partners}. partners_ucl: UCL partners_ic: Imperial College de Londres partners_bytemark: Bytemark Hosting @@ -988,22 +987,22 @@ ast: href="http://opendatacommons.org/licenses/odbl/">Open Data Commons Open Database License (ODbL) de la Fundación OpenStreetMap (OSMF). - intro_2_html: Pues copiar, distribuir, tresmitir y adautar los nuesos datos - de mou llibre, mentanto des reconocimientu a OpenStreetMap y a los sos collaboradores. - Si camudes o creas conteníu sobre los nuesos datos, namái podrás distribuir + intro_2_html: Puedes copiar, distribuir, tresmitir y adautar los nuesos datos + de mou llibre, mentanto deas reconocimientu a OpenStreetMap y a los sos collaboradores. + Si camudes o crees conteníu sobre los nuesos datos, namái podrás distribuir el resultáu baxo la mesma llicencia. El códigu - llegal completu t'esplica los tos drechos y obligaciones. + llegal completu t'esplica los tos drechos y obligaciones. intro_3_html: La cartografía de los mosaicos del mapa y la nuesa documentación, tan llicenciaos baxo la llicencia Creative Commons Reconocimientu-CompartirIgual 2.0 (CC-BY-SA). credit_title_html: Cómo dar reconocimientu a OpenStreetMap - credit_1_html: Requerimos qu'uses el créditu “© Collaboradores d'OpenStreetMap”. + credit_1_html: Riquimos qu'uses el créditu “© Collaboradores d'OpenStreetMap”. credit_2_html: |- - Tamién debes dexar claro que los datos tan disponibles baxo la llicencia Open Database License (ODbL), y si utilices los nuesos mosaicos de mapa, que la cartografía tien llicencia CC-BY-SA. Pues facelo enllazando a esta páxina de drechos d'autor. - Alternativamente, y como requisitu si distribúis OSM en forma de datos, pues nomar y enllazar direutamente a les llicencies. En medios onde los enllaces nun seyan posibles (por exemplu, obres impreses), te suxerimos dirixir a los llectores a openstreetmap.org (espandiendo «OpenStreetMap» a esta dirección completa, seique), a opendatacommons.org y, si ye'l casu, a creativecommons.org. + Tamién tienes de dexar claro que los datos tan disponibles baxo la llicencia Open Database License (ODbL), y si utilices los nuesos mosaicos de mapa, que la cartografía tien llicencia CC BY-SA. Pues facelo enllazando a esta páxina de drechos d'autor. + Alternativamente, y como requisitu si distribues OSM en forma de datos, pues nomar y enllazar direutamente a les llicencies. En medios onde los enllaces nun seyan posibles (por exemplu, obres imprentaes), suxerímoste dirixir a los llectores a openstreetmap.org (espandiendo 'OpenStreetMap' a esta dirección completa, seique), a opendatacommons.org y, si ye'l casu, a creativecommons.org. credit_3_html: |- Nun mapa electrónicu navegable, los créditos tendríen d'apaecer na esquina del mapa. - Por exemplu: + Por casu: attribution_example: alt: Exemplu de cómo dar reconocimientu a OpenStreetMap nuna páxina web title: Exemplu de reconocimientu @@ -1077,11 +1076,11 @@ ast: al usu de les marques, mándales al grupu de trabayu sobro llicencies. welcome_page: - title: ¡Bienveníu! + title: ¡Afáyate! introduction_html: |- - Bienveníu a OpenStreetMap, el mapa del mundu llibre y editable. Agora - qu'anició sesión, yá ta preparáu editar mapes. Esta ye una guía rápida - de les coses más importantes que necesita saber. + Afáyate n'OpenStreetMap, el mapa del mundu llibre y editable. Agora + qu'aniciasti sesión, yá puedes editar mapes. Esta ye una guía rápida + de les coses más importantes que necesites saber. whats_on_the_map: title: Qué hai nel Mapa on_html: |- @@ -1089,8 +1088,8 @@ ast: incluye millones d'edificios, carreteres, y otros detalles de llugares. Puedes poner nel mapa cualquier carauterística del mundu real que t'interese. off_html: |- - Lo que nun incluye son datos suxetivos como calificaciones, carauterístiques históriques o hipotétiques, y datos de fontes con drechos d'autor. Si nun tien - un permisu especial, nun copie de mapes en llinia o en papel. + Lo que nun incluye son datos suxetivos como calificaciones, carauterístiques históriques o hipotétiques, y datos de fontes con drechos d'autor. Si nun tienes + un permisu especial, nun copies de mapes en llinia o en papel. basic_terms: title: Términos básicos pa facer mapes paragraph_1_html: OpenStreetMap tien cierta xíriga de so. Estes son delles pallabres @@ -1144,8 +1143,8 @@ ast: other_concerns: title: Otres preocupaciones explanation_html: |- - Si tien dalguna preocupación tocante a cómo tan usándose los nuesos datos o tocante al conteníu, consulte la - páxina de drechos d'autor pa más información llegal, o comuníquese col grupu de trabayu de la OSMF afayadizu. + Si tienes dalguna preocupación tocante a cómo tan usándose los nuesos datos o tocante al conteníu, consulta la + páxina de drechos d'autor pa más información llegal, o comunícate col grupu de trabayu de la OSMF afayadizu. help_page: title: Algamar ayuda introduction: OpenStreetMap tien dellos recursos p'aprender sobro'l proyeutu, @@ -1198,19 +1197,23 @@ ast: qu'OSM ye precisu y ta anováu. community_driven_title: Dirixíu pola comunidá community_driven_html: |- - La comunidá d'OpenStreetMap ye diversa, apasionada, i crez cada día. Ente los nuesos collaboradores hai cartógrafos entusiastes, profesionales de GIS, inxenieros que xestionen los sirvidores d'OSM, voluntarios que faen mapes de les zones afeutaes por desastres, y muncho más. - Pa saber más tocante a la comunidá, vea los diarios d'usuarios, los blogs de la comunidá, y la páxina web de la Fundación OSM. + La comunidá d'OpenStreetMap ye diversa, apasionada, y medra caldía. + Ente los collaboradores hai cartógrafos entusiastes, profesionales de GIS, + inxenieros que xestionen los sirvidores d'OSM, voluntarios que + faen mapes de les zones afeutaes por desastres, y muncho más. + Pa saber más tocante a la comunidá, ver los diarios d'usuarios, los blogs de la comunidá, y la páxina web de la Fundación OSM. open_data_title: Datos abiertos - open_data_html: 'OpenStreetMap son datos abiertos: tien llibertá d''usalos - pa cualquier propósitu, siempre que-y dea créditu a OpenStreetMap y los sos - collaboradores. Si altera o usa como base los datos de ciertes maneres, sólo - pue distribuir el resultáu baxo la mesma llicencia. Vea la páxina - de copyright y llicencia pa más detalles.' + open_data_html: |- + OpenStreetMap son datos abiertos: tienes la llibertá d'usalos pa cualquier + propósitu, siempre que-y deas créditu a OpenStreetMap y los sos collaboradores. + Si alteres o uses como base los datos de determinaes maneres, sólo puedes distribuir + el resultáu baxo la mesma llicencia. Ver la páxina de copyright y llicencia + pa más detalles. legal_title: Llegal legal_html: "Esti sitiu y munchos otros servicios rellacionaos xestiónalos formalmente la \nFundación OpenStreetMap (OSMF) \nnel nome de la comunidá. L'usu de tolos servicios remanaos pola OSMF tán suxetos - les nueses polítiques + a les nueses polítiques d'usu aceptable y la nuesa política de privacidá\n
    \nComunícate cola OSMF \nsi tienes entrugues o problemes relativos a les llicencies, @@ -1385,6 +1388,7 @@ ast: date: Data reply_button: Contestar unread_button: Marcar como non lleíu + delete_button: Desaniciar back: Anterior to: Pa wrong_user: Tas coneutáu como `%{user}' pero'l mensaxe que quies lleer nun s'unvió @@ -1443,7 +1447,7 @@ ast: key: table: entry: - motorway: Autopista + motorway: Autoestrada main_road: Carretera principal trunk: Carretera nacional primary: Carretera primaria @@ -1658,7 +1662,7 @@ ast: aceutalos, pero debes conocelos. oauth: oauthorize: - title: Autorizar l'accesu a la so cuenta + title: Autorizar l'accesu a la to cuenta request_access: L'aplicación %{app_name} ta solicitando accesu a la to cuenta, %{user}. Por favor, revisa si quies que l'aplicación tenga les capacidaes darréu. Puedes esbillar tantes o tan poques como te preste. @@ -2323,10 +2327,10 @@ ast: unhide_comment: amosar notes: new: - intro: ¿Alcontró un error o falta daqué? Informe a otros mapeadores pa que - podamos igualo. Mueva'l marcador a la posición correuta y escriba una nota - pa esplicar el problema. (Por favor, nun escriba información personal o - información de mapes con drechos d'autor o de llistes de teléfonos). + intro: ¿Alcontrasti un error o falta daqué? Informa a otros mapeadores pa + que podamos igualo. Mueve'l marcador a la posición correuta y escribi una + nota pa esplicar el problema. (Por favor, nun escribas información personal + o información de mapes con drechos d'autor o de llistes de teléfonos). add: Amestar nota show: anonymous_warning: Esta nota incluye comentarios d'usuarios anónimos que tendríen diff --git a/config/locales/az.yml b/config/locales/az.yml index 5345f315d..e819673e5 100644 --- a/config/locales/az.yml +++ b/config/locales/az.yml @@ -266,7 +266,6 @@ az: search: title: latlon: Daxili nəticələr - us_postcode: Geocoder.us nəticələri uk_postcode: NPEMap / FreeThe Postcode nəticələri ca_postcode: Geocoder.CA nəticələri diff --git a/config/locales/be-Tarask.yml b/config/locales/be-Tarask.yml index 8be10b30b..2b2201668 100644 --- a/config/locales/be-Tarask.yml +++ b/config/locales/be-Tarask.yml @@ -284,7 +284,6 @@ be-Tarask: search: title: latlon: Вынікі з Internal - us_postcode: Вынікі з Geocoder.us uk_postcode: Вынікі з NPEMap / FreeThe Postcode ca_postcode: Вынікі з Geocoder.CA diff --git a/config/locales/be.yml b/config/locales/be.yml index f9619c73e..a60883a64 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -387,7 +387,6 @@ be: search: title: latlon: Вынікі з Internal - us_postcode: Вынікі з Geocoder.us uk_postcode: Вынінкі з NPEMap / FreeThe Postcode ca_postcode: Вынікі з Geocoder.CA @@ -953,7 +952,7 @@ be: для выкарыстання на ўмовах адкрытай ліцэнзіі. intro_2_create_account: Стварыць рахунак удзельніка partners_html: Хостынг падтрымліваецца %{ucl}, %{ic} і %{bytemark}, і іншымі %{partners}. - partners_ucl: UCL VR-цэнтр + partners_ucl: UCL partners_ic: Imperial College London partners_bytemark: Bytemark Hosting partners_partners: партнёрамi @@ -1025,10 +1024,10 @@ be: Даведайцеся больш аб выкарыстанні нашых дадзеных і аб тым, як паказваць нас як крыніцу паходжання дадзеных на старонцы OSMF Licence і адказах на прававыя пытанні. more_2_html: Хоць дадзеныя OpenStreetMap з'яўляецца адкрытымі дадзенымі, мы - не ў стане прадастаўляць бясплатны картаграфічны API для іншых распрацоўнікаў. - Азнаёмціся з нашымі Правіламі - выкарыстання API, Правіламі - выкарыстання графічных карт і Правіламі + не ў стане прадастаўляць бясплатны картаграфічны API для іншых распрацоўшчыкаў. + Азнаёмцеся з нашымі Правіламі + выкарыстання API, Правіламі + выкарыстання графічных карт і Правіламі выкарыстання сэрвісу Nominatim. contributors_title_html: Нашы ўдзельнікі contributors_intro_html: 'Нашымі ўдзельнікамі з''яўляюцца тысячы людзей. Мы @@ -1241,6 +1240,7 @@ be: footer_html: Вы можаце таксама прачытаць паведамленне на %{readurl}, і вы можаце адказаць на %{replyurl} friend_notification: + hi: Прывітанне, %{to_user}, subject: '[OpenStreetMap] %{user} дадаў вас у спіс сваіх сяброў' had_added_you: '%{user} пасябраваў з Вамі на OpenStreetMap.' see_their_profile: Вы можаце прагледзець профіль на %{userurl} і дадаць, як @@ -1325,6 +1325,7 @@ be: Заўвага каля %{place}.' details: Больш падрабязна пра ўвагу можна прачытаць на %{url}. changeset_comment_notification: + hi: Прывітанне, %{to_user}, greeting: Прывітанне, commented: subject_own: '[OpenStreetMap] %{commenter} пракаментаваў адзін з вашых набораў @@ -1338,6 +1339,8 @@ be: partial_changeset_with_comment: з каментаром '%{changeset_comment}' partial_changeset_without_comment: без каментароў details: Дадатковыя звесткі аб наборы зьменаў можна знайсці ў %{url}. + unsubscribe: Каб адпісацца ад абнаўленняў гэтага пакета правак наведайце %{url} + і націсніце кнопку "Адпісацца". message: inbox: title: Уваходныя @@ -1399,6 +1402,7 @@ be: date: Дата reply_button: Адказаць unread_button: Адзначыць, як непрачытанае + delete_button: Выдаліць back: Назад to: Каму wrong_user: Вы ўвайшлі ў сістэму як `%{user}', але паведамленне, якое Вы жадаеце @@ -1466,6 +1470,9 @@ be: track: Палявая дарога bridleway: Дарога для коней cycleway: Веласіпедная дарожка + cycleway_national: Нацыянальная веладарожка + cycleway_regional: Рэгіянальная веладарожка + cycleway_local: Веладарожка мясцовага значэння footway: Пешаходная дарожка rail: Чыгунка subway: Метро @@ -1657,6 +1664,8 @@ be: require_moderator: not_a_moderator: Вам неабходна быць мадэратарам для выканання гэтага дзеяння. setup_user_auth: + blocked_zero_hour: У вас ёсць тэрміновае паведамленне на сайце OpenStreetMap. + Вам трэба прачытаць паведамленне, перш чым вы зможаце захаваць вашы змены. blocked: Ваш доступ да API быў заблакаваны. Калі ласка, ўвайдзіце ў вэб-інтэрфейс, каб даведацца больш. need_to_see_terms: Ваш доступ да API часова прыпынены. Калі ласка, ўвайдзіце @@ -1687,6 +1696,8 @@ be: invalid: Токен аўтарызацыі не сапраўдны. revoke: flash: Вы адклікалі токен для дастасавання %{application} + permissions: + missing: Вы не дазволілі праграме атрымаць доступ да гэтай функцыі oauth_clients: new: title: Зарэгістраваць новае дастасаванне @@ -1792,6 +1803,9 @@ be: github: title: Уваход праз GitHub alt: Увайсці праз уліковы запіс GitHub + wikipedia: + title: Увайсці праз Вікіпедыю + alt: Уваход з выкарыстаннем рахунку ў Вікіпедыі yahoo: title: Уваход праз Yahoo alt: Уваход праз Yahoo OpenID @@ -2196,6 +2210,8 @@ be: helper: time_future: Заканчваецца праз %{time}. until_login: Актыўная да моманту ўваходу ўдзельніка ў сістэму. + time_future_and_until_login: Заканчваецца праз %{time} і пасля таго, як карыстальнік + увойдзе ў сістэму. time_past: Скончылася %{time} таму. blocks_on: title: Блакіроўкі для %{name} @@ -2299,6 +2315,7 @@ be: header: Слаі карты notes: Заўвагі на карце data: Картаграфічныя дадзеныя + gps: Агульныя GPS-сляды overlays: Уключыць накладкі для ліквідацыі памылак карты title: Слаі copyright: © OpenStreetMap contributors @@ -2337,16 +2354,19 @@ be: edit_help: Перамясціце карту і наблізце месца, якое вы хочаце рэдагаваць, затым націсніце тут. directions: + ascend: Угору engines: - graphhopper_bicycle: Ровар (GraphHopper) - graphhopper_foot: Пешаход (GraphHopper) - mapquest_bicycle: Ровар (MapQuest) + graphhopper_bicycle: Веласіпед (GraphHopper) + graphhopper_car: Аўтамабіль (GraphHopper) + graphhopper_foot: Пешшу (GraphHopper) + mapquest_bicycle: Веласіпед (MapQuest) mapquest_car: Аўтамабіль (MapQuest) - mapquest_foot: Пешаход (MapQuest) + mapquest_foot: Пешшу (MapQuest) osrm_car: Аўтамабіль (OSRM) mapzen_bicycle: Веласіпед (Mapzen) mapzen_car: Аўтамабіль (Mapzen) mapzen_foot: Пешшу (Mapzen) + descend: Уніз directions: Маршрут distance: Адлегласць errors: @@ -2355,11 +2375,21 @@ be: instructions: continue_without_exit: Працягвайце рух па %{name} slight_right_without_exit: Плаўна павярніце направа на %{name} + offramp_right_without_exit: Павярніце направа на з'езд да %{name} + onramp_right_without_exit: Павярніце направа на з'езд да %{name} + endofroad_right_without_exit: У канцы дарогі павярніце направа на %{name} + merge_right_without_exit: Перастройцеся ўправа на %{name} + fork_right_without_exit: На развілцы павярніце направа на %{name} turn_right_without_exit: Павярніце направа на %{name} sharp_right_without_exit: Рэзка павярніце направа на %{name} uturn_without_exit: Развярніцеся на %{name} sharp_left_without_exit: Рэзка павярніце налева на %{name} turn_left_without_exit: Павярніце налева на %{name} + offramp_left_without_exit: Павярніце налева на з'езд да %{name} + onramp_left_without_exit: Павярніце налева на з'езд да %{name} + endofroad_left_without_exit: У канцы дарогі павярніце налева на %{name} + merge_left_without_exit: Перастройцеся ўлева на %{name} + fork_left_without_exit: На развілцы павярніце налева на %{name} slight_left_without_exit: Плаўна павярніце налева на %{name} via_point_without_exit: (праз кропку) follow_without_exit: Рухайцеся па %{name} @@ -2371,6 +2401,11 @@ be: against_oneway_without_exit: Рухайцеся супраць аднабаковага руху па %{name} end_oneway_without_exit: Канец аднабаковага руху на %{name} roundabout_with_exit: Пакіньце кальцавую развязку праз выезд %{exit} на %{name} + turn_left_with_exit: На кругавой развязцы павярніце налева на %{name} + slight_left_with_exit: На кругавой развязцы плаўна павярніце налева на %{name} + turn_right_with_exit: На кругавой развязцы павярніце направа на %{name} + slight_right_with_exit: На кругавой развязцы плаўна павярніце направа на %{name} + continue_with_exit: На кругавой развязцы працягвайце рух прама на %{name} unnamed: без назвы courtesy: Маршрут прадастаўлены %{link} time: Час @@ -2381,6 +2416,13 @@ be: nothing_found: Аб’екты не знойдзены error: 'Памылка сувязі з %{server}: %{error}' timeout: Тайм-аўт падключэння да %{server} + context: + directions_from: Маршрут адсюль + directions_to: Маршрут сюды + add_note: Дадаць заўвагу тут + show_address: Паказаць адрас + query_features: Пошук аб’ектаў + centre_map: Цэнтраваць карту redaction: edit: description: Апісанне diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 099cf7a5d..56547d363 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -6,6 +6,7 @@ # Author: MrPanyGoff # Author: Plamen # Author: Ricordo.tenerissimo +# Author: ShockD # Author: StanProg # Author: Vodnokon4e # Author: АдмиралАнимЕ @@ -25,6 +26,7 @@ bg: node: Възел notifier: Известител old_node: Стар възел + old_relation: Стара релация relation: Релация relation_member: Член на релация relation_tag: Таг на релация @@ -101,8 +103,8 @@ bg: changeset: title: 'Списък с промени: %{id}' belongs_to: Автор - node: Точки (%{count}) - node_paginated: Точки (%{x}-%{y} от %{count}) + node: Възли (%{count}) + node_paginated: Възли (%{x}-%{y} от %{count}) way: Пътища (%{count}) way_paginated: Пътища (%{x}-%{y} от общо %{count}) relation: Релации (%{count}) @@ -114,12 +116,12 @@ bg: join_discussion: Впишете се, за да се присъедините към обсъждането discussion: Обсъждане node: - title: 'Точка: %{name}' + title: 'Възел: %{name}' history_title: 'История на точка: %{name}' way: title: 'Път: %{name}' history_title: 'История на пътя: %{name}' - nodes: Точки + nodes: Възли also_part_of: one: част от път %{related_ways} other: част от пътища %{related_ways} @@ -143,7 +145,7 @@ bg: way: път relation: релация changeset: списък с промени - note: Бележка + note: бележка timeout: type: node: възел @@ -162,6 +164,8 @@ bg: loading: Зареждане... tag_details: tags: Етикети + wikidata_link: Обектът %{page} в Уикиданни + wikipedia_link: Статията %{page} в Уикипедия telephone_link: Позвънете на %{phone_number} note: title: 'Бележка: %{id}' @@ -188,9 +192,13 @@ bg: area: Област list: title: Списък с промени + title_user: Списък с промени на %{user} + title_friend: Списъци с промени на Ваши приятели + title_nearby: Списъци с промени от потребители наблизо empty: Няма намерени списъци с промени. empty_area: Няма списъци с промени в този район. empty_user: Няма списъци с промени от този потребител. + no_more: Не са намерени повече списъци с промени. load_more: Зареждане на още rss: commented_at_html: Обновено преди %{when} @@ -239,7 +247,7 @@ bg: hide_link: Скриване на този пост confirm: Потвърди diary_comment: - hide_link: Скрий този коментар + hide_link: Скриване на коментара confirm: Потвърждаване location: location: 'Местоположение:' @@ -284,7 +292,6 @@ bg: search: title: latlon: Вътрешни резултати - us_postcode: Резултати от Geocoder.us uk_postcode: Резултати от NPEMap / FreeThe Postcode ca_postcode: Резултати от Geocoder.CA @@ -300,7 +307,9 @@ bg: cable_car: Кабинков лифт chair_lift: Седалков лифт aeroway: + gate: Врата helipad: Вертолетна площадка + runway: Писта taxiway: Път за рулиране terminal: Терминал amenity: @@ -313,12 +322,16 @@ bg: bench: Пейка bicycle_parking: Паркинг за велосипеди bicycle_rental: Велосипеди под наем + biergarten: Бирария на открито + boat_rental: Наем на лодки + brothel: Бордел bureau_de_change: Обменно бюро bus_station: Автобусна спирка cafe: Кафене car_rental: Коли под наем car_wash: Автомивка casino: Казино + charging_station: Зарядна станция cinema: Кино clinic: Поликлиника clock: Часовник @@ -330,6 +343,7 @@ bg: doctors: Лекари dormitory: Пансион drinking_water: Питейна вода + driving_school: Автошкола embassy: Посолство emergency_phone: Телефон за спешни повиквания fast_food: Заведения за бързо хранене @@ -351,6 +365,7 @@ bg: nightclub: Нощен клуб office: Офис parking: Паркинг + parking_entrance: Вход на паркинг pharmacy: Аптека place_of_worship: Място за поклонение police: Полиция @@ -403,12 +418,12 @@ bg: tailor: Шивач "yes": Работилница emergency: - ambulance_station: Пожарна + ambulance_station: Станция за линейки defibrillator: Дефибрилатор landing_site: Място за аварийно кацане phone: Телефон за спешни повиквания highway: - abandoned: Изоставена железопътна линия + abandoned: Изоставена магистрала bridleway: Конен път bus_stop: Автобусна спирка construction: Магистрала в строеж @@ -436,13 +451,14 @@ bg: speed_camera: Камера за контрол на скоростта steps: Стълбище street_lamp: Улична лампа - track: Полски път - trunk: Скоростен път - trunk_link: Скоростен път + track: Селски път + traffic_signals: Светофар + trunk: Междуградски път + trunk_link: Междуградски път unsurfaced: Път без настилка "yes": Път historic: - archaeological_site: Археологическа зона + archaeological_site: Разкопки battlefield: Бойно поле boundary_stone: Граничен камък building: Историческа сграда @@ -456,7 +472,7 @@ bg: house: Къща icon: Икона manor: Имение - memorial: Паметник + memorial: Мемориал mine: Рудник monument: Паметник roman_road: Римски път @@ -465,6 +481,8 @@ bg: tomb: Гробница tower: Кула wreck: Потънал кораб + junction: + "yes": Кръстовище landuse: allotments: Градини basin: Басейн @@ -498,7 +516,7 @@ bg: fitness_centre: Фитнес център garden: Градина golf_course: Игрище за голф - horse_riding: Конна езда + horse_riding: Конна база ice_rink: Ледена пързалка marina: Пристанище за лодки miniature_golf: Мини-голф @@ -542,7 +560,7 @@ bg: peak: Връх reef: Риф rock: Скала - saddle: Седло + saddle: Седловина sand: Пясък spring: Ручей stone: Камък @@ -550,7 +568,7 @@ bg: valley: Долина volcano: Вулкан water: Вода - wood: Дърво + wood: Гора office: accountant: Счетоводител architect: Архитект @@ -588,12 +606,13 @@ bg: railway: abandoned: Изоставена железопътна линия construction: Железопътна линия в строеж + disused: Изоставена ж.п. линия disused_station: изоставена гара halt: Железопътна спирка historic_station: Гара с историческо значение junction: Железопътен възел level_crossing: Прелез - light_rail: Бърз трамвай + light_rail: Лека железница monorail: Монорелсов път narrow_gauge: Теснолинейка platform: Железопътна платформа @@ -605,14 +624,14 @@ bg: tram_stop: Трамвайна спирка shop: antiques: Антики - art: Магазин на изкуствата + art: Арт магазин bakery: Пекарна beauty: Салон за красота beverages: Магазин за напитки bicycle: Магазин за велосипеди books: Книжарница boutique: Бутик - butcher: Месарница + butcher: Месар car: Автосалон car_parts: Авточасти car_repair: Автосервиз @@ -629,7 +648,7 @@ bg: general: Смесен магазин gift: Магазин за подаръци greengrocer: Плод и зеленчук - grocery: Бакалия + grocery: Магазин за хранителни стоки hairdresser: Фризьорски салон insurance: Застраховане jewelry: Бижутериен магазин @@ -654,12 +673,12 @@ bg: tourism: apartment: Апартамент artwork: Произведения на изкуството - chalet: Хижа + chalet: Бунгало gallery: Галерия guest_house: Къща за гости hostel: Хостел hotel: Хотел - information: Сведения + information: Информация motel: Мотел museum: Музей picnic_site: Място за пикник @@ -669,7 +688,7 @@ bg: "yes": Тунел waterway: canal: Канал - dam: Яз + dam: Язовирна стена river: Река waterfall: Водопад admin_levels: @@ -682,11 +701,14 @@ bg: level10: Граница на предградията description: types: + towns: Градове places: Места results: no_results: Не бяха открити резултати more_results: Повече резултати layouts: + logo: + alt_text: Лого на OpenStreetMap home: Моят дом logout: Излизане log_in: Влизане @@ -700,17 +722,19 @@ bg: export_data: Изнасяне на данни gps_traces: GPS-следи gps_traces_tooltip: Управление на GPS-следи - user_diaries: Дневник + user_diaries: Потребителски дневник user_diaries_tooltip: Дневници на потребители edit_with: Редактиране с %{editor} tag_line: Свободна Wiki-карта на света intro_header: Добре дошли в OpenStreetMap! intro_2_create_account: Създаване на сметка + partners_ucl: UCL partners_partners: партньори help: Помощ about: За проекта copyright: Авторски права community: Общност + foundation: Фондация make_a_donation: text: Направете дарение learn_more: Научете повече @@ -726,6 +750,9 @@ bg: mapping_link: картографиране legal_babble: title_html: Авторски права и лиценз + contributors_fr_html: |- + Франция: Съдържа данни от + Главната данъчна дирекция. infringement_title_html: Нарушаване на авторските права trademarks_title_html: Търговски марки trademarks_1_html: OpenStreetMap и логото с лупата са регистрирани търговски @@ -743,6 +770,8 @@ bg: fixthemap: how_to_help: title: Как да помогна + join_the_community: + title: Присъединете са към общността help_page: welcome: title: Добре дошли в OSM @@ -750,6 +779,7 @@ bg: title: Наръчник за начинаещи help: url: https://help.openstreetmap.org/ + title: help.openstreetmap.org mailing_lists: title: Пощенски списъци forums: @@ -764,6 +794,7 @@ bg: about_page: next: Следващ legal_title: Правни въпроси + partners_title: Партньори notifier: diary_comment_notification: hi: Здравейте %{to_user}, @@ -797,6 +828,8 @@ bg: note_comment_notification: anonymous: Анонимен потребител greeting: Здравейте, + commented: + subject_other: '[OpenStreetMap] %{commenter} коментира бележка, която ви интересува' changeset_comment_notification: hi: Здравейте %{to_user}, greeting: Здравейте, @@ -828,6 +861,7 @@ bg: title: Изпратете съобщение send_message_to: Изпратете ново съобщение на %{name} subject: Тема + body: Текст send_button: Изпращане message_sent: Съобщението е изпратено no_such_message: @@ -850,6 +884,7 @@ bg: date: Дата reply_button: Отговор unread_button: Отбелязване като непрочетено + delete_button: Изтриване back: Назад to: До sent_message_summary: @@ -858,6 +893,8 @@ bg: deleted: Съобщението беше изтрито site: index: + permalink: Постоянна връзка + shortlink: Къса връзка createnote: Добавяне на бележка sidebar: search_results: Резултати от търсенето @@ -951,6 +988,7 @@ bg: filename: 'Име на файл:' download: сваляне uploaded_at: 'Качени:' + points: 'Точки:' map: карта edit: редактиране owner: 'Собственик:' @@ -976,6 +1014,7 @@ bg: view: pending: Обработва се filename: 'Име на файл:' + download: изтегляне map: карта edit: редактиране owner: 'Собственик:' @@ -992,6 +1031,9 @@ bg: view_map: Вижте на картата edit: редактиране edit_map: Редактиране на картата + public: ПУБЛИЧНО + private: ЧАСТНО + trackable: ПРОСЛЕДИМО by: от in: в map: карта @@ -999,6 +1041,8 @@ bg: public_traces: Публични GPS-следи your_traces: Вашите GPS-следи public_traces_from: Публични GPS-следи от потребител %{user} + description: + description_without_count: GPX-файл от %{user} oauth: oauthorize: allow_write_api: промени картата. @@ -1089,6 +1133,7 @@ bg: no_such_user: title: Няма такъв потребител heading: Потребителят %{user} не съществува + deleted: изтрито view: my edits: Mоите редакции my traces: Моите следи @@ -1108,15 +1153,21 @@ bg: latest edit: 'Последна редакция %{ago}:' email address: 'Електронна поща:' created from: 'Създадено от:' + status: 'Състояние:' + spam score: 'Оценка за спам:' description: Описание user location: Местоположение settings_link_text: настройки your friends: Вашите приятели no friends: Все още нямате добавени приятели. km away: '%{count} км от вас' + nearby users: Други потребители наблизо comments: Коментари create_block: Блокиране на този потребител delete_user: Изтриване на този потребител + confirm: Потвърдете + popup: + friend: Приятел account: title: Редакция на профил my settings: Моите настройки @@ -1160,6 +1211,7 @@ bg: success: '%{name} беше премахнат от списъка с приятелите.' list: title: Потребители + heading: Потребители user_role: grant: confirm: Потвърждаване @@ -1182,6 +1234,7 @@ bg: entry: comment: Коментар mine: + creator: Автор ago_html: преди %{when} javascripts: share: @@ -1231,6 +1284,8 @@ bg: notes: new: add: Добавяне на бележка + show: + comment: Коментар directions: engines: graphhopper_bicycle: Велосипед (GraphHopper) @@ -1254,6 +1309,8 @@ bg: destination_without_exit: Пристигнахте на местоназначението unnamed: неименуван път time: Време + query: + node: Възел context: add_note: Добавете бележка тук ... diff --git a/config/locales/bn.yml b/config/locales/bn.yml index 4ed4b2c7f..0598c5157 100644 --- a/config/locales/bn.yml +++ b/config/locales/bn.yml @@ -379,7 +379,6 @@ bn: search: title: latlon: অভ্যন্তরীণ থেকে ফলাফল - us_postcode: Geocoder.usNPEMap / FreeThe Postcode থেকে ফলাফল ca_postcode: Geocoder.CA থেকে ফলাফল @@ -408,6 +407,7 @@ bn: atm: এটিএম bank: ব্যাংক bar: বার + bbq: বিবিকিউ bench: বেঞ্চ bicycle_parking: সাইকেল পার্কিং bicycle_rental: ভাড়ার সাইকেল @@ -475,6 +475,7 @@ bn: reception_area: অভ্যর্থন এলাকা restaurant: রেঁস্তোরা retirement_home: অবসর গৃহ + sauna: বাষ্পস্নান school: বিদ্যালয় shelter: আশ্রয় shop: দোকান @@ -672,6 +673,7 @@ bn: volcano: আগ্নেয়গিরি water: পানি wetland: জলাভূমি + wood: কাঠ office: accountant: হিসাবরক্ষক administrative: প্রশাসন @@ -740,6 +742,7 @@ bn: books: বইয়ের দোকান butcher: মাংসবিক্রেতা carpet: কার্পেটের দোকান + chemist: রাসায়নবিৎ clothes: কাপড়ের দোকান computer: কম্পিউটারের দোকান confectionery: মিষ্টান্নের দোকান @@ -867,7 +870,7 @@ bn: intro_text: ওপেনস্ট্রীটম্যাপ বিশ্বের, একটি মানচিত্র; যা আপনার মতো মানুষের দ্বারা নির্মিত এবং এটি মুক্ত লাইসেন্সের অধীনে বিনামূল্যে ব্যবহারযোগ্য। intro_2_create_account: একটি ব্যবহারকারী অ্যাকাউন্ট তৈরি করুন - partners_html: হোস্টিং %{ucl}, %{ic} ও %{bytemark}, এবং অন্যান্য %{partners} কর্তৃক + partners_html: হোস্টিং %{ucl}, %{bytemark}, %{ic}, এবং অন্যান্য %{partners} কর্তৃক সমর্থিত। partners_ucl: UCL partners_ic: ইম্পেরিয়াল মহাবিদ্যালয় লন্ডন @@ -906,10 +909,8 @@ bn: title: আরোপণ উদাহরণ more_title_html: আরও খুঁজা হচ্ছে more_1_html: |- - আমাদের উপাত্তের ব্যাবহার, ও কৃতজ্ঞতা স্বীকার সম্পর্কে আরও জানতে, এখানে OSMF Licence page and the community Legal - FAQ পড়ুন। + আমাদের উপাত্ত ব্যবহার, ও আমাদেরকে কৃতিত্ব প্রদানের পদ্ধতি সম্পর্কে জানতে OSMF লাইসেন্সের পাতা দেখুন। contributors_title_html: আমাদের অবদানকারীগণ infringement_title_html: কপিরাইট লঙ্ঘন trademarks_title_html: ট্রেডমার্ক @@ -935,6 +936,7 @@ bn: other_concerns: title: অন্যান্য উদ্বেগ help_page: + title: সাহায্য পান welcome: url: /স্বাগতম title: ওএসএম-এ স্বাগতম @@ -1002,10 +1004,10 @@ bn: note_comment_notification: anonymous: একজন বেনামি ব্যবহারকারী greeting: হাই, - details: টীকাটি সম্পর্কে আরও বিস্তারিত %{url|এখানে} পাওয়া যাবে। + details: টীকাটি সম্পর্কে আরও বিস্তারিত %{url} এ পাওয়া যাবে। changeset_comment_notification: greeting: হাই, - details: পরিবর্তনধার্য সম্পর্কে আরও বিস্তারিত %{url|এখানে} পাওয়া যাবে। + details: পরিবর্তনধার্য সম্পর্কে আরও বিস্তারিত %{url} এ পাওয়া যাবে। message: inbox: title: ইনবক্স @@ -1047,6 +1049,7 @@ bn: date: তারিখ reply_button: প্রত্যুত্তর unread_button: অপঠিত হিসেবে চিহ্নিত করুন + delete_button: অপসারণ back: পিছনে to: প্রাপক sent_message_summary: @@ -1074,7 +1077,7 @@ bn: get_directions_title: দুটি বিন্দুর মধ্যে নির্দেশনী খুঁজুন from: থেকে to: হতে - where_am_i: আমি কোথায়? + where_am_i: এটি কোথায়? where_am_i_title: অনুসন্ধান যন্ত্র ব্যবহার করে বর্তমান অবস্থানটি বর্ণনা করুন submit_text: যাও key: @@ -1371,6 +1374,8 @@ bn: reactivate: পুনঃসক্রিয় comment: মন্তব্য directions: + engines: + graphhopper_car: গাড়ি (GraphHopper) directions: দিক distance: দূরত্ব errors: diff --git a/config/locales/br.yml b/config/locales/br.yml index f28795547..d1218b530 100644 --- a/config/locales/br.yml +++ b/config/locales/br.yml @@ -387,7 +387,6 @@ br: search: title: latlon: Disoc'hoù diwar Internal - us_postcode: Disoc'hoù diwar Geocoder.us uk_postcode: Disoc'hoù diwar NPEMap / FreeThe Postcode ca_postcode: Disoc'hoù diwar Geocoder.CA @@ -954,7 +953,7 @@ br: intro_2_create_account: Krouiñ ur gont implijer partners_html: '%{ucl}, %{ic}, %{bytemark}, ha %{partners} all a ra war-dro an herberc''hiañ.' - partners_ucl: ↓Kreizenn VR an UCL + partners_ucl: ↓"Universiy College" Londrez partners_ic: Skolaj impalaerel Londrez partners_bytemark: ↓Herberc'hiañ Bytemark partners_partners: Kevelourien @@ -1415,6 +1414,7 @@ br: date: Deiziad reply_button: Respont unread_button: Merkañ evel anlennet + delete_button: Diverkañ back: Distreiñ to: Da wrong_user: Kevreet oc'h evel "%{user}", met ar gemennadenn a fell deoc'h lenn @@ -2379,6 +2379,7 @@ br: ascend: Pignat engines: graphhopper_bicycle: Marc'h-houarn (GraphHopper) + graphhopper_car: Karr GraphHopper) graphhopper_foot: Troad (GraphHopper) mapquest_bicycle: Marc'h-houarn (MapQuest) mapquest_car: Karr (MapQuest) diff --git a/config/locales/bs.yml b/config/locales/bs.yml index 7f4e3a8d0..2f2d03731 100644 --- a/config/locales/bs.yml +++ b/config/locales/bs.yml @@ -325,7 +325,6 @@ bs: search: title: latlon: Rezultati sa Internal - us_postcode: Rezultati sa Geocoder.us uk_postcode: Rezultati sa NPEMap / FreeThe Postcode ca_postcode: Rezultati sa Geocoder.CA @@ -859,7 +858,7 @@ bs: intro_2_create_account: Napravite korisnički račun partners_html: Hosting je podržan od strane %{ucl}, %{ic} i %{bytemark}, i drugih %{partners}. - partners_ucl: UCL VR Centar + partners_ucl: UCL partners_ic: Imperial College London partners_bytemark: Bytemark Hosting partners_partners: partnera @@ -1614,16 +1613,16 @@ bs: revoke: administrator: Opozvati pristup za administatora moderator: Opozvati pristup za moderatora - block_history: prikazati dobivene blokade - moderator_history: prikazati date blokade + block_history: Aktivne blokade + moderator_history: Date blokade comments: komentari - create_block: blokirati ovog korisnika - activate_user: aktivirati ovog korisnika - deactivate_user: deaktivirati ovog korisnika - confirm_user: potvrditi ovog korisnika - hide_user: sakriti ovog korisnika - unhide_user: otkriti ovog korisnika - delete_user: izbrisati ovog korisnika + create_block: Blokiraj ovog korisnika + activate_user: Aktiviraj ovog korisnika + deactivate_user: Deaktiviraj ovog korisnika + confirm_user: Potvrdi ovog korisnika + hide_user: Sakrij ovog korisnika + unhide_user: Otkrij ovog korisnika + delete_user: ObriÅ¡i ovog korisnika confirm: Potvrditi friends_changesets: promjena spiska prijatelja friends_diaries: unosi u dnevnik prijatelja diff --git a/config/locales/ca.yml b/config/locales/ca.yml index e23b4f80c..106f2c060 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -224,7 +224,7 @@ ca: telephone_link: Telefona %{phone_number} note: title: 'Nota: %{id}' - new_note: Nova nota + new_note: Nota nova description: Descripció open_title: 'Nota no resolta: #%{note_name}' closed_title: 'Nota resolta #%{note_name}' @@ -282,7 +282,7 @@ ca: full: Discussió sencera diary_entry: new: - title: Nova Entrada de Diari + title: Entrada de diari nova publish_button: Publica list: title: Diaris d'usuari/a @@ -290,7 +290,7 @@ ca: title_nearby: Diaris d'amics propers user_title: Diari de %{user} in_language_title: Entrades de diari en %{language} - new: Nova Entrada de Diari + new: Entrada de diari nova new_title: Redacta una nova entrada al teu diari d'usuari/a no_entries: No hi ha entrades al diari recent_entries: 'Entrades recents al diari:' @@ -412,7 +412,6 @@ ca: search: title: latlon: Resultats propis - us_postcode: Resultats de Geocoder.us uk_postcode: Resultats de NPEMap / FreeThe Postcode ca_postcode: Resultats de Geocoder.CA @@ -1439,6 +1438,7 @@ ca: date: Data reply_button: Respon unread_button: Marca com a no llegit + delete_button: Suprimeix back: Enrere to: Per a wrong_user: Heu iniciat la sessió com a "%{user}", però el missatge que voleu @@ -1990,7 +1990,7 @@ ca: block_history: Blocatges actius moderator_history: Blocatges imposats comments: Comentaris - create_block: Bloqueja aquest usuari + create_block: Bloca aquest usuari activate_user: Activa aquest usuari deactivate_user: Desactiva aquest usuari confirm_user: Confirma aquest usuari @@ -2197,31 +2197,29 @@ ca: s'aturés. tried_waiting: Li he donat una quantitat raonable de temps a l'usuari per a respondre a aquestes comunicacions. - needs_view: L'usuari necessita connectar-se abans que aquest bloqueig es suprimeixi + needs_view: L'usuari necessita connectar-se abans que aquest blocatge es suprimeixi back: Mostra tots els blocs edit: title: Bloc d'edició en %{name} heading: Bloc d'edició en %{name} - reason: La raó per què està sent bloquejat %{name}. Si us plau, ser tan tranquil - i tan raonable com sigui possible, donant amb tant detall com sigui possible - sobre la situació. Tingueu en compte que no tots els usuaris de comprendre - l'argot de la comunitat, així que si us plau, intenti utilitzar termes de - l'home comú. - period: Quant de temps, a partir d'ara, l'usuari es bloqueja des de l'API per - a. + reason: La raó per la qual %{name} està sent blocat. Si us plau, sigueu tan + tranquil i tan raonable com sigui possible, donant tant detall com sigui possible + sobre la situació. Tingueu en compte que no tots els usuaris comprenen l'argot + de la comunitat, així que si us plau, intenteu utilitzar termes comuns. + period: Quant de temps, a partir d'ara, l'usuari tindrà blocat l'accés a l'API. submit: Bloc d'Actualització show: Mostra el bloc back: Mostra tots els blocs - needs_view: L'usuari necessita connectar-se abans que aquest bloqueig es suprimeixi? + needs_view: L'usuari necessita connectar-se abans que aquest blocatge es suprimeixi? filter: block_expired: El bloc ja ha expirat i no es pot editar. block_period: El període de blocatge ha de ser un dels valors seleccionables de la llista desplegable. create: - try_contacting: Si us plau, intentar contactar-se amb l'usuari abans de bloqueig + try_contacting: Si us plau, intentar contactar-se amb l'usuari abans de blocatge d'ells i donar-los un termini raonable per respondre. try_waiting: Si us plau tracti de donar l'usuari d'un termini raonable per respondre - abans de bloqueig d'ells. + abans de blocatge d'ells. flash: Crear un bloc a l'usuari %{name}. update: only_creator_can_edit: Només el moderador que ha creat aquest bloc pot editar-lo. @@ -2268,8 +2266,8 @@ ca: heading: Llista de blocs %{name} empty: '%{name} no ha fet cap blocs encara.' show: - title: '%{block_on} bloquejat per %{block_by}' - heading: '%{block_on} bloquejat per %{block_by}' + title: '%{block_on} blocat per %{block_by}' + heading: '%{block_on} blocat per %{block_by}' time_future: Finalitza en %{time} time_past: Va acabar fa %{time} created: Creat diff --git a/config/locales/cs.yml b/config/locales/cs.yml index f9a9fa35d..f5da185a8 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -410,7 +410,6 @@ cs: search: title: latlon: Výsledky z interní databáze - us_postcode: Výsledky z Geocoder.us uk_postcode: Výsledky z NPEMap / FreeThe Postcode ca_postcode: Výsledky z Geocoder.CA @@ -975,7 +974,7 @@ cs: intro_text: OpenStreetMap je mapa světa, vytvořená lidmi jako vy a volně využitelná pod otevřenou licencí. intro_2_create_account: Vytvořit uživatelský účet - partners_html: Hosting podporují %{ucl}, %{ic} a %{bytemark} a další %{partners}. + partners_html: Hosting podporují %{ucl}, %{bytemark}, %{ic} a další %{partners}. partners_ucl: UCL partners_ic: Imperial College London partners_bytemark: Bytemark Hosting @@ -1039,9 +1038,7 @@ cs: title: Příklad uvedení autorství more_title_html: Další informace more_1_html: O používání naÅ¡ich dat a způsobu uvádění autorství se můžete dočíst - více na licenční stránce OSMF - a v naÅ¡em komunitním Právním - FAQ. + více na licenční stránce OSMF. more_2_html: |- Přestože OpenStreetMap tvoří svobodná data, nemůžeme zdarma poskytovat třetím stranám mapové API. Vizte naÅ¡e Pravidla použití API, Pravidla použití dlaždic a Pravidla použití Nominatimu. @@ -1407,6 +1404,7 @@ cs: date: Datum reply_button: Odpovědět unread_button: Označit jako nepřečtené + delete_button: Smazat back: Zpět to: Komu wrong_user: Jste přihlášeni jako „%{user}“, ale zpráva, kterou si chcete přečíst, diff --git a/config/locales/cy.yml b/config/locales/cy.yml index c90978652..34a89c9d1 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -31,6 +31,8 @@ cy: old_way_node: Nod Hen Ffordd old_way_tag: Tag Hen Ffordd relation: Perthynas + relation_member: Aelod Perthynol + relation_tag: Tag Perthynas session: Sesiwn trace: Dargopïo tracepoint: Pwynt Dargopïo @@ -76,11 +78,18 @@ cy: pass_crypt: Cyfrinair editor: default: (currently %{name}) diofyn + potlatch: + name: Potlatch 1 + description: Potlatch 1 (golygygu gyda'r porwr) id: name: iD description: iD (golygydd y porwr) + potlatch2: + name: Potlatch 2 + description: Potlatch 2 (golygu gyda'r porwr) remote: name: Rheolaeth o bell + description: Pellreolwr (JOSM neu Merkaartor) browse: created: Crewyd closed: Wedi cau @@ -91,6 +100,7 @@ cy: edited_by_html: Golygwyd %{time} yn ôl gan %{user} closed_by_html: Caewyd %{time} yn ôl gan %{user} version: Fersiwn + in_changeset: Set-newid anonymous: dienw no_comment: (dim sylw) part_of: Rhan o @@ -105,20 +115,37 @@ cy: node_paginated: Cygnau (%{x}-%{y} o %{count}) way: Llwybrau %{count} way_paginated: Llwybrau (%{x}-%{y} o %{count}) + relation: Perthynas %{count} + relation_paginated: Perthynas (%{x}-%{y} o %{count}) comment: Sylwadau (%{count}) hidden_commented_by: Sylw cudd gan %{user} %{when} yn ôl commented_by: Sylw gan %{user} %{when} yn ôl + changesetxml: Set-newid XML + osmchangexml: osmChange XML + feed: + title: Set-newid %{id} + title_comment: Set-newid %{id} - %{comment} join_discussion: Mewngofnodwch i ymuno yn y sgwrs discussion: Sgwrs + node: + title: 'Nod: %{name}' + history_title: 'Hanes y Nod: %{name}' way: title: 'Llwybr: %{name}' history_title: 'Hanes Llwybr: %{name}' + nodes: Nodau + also_part_of: + one: rhan o'r ffordd %{related_ways} + other: rhan o'r ffyrdd %{related_ways} relation: title: 'Perthynas: %{name}' + history_title: 'Hanes y Perthynas: %{name}' members: Aelodau relation_member: + entry_role: '%{type} %{name} fel %{role}' type: + node: Nod way: Llwybr relation: Perthynas containing_relation: @@ -127,13 +154,23 @@ cy: not_found: sorry: 'Ymddiheurwn, ni ellir canfod %{type} #%{id}.' type: + node: nod way: llwybr + relation: perthynas + changeset: set-newid + note: nod timeout: + sorry: Cymerodd yn rhy hir i adalw data math %{type} (gydag ID %{id})! type: + node: nod way: llwybr relation: perthynas + changeset: set-newid + note: nodyn redacted: + redaction: Golygiad %{id} type: + node: nod way: llwybr relation: perthynas start_rjs: @@ -178,14 +215,27 @@ cy: comment: Sylw area: Maes list: + title: Setiau-newid + title_user: Set-newid gan %{user} + title_friend: Setiau-newid eich cyfeillion + title_nearby: Setiau-newid defnyddwyr cyfagos + empty: Ni chanfuwyd setiau-newid. + empty_area: Dim setiau-newid yn yr ardal yma. + empty_user: Dim setiau-newid gan y defnyddiwr hwn. + no_more: Dim rhagor o setiau-newid. + no_more_area: Dim rhagor o setiau-newid yn yr ardal yma. load_more: Llwytho mwy rss: + title_all: Trafodaeth OpenStreetMa o'r setiau-newid + title_particular: 'Trafodaeth OpenStreetMap set-newid #%{changeset_id}' + comment: Sylw newydd ar set-newid %{changeset_id} gan awdur %{author} commented_at_html: Diweddarwyd %{when} yn ôl commented_at_by_html: Diweddarwyd %{when} yn ôl gan %{user} full: Sgwrs llawn diary_entry: new: title: Cofnod Dyddiadur Newydd + publish_button: Cyhoeddi list: title: Dyddiaduron defnyddwyr title_friends: Dyddiaduron ffrindiau @@ -268,10 +318,12 @@ cy: format_to_export: Fformatiwch i'w Hallforio osm_xml_data: Data XML OpenStreetMap map_image: Delwedd y Map (dangoser yr haen safonol) + embeddable_html: Mewnosod HTML licence: Trwydded export_details: Trwyddedir OpenStreetMap ar drwydded Comin Data Agored (Open Data Commons Open Database License) (ODbL). too_large: + advice: 'Os yw''r allforio''n methu, ystyriwch un o''r canlynol:' other: title: Ffynonellau eraill description: Ffynonellau ychwanegol a nodir ar wici OpenStreetMap @@ -290,7 +342,6 @@ cy: search: title: latlon: Canlyniadau o Internal - us_postcode: Canlyniadau o Geocoder.us uk_postcode: Canlyniadau o NPEMap / FreeThe Postcode ca_postcode: Canlyniadau o Geocoder.CA @@ -314,6 +365,7 @@ cy: gate: Giat helipad: Pad Hofrennydd runway: Rhedfa Awyr + taxiway: Safle tacsi terminal: Terfynell amenity: animal_shelter: Cysgod Anifeiliaid @@ -353,14 +405,17 @@ cy: emergency_phone: Ffôn Argyfwng fast_food: Bwyd Parod ferry_terminal: Terfynell Fferi + fire_hydrant: Hydrant tân fire_station: Gorsaf Dân food_court: Cwrt Fwydydd fountain: Ffynnon fuel: Tanwydd + gambling: Gamblo grave_yard: Mynwent gym: Canolfan Ffitrwydd / Campfa health_centre: Canolfan Iechyd hospital: Ysbyty + hunting_stand: Llwyfan Hela ice_cream: Hufen Iâ kindergarten: Meithrinfa library: Llyfrgell @@ -403,17 +458,21 @@ cy: toilets: Tai bach townhall: Neuadd Dref university: Prifysgol + vending_machine: Peiriant Gwerthu veterinary: Milfeddygfa village_hall: Neuadd Bentref waste_basket: Bin sbwriel + waste_disposal: Gwaredu Sbwriel youth_centre: Canolfan Ieuenctid boundary: + administrative: Ffin Gweinyddol census: Ffin Cyfrifiad national_park: Parc Cenedlaethol protected_area: Ardal Warchodol bridge: aqueduct: Dyfrbont suspension: Pont Grog + swing: Pont Droelli viaduct: Pont Trenau "yes": Pont building: @@ -426,19 +485,26 @@ cy: painter: Peintiwr photographer: Ffotograffydd plumber: Plymar + shoemaker: Crudd + tailor: Teiliwr "yes": Siop Grefftau emergency: ambulance_station: Gorsaf Ambiwlans + defibrillator: Diffibriliwr + landing_site: Man Glanio Mewn Argyfwng phone: Ffôn Argyfwng highway: + abandoned: Hen Briffordd bridleway: Llwybr Ceffyl bus_guideway: Lon Bysiau bus_stop: Stop Bysiau construction: Priffordd yn cael ei Adeiladu cycleway: Llwybr Beicio + elevator: Codwr emergency_access_point: Pwynt Mynediad Argyfwng footway: Llwybr Cerdded ford: Rhyd + living_street: Stryd Byw milestone: Carreg Filltir motorway: Traffordd motorway_junction: Cyffordd Traffordd @@ -449,6 +515,7 @@ cy: primary: Priffordd primary_link: Priffordd proposed: Ffordd Arfaethedig + raceway: Trac Rasio residential: Ffordd rest_area: Man Gorffwys road: Ffordd @@ -522,18 +589,25 @@ cy: railway: Rheilffordd recreation_ground: Maes Chwarae reservoir: Cronfa Ddŵr + reservoir_watershed: Gwahanfa Ddŵr + residential: Ardal Breswyl retail: Adwerthu + road: Ardal Ffordd village_green: Llain Pentref vineyard: Gwinllan + "yes": Defnydd Tir leisure: beach_resort: Ardal Wyliau + bird_hide: Cuddle Adar club: Clwb common: Tir Comin dog_park: Parc Cwn fishing: Man Pysgota fitness_centre: Canolfan Gadw'n Heini + fitness_station: Lle Cadw'n Heini garden: Gardd golf_course: Cwrs Golff + horse_riding: Llain Marchogaeth ice_rink: Llawr Sglefrio marina: Marina miniature_golf: Golff Pitw @@ -542,6 +616,7 @@ cy: pitch: Maes Chwarae playground: Lle Chwarae recreation_ground: Maes Hamdden + resort: Cyrchfan Gwyliau sauna: Sawna slipway: Llithrffordd sports_centre: Canolfan Chwaraeon @@ -549,9 +624,11 @@ cy: swimming_pool: Pwll Nofio track: Trac Rhedeg water_park: Parc Dŵr + "yes": Hamdden man_made: lighthouse: Goleudy pipeline: Pibell + tower: Tŵr works: Ffatri "yes": Wnaed gan Ddyn military: @@ -568,6 +645,7 @@ cy: cliff: Clogwyn crater: Crater dune: Twyn + fell: Rhostir fjord: Ffiord forest: Coedwig geyser: Geiser @@ -585,6 +663,7 @@ cy: reef: Riff ridge: Cefn rock: Craig + saddle: Cyfrwy sand: Tywod scree: Sgri scrub: Llwyni @@ -607,10 +686,13 @@ cy: government: Swyddfa Llywodraeth insurance: Swyddfa Yswiriant lawyer: Cyfreithiwr + ngo: Swyddfa'r NGO telecommunication: Swyddfa Telegyfathrebu travel_agent: Asiantaeth Deithio "yes": Swyddfa place: + allotments: Rhandiroedd + block: Bloc airport: Maes Awyr city: Dinas country: Gwlad @@ -633,7 +715,9 @@ cy: subdivision: Is-adran suburb: Maestref town: Tref + unincorporated_area: Ardal Anghorfforedig village: Pentref + "yes": Lle railway: abandoned: Hen Reilffordd construction: Rheilffordd yn cael ei Osod @@ -644,7 +728,9 @@ cy: historic_station: Hen Orsaf Trenau junction: Cyffordd Rheilffyrdd level_crossing: Croesfan Wastad + light_rail: Rheilffordd Ysgafn miniature: Lein Fach + monorail: Trên Un Gledren narrow_gauge: Lein Fach Gul platform: Platfform Drenau preserved: Rheilffordd ar Gadw @@ -652,8 +738,9 @@ cy: spur: Cainc Rheilffordd station: Gorsaf Drenau stop: Siop Reilffordd - subway: Gorsaf Drenau Tanddaearol + subway: Gorsaf Tanddaearol subway_entrance: Mynedfa at Drenau Tanddaearol + switch: Pwyntiau Atal (Rheilffyrdd) tram: Tramffordd tram_stop: Stop Tramiau shop: @@ -733,6 +820,7 @@ cy: "yes": Siop tourism: alpine_hut: Cwt Mynydd + apartment: Rhandai neu fflatiau artwork: Gwaith Celf attraction: Atyniad bed_and_breakfast: Gweldy a Brecwast @@ -755,6 +843,7 @@ cy: culvert: Twnel Ddŵr "yes": Twnel waterway: + artificial: Dyfrffyrdd Artiffisial boatyard: Iard Gychod canal: Camlas dam: Argae @@ -771,6 +860,7 @@ cy: wadi: Sychnant waterfall: Rheadr weir: Cored + "yes": Dyfrffyrdd admin_levels: level2: Ffin Gwledydd level4: Ffin Taleithiau @@ -807,6 +897,7 @@ cy: data: Data export_data: Allforio Data gps_traces: Dargopiadau GPS + gps_traces_tooltip: Rheoli Amlinellau GPS user_diaries: Dyddiaduron Defnyddwyr user_diaries_tooltip: Gweld dyddiaduron defnyddwyr edit_with: Golygu gyda %{editor} @@ -872,6 +963,7 @@ cy: add_a_note: title: Dim amser i olygu? Ychwanegwch nodyn! fixthemap: + title: Adrodd am broblem / Cywiro map how_to_help: title: Sut i Helpu join_the_community: @@ -883,6 +975,8 @@ cy: welcome: url: /croeso title: Croeso i OSM + beginners_guide: + title: Llawlyfr Dechreuwyr about_page: next: Nesaf copyright_html: ©cyfrannwyr
    OpenStreetMap @@ -890,6 +984,10 @@ cy: open_data_title: Data Agored partners_title: Partneriaid notifier: + message_notification: + hi: Pa hwyl %{to_user}? + friend_notification: + hi: Henffych %{to_user}! gpx_notification: greeting: Pa hwyl? with_description: gyda'r disgrifiad @@ -953,6 +1051,7 @@ cy: date: Dyddiad reply_button: Ateb unread_button: Nodi nad yw wedi ei ddarllen + delete_button: Dileu back: Yn ôl to: At sent_message_summary: @@ -977,7 +1076,7 @@ cy: close: Cau search: search: Chwilio - where_am_i: Ble ydw i? + where_am_i: Ble mae hwn? where_am_i_title: Disgrifiwch eich lleoliad presennol gan ddefnyddio peiriant chwilio. submit_text: Mynd @@ -985,22 +1084,38 @@ cy: table: entry: motorway: Traffordd + main_road: Prif ffordd trunk: Cefnffordd primary: Priffordd secondary: Ffordd eilaidd unclassified: Ffordd annosbarthedig track: Trac + bridleway: Llwybr ceffyl + cycleway: Llwybr beicio + cycleway_national: Llwybr beicio cenedlaethol + cycleway_regional: Llwybr beicio rhanbarthol + cycleway_local: Llwybr beicio lleol footway: Ffordd droed rail: Rheilffordd subway: Trenau Tanddaearyddol tram: - 1: tram + - Rheilffordd ysgafn + - tram cable: - Car codi + - Lifft cadair + runway: + - Llwybr glanio'r maes awyr + - atredfa + apron: + - Ffedog (y maes awyr) + - terminws + admin: Ffin gweinyddol forest: Coedwig wood: Coed golf: Cwrs golff park: Parc + resident: Ardal breswyl common: - Comin - dôl @@ -1028,6 +1143,10 @@ cy: - Crib private: Mynediad preifat destination: Mynediad cyrchfan + construction: Ffyrdd wrthi'n cael eu hadeiladu + bicycle_shop: Siop feics + bicycle_parking: Man parcio beics + toilets: Lle chwech richtext_area: edit: Golygu preview: Rhagolwg @@ -1251,14 +1370,17 @@ cy: administrator: Mae'r defnyddiwr hwn yn weinyddwr. moderator: Mae'r defnyddiwr hwn yn gymedrolwr. comments: Sylwadau - create_block: rhwystro'r defnyddiwr hwn - activate_user: actifadu'r defnyddiwr hwn - confirm_user: cadarnhau'r defnyddiwr - hide_user: cuddio'r defnyddiwr - unhide_user: datguddio'r defnyddiwr - delete_user: dileu'r defnyddiwr + create_block: Rhwystro'r Defnyddiwr hwn + activate_user: Gwneud y cyfri'n fyw + deactivate_user: Atal y cyfri + confirm_user: Cadarnhau'r Defnyddiwr + hide_user: Cuddio'r Defnyddiwr + unhide_user: Datguddio'r Defnyddiwr + delete_user: Dileu'r Defnyddiwr confirm: Cadarnhau + friends_changesets: setiau-newid eich cyfeillion friends_diaries: cofnodion dyddiaduron cyfeillion + nearby_changesets: setiau-newid gerllaw nearby_diaries: cofnodion dyddiaduron defnyddwyr gerllaw popup: your location: Eich lleoliad @@ -1304,9 +1426,11 @@ cy: save changes button: Cadw'r Newidiadau make edits public button: Gwneud fy holl olygiadau yn gyhoeddus return to profile: Dychwelyd i'r proffil + confirm: + button: Cadarnhau confirm_email: button: Cadarnhau - success: Wedi cadarnhau eich cyfeiriad ebost! Diolch am gofrestru. + success: Cadarnhewch eich cyfeiriad ebost newydd! failure: Mae cyfeiriad ebost eisoes wedi ei gadarnhau gyda'r tocyn hwn. set_home: flash success: Wedi cadw'r lleoliad cartref diff --git a/config/locales/da.yml b/config/locales/da.yml index 979f21fe6..d901b31b6 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -403,7 +403,6 @@ da: search: title: latlon: Resultater fra interne - us_postcode: Resultater fra Geocoder.us uk_postcode: Resultater fra NPEMap / FreeThe Postcode ca_postcode: Resultater fra Geocoder.CA @@ -968,8 +967,8 @@ da: intro_text: OpenStreetMap er et kort over verden, skabt af folk som dig og gratis at bruge under en Ã¥ben licens. intro_2_create_account: Opret en brugerkonto - partners_html: Hosting understøttes af %{ucl}, %{ic} og %{bytemark} og andre %{partners}. - partners_ucl: UCL VR centret + partners_html: Driften støttes af %{ucl}, %{ic}, %{bytemark} og andre %{partners}. + partners_ucl: University College London partners_ic: Imperial College London partners_bytemark: Bytemark Hosting partners_partners: partnere @@ -1016,18 +1015,18 @@ da: Hvis du ændrer eller bygger pÃ¥ vores\ndata, mÃ¥ du kun distribuere resultatet under den samme licens. Den\nfulde juridiske tekst\nforklarer dine rettigheder og pligter." - intro_3_html: Kartografi i vores kort, og vores dokumentation er licenseret - under Creative + intro_3_html: Kartografien i vores kort-fliser, samt vores dokumentation er + licenseret under Creative Commons Navngivelse-DelPÃ¥SammeVilkÃ¥r 2.0 (CC BY-SA). credit_title_html: Kildeangivelse og OpenStreetMap credit_1_html: Vi kræver at din kildeangivelse mindst bestÃ¥r af “© OpenStreetMap-bidragsydere”.. credit_2_html: "Du skal ogsÃ¥ gøre det klart, at dataene er tilgængelige under - Open \nDatabase License, og hvis du bruger vores kort fliser, at kartografi - er\n licenseret som CC-BY-SA. Du kan gøre dette ved at linke til\ndenne + Open \nDatabase License, og hvis du bruger vores kort-fliser, at kartografien + er\n licenseret som CC BY-SA. Du kan gøre dette ved at linke til\ndenne side om ophavsret. \nAlternativt, og som et krav, hvis du distribuerer - OSM i en\n dataform, kan du navngive og oprette et hyperlink direkte til licenserne. - I medier\n hvor hyperlinks ikke er mulig (f.eks. trykte værker), foreslÃ¥r + OSM som\n data, kan du navngive og oprette et hyperlink direkte til licenserne. + I medier\n hvor hyperlinks ikke er mulige (f.eks. trykte værker), foreslÃ¥r vi, at du\n henviser dine læsere til openstreetmap.org (mÃ¥ske ved at udvide\n'OpenStreetMap' til denne fuld adresse), til opendatacommons.org, og\n hvis relevant, til creativecommons.org." @@ -1039,17 +1038,17 @@ da: title: Eksempel pÃ¥ kildeangivelse more_title_html: Læs mere more_1_html: |- - Læs mere om brug af vores data, og hvordan du kreditere os, pÃ¥ OSMF Licenssiden og pÃ¥ den juridiske + Læs mere om brug af vores data, og hvordan du krediterer os, pÃ¥ OSMF Licens-siden og i fællesskabets Juridiske FAQ. more_2_html: |- Selvom OpenStreetMap er Ã¥bne data, kan vi ikke levere et gratis kort-API til tredjeparter. Se vores Politik for brug af API, - Politik for brug af kortbilleder - og politik for brug af Nominatim. + Politik for brug af kort-fliser + og Politik for brug af Nominatim. contributors_title_html: Vores bidragsydere contributors_intro_html: |- Vores bidragsydere er tusinder af individer. Vi medtager ogsÃ¥ @@ -1432,6 +1431,7 @@ da: date: Dato reply_button: Svar unread_button: Marker som ulæst + delete_button: Slet back: Tilbage to: Til wrong_user: Du er logget pÃ¥ som '%{user}', men den besked du har bedt om at @@ -2382,8 +2382,10 @@ da: comment: Kommenter edit_help: Flyt kortet og zoom ind pÃ¥ et sted, du vil redigere, og klik sÃ¥ her. directions: + ascend: Stigning engines: graphhopper_bicycle: Cykel (GraphHopper) + graphhopper_car: Bil (GraphHopper) graphhopper_foot: Til fods (GrapHopper) mapquest_bicycle: Cykel (MapQuest) mapquest_car: Bil (MapQuest) @@ -2392,6 +2394,7 @@ da: mapzen_bicycle: Cykel (Mapzen) mapzen_car: Bil (Mapzen) mapzen_foot: Fod (Mapzen) + descend: Fald directions: Rutevejledning distance: Afstand errors: diff --git a/config/locales/de.yml b/config/locales/de.yml index ea7906de6..e9e68c6f9 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -430,7 +430,6 @@ de: search: title: latlon: Suchergebnisse von Internal - us_postcode: Suchergebnisse von Geocoder.us uk_postcode: Suchergebnisse von NPEMap / FreeThe Postcode ca_postcode: Suchergebnisse von Geocoder.CA @@ -998,7 +997,7 @@ de: intro_text: OpenStreetMap ist eine Karte der Welt, erstellt von Menschen wie dir und frei verwendbar unter einer offenen Lizenz. intro_2_create_account: Erstelle ein Benutzerkonto - partners_html: Das Hosting wird %{ucl}, %{ic}, %{bytemark} sowie von anderen %{partners} + partners_html: Das Hosting wird von %{ucl}, %{bytemark}, %{ic} und weiteren %{partners} unterstützt. partners_ucl: UCL partners_ic: dem Imperial College London @@ -1078,8 +1077,7 @@ de: more_title_html: Weitere Informationen more_1_html: |- Mehr Informationen dazu, wie unsere Daten verwendet werden können und wie man auf unsere Urheberschaft hinweist, - kann man auf unserer OSMF-Lizenzseite und in den - Häufigen rechtlichen Fragen (Legal FAQ) nachlesen. + kann man auf unserer OSMF-Lizenzseite nachlesen. more_2_html: |- Obwohl OpenStreetMap „Open Data“ ist, können wir keine unentgeltliche Karten-API für Drittparteien bereitstellen. @@ -1166,9 +1164,9 @@ de: way_html: Ein Way ("Weg") in OSM ist eine offene Linie wie z.B. eine Straße, ein Weg, ein Fluss oder bildet eine geschlossene Fläche, z.B. ein Gebäude. - tag_html: Ein tag ("Attribut") ist eine Eigenschaft, die man - einem Objekt zuweist. Z.B. der Name eines Restaurants oder die maximal erlaubte - Geschwindigkeit auf einer Straße. + tag_html: Ein tag („Attribut“) ist eine Eigenschaft, die man + einem Objekt zuweist, z. B. der Name eines Restaurants oder die erlaubte + Höchstgeschwindigkeit auf einer Straße. rules: title: Regeln! paragraph_1_html: "OpenStreetMap hat nur wenige formale Regeln, aber wir erwarten, @@ -1269,8 +1267,9 @@ de: Die OpenStreetMap-Gemeinschaft ist vielfältig, leidenschaftlich und wächst täglich. Unsere Mitwirkenden sind begeisterte Mapper, GIS-Profis, Ingenieure, die die OSM-Server betreiben und viele mehr. - Um mehr über die Gemeinschaft zu erfahren, lies unsere - Benutzertagebücher, + Um mehr über die Gemeinschaft zu erfahren, lies unseren + OpenStreetMap-Blog, + die Benutzertagebücher, Community-Blogs und die Website der OSM-Foundation. open_data_title: Open Data @@ -1477,6 +1476,7 @@ de: date: Datum reply_button: Antworten unread_button: Als ungelesen markieren + delete_button: Löschen back: Zurück to: An wrong_user: Du bist angemeldet als '%{user}', aber die Nachricht, die du lesen @@ -1532,7 +1532,7 @@ de: get_directions_title: Routenberechnung zwischen zwei Orten from: Von to: Nach - where_am_i: Wo bin ich? + where_am_i: Wo ist das? where_am_i_title: Die momentane Position mit der Suchmaschine anzeigen submit_text: Los key: diff --git a/config/locales/diq.yml b/config/locales/diq.yml index a646cc13d..edfa18f4f 100644 --- a/config/locales/diq.yml +++ b/config/locales/diq.yml @@ -232,7 +232,7 @@ diq: confirm: Tesdiq ke location: location: 'Herun:' - view: Bımotne + view: Bıvêne edit: Bıvurne comments: post: Bırışe @@ -274,7 +274,6 @@ diq: search: title: latlon: OSM ra neticey - us_postcode: Geocoder.us ra neticey uk_postcode: FreeThe Postcode ra neticey ca_postcode: Geocoder.CA ra neticey osm_nominatim: OSM Nominatim @@ -466,7 +465,7 @@ diq: historic: archaeological_site: Arkeolojik Ca battlefield: Cay herbi - boundary_stone: Siya sinori + boundary_stone: Kemera Sinori building: Binaya verên bunker: Stare castle: Qela @@ -678,8 +677,11 @@ diq: gift: Çiyo Hediye salon: Kuafor tourism: + gallery: Galeriye hostel: Hostel hotel: Hotel + information: Melumat + motel: Motel tunnel: "yes": Tûnêl waterway: @@ -698,9 +700,16 @@ diq: edit: Bıvırne history: Tarix export: Tebergroten + data: Melumati help: Peşti + copyright: Heqa telıfi community: Cemaet community_blogs: Blogê Cemaeti + license_page: + native: + title: Heqa na pele de + welcome_page: + title: Xeyr amey! notifier: diary_comment_notification: hi: Merheba %{to_user}, @@ -716,6 +725,10 @@ diq: greeting: Merheba, lost_password_html: greeting: Merheba, + note_comment_notification: + greeting: Merheba, + changeset_comment_notification: + greeting: Merheba, message: inbox: title: Ameyan @@ -728,6 +741,7 @@ diq: reply_button: Cewab bıde delete_button: Bestere new: + title: Mesac bırışê subject: Mewzu body: Vêrey mesaci send_button: Bırışe @@ -739,13 +753,18 @@ diq: subject: Mewzu date: Dem read: + title: Mesaci bıwanê subject: Mewzu date: Dem reply_button: Cewab bıde + delete_button: Bestere + back: Peyser to: Kêrê sent_message_summary: delete_button: Bestere site: + edit: + user_page_link: pela karberi sidebar: search_results: Neticeyê geyrayışi close: Racnê @@ -1039,7 +1058,7 @@ diq: one: 1 seate other: '%{count} seati' partial: - show: Bımotne + show: Bımocne edit: Bıvırne revoke: Terkne! confirm: Vac welay? @@ -1066,7 +1085,7 @@ diq: time_future: '%{time} dı bıqediyo' time_past: Verdê %{time} qedya status: Weziyet - show: Bımotne + show: Bımocne edit: Bıvurne revoke: Terkne! confirm: Vac welay? @@ -1075,6 +1094,9 @@ diq: entry: comment: Mışewre javascripts: + share: + cancel: Bıtexelne + image: Resım map: base: standard: Standard diff --git a/config/locales/dsb.yml b/config/locales/dsb.yml index 948147f06..1a605354d 100644 --- a/config/locales/dsb.yml +++ b/config/locales/dsb.yml @@ -363,7 +363,6 @@ dsb: search: title: latlon: Wuslědki z Internal - us_postcode: Wuslědki z Geocoder.us uk_postcode: Wuslědki z NPEMap / FreeThe Postcode ca_postcode: Wuslědki z Geocoder.CA diff --git a/config/locales/el.yml b/config/locales/el.yml index dd772a2d9..f208ac40a 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -9,10 +9,12 @@ # Author: FocalPoint # Author: Geraki # Author: Glavkos +# Author: KATRINE1992 # Author: Kiriakos # Author: Kongr43gpen # Author: Logictheo # Author: Macofe +# Author: Nikosgranturismogt # Author: Omnipaedista # Author: Protnet # Author: Ruila @@ -418,7 +420,6 @@ el: title: latlon: Αποτελέσματα από την εσωτερική βάση δεδομένων - us_postcode: Αποτελέσματα από Geocoder.us uk_postcode: Αποτελέσματα από NPEMap / FreeThe Postcode ca_postcode: Αποτελέσματα από Geocoder.CA @@ -987,8 +988,8 @@ el: intro_text: Το OpenStreetMap είναι χάρτης του κόσμου, που δημιουργήθηκε από ανθρώπους σαν κι εσάς και είναι δωρεάν, υπό άδεια ελεύθερης χρήσης. intro_2_create_account: Δημιουργήστε ένα λογαριασμό χρήστη - partners_html: Η φιλοξενία υποστηρίζεται από το %{ucl}, %{ic} και %{bytemark}, - και άλλους %{partners}. + partners_html: Η λειτουργία υποστηρίζεται από το %{ucl}, %{ic} και %{bytemark}, + και άλλους %{συνεργάτες}. partners_ucl: UCL partners_ic: Imperial College του Λονδίνου partners_bytemark: Bytemark Hosting @@ -1053,8 +1054,8 @@ el: title: Παράδειγμα αναφοράς δημιουργού more_title_html: Μαθαίνοντας περισσότερα more_1_html: |- - Διαβάστε περισσότερα σχετικά με τη χρήση των δεδομένων μας, και πώς να μας μνημονεύσετε στην σελίδα Άδειας OSMF και τις συχνές νομικές ερωτήσεις της κοινότητας. + Διαβάστε περισσότερα σχετικά με τη χρήση των δεδομένων μας, και πώς να μας μνημονεύσετε στην + σελίδα Άδειας OSMF. more_2_html: |- Παρόλο που το OpenStreetMap αποτελείται από ανοικτά δεδομένα, δεν μπορούμε να προσφέρουμε ένα δωρεάν API χαρτών για τρίτους προγραμματιστές. @@ -1281,6 +1282,7 @@ el: footer_html: Μπορείτε επίσης να διαβάσετε το μήνυμα στο %{readurl} και να απαντήσετε στο %{replyurl} friend_notification: + hi: Γεια σας %{to_user}, subject: '[OpenStreetMap] Ο χρήστης %{user} σας πρόσθεσε ως φίλο' had_added_you: Ο χρήστης %{user} σας πρόσθεσε ως φίλο στο OpenStreetMap. see_their_profile: Μπορείτε να δείτε το προφίλ του στο %{userurl}. @@ -1452,6 +1454,7 @@ el: date: Ημ/νία reply_button: Απάντηση unread_button: Σήμανση ως αδιάβαστο + delete_button: Διαγραφή back: Επιστροφή to: Προς wrong_user: Έχετε συνδεθεί ως «%{user}» αλλά το μήνυμα που ζητάτε να διαβάσετε @@ -1506,7 +1509,7 @@ el: get_directions_title: Βρείτε οδηγίες μεταξύ δύο σημείων from: Από to: Προς - where_am_i: Πού είμαι; + where_am_i: Πού είναι αυτό; where_am_i_title: Περιέγραψε την τωρινή τοποθεσία με χρήση της μηχανής αναζήτησης submit_text: Μετάβαση key: @@ -1602,6 +1605,8 @@ el: public: Δημόσιο (εμφανίζεστε στη λίστα ιχνών σαν ανώνυμος, μη χρονοσημασμένα σημεία) trackable: Ανιχνεύσιμο (κοινοποιείται ως ανώνυμα διατεταγμένα σημεία με χρονοσημάνσεις) + identifiable: Μπορεί να αναγνωριστεί (φαίνεται στην λίστα παρακολούθησης και + ως αναγνωρίσιμο, τα σημεία ταξινόμησης με χρονικά σήματα) create: upload_trace: Αποστολή Ίχνους GPS trace_uploaded: Το GPX αρχείο σας έχει μεταμορφωθεί και αναμένει την εισαγωγή @@ -1701,6 +1706,10 @@ el: made_public: Το ίχνος έγινε δημόσιο offline_warning: message: Το σύστημα μεταφόρτωσης αρχείων GPX δεν είναι διαθέσιμο προς το παρών + offline: + heading: GPX Αποθήκευση Offline + message: O φάκελλος αποθήκευσης GPX και το σύστημα ανεβάσματος αρχείων δεν είναι + διαθέσιμα αυτή την στιγμή georss: title: OpenStreetMap Ίχνη GPS description: @@ -1741,6 +1750,7 @@ el: allow_write_notes: τροποποιήσει σημειώσεις. grant_access: Παροχή Πρόσβασης oauthorize_success: + title: Επιτρέπεται το αίτημα εξουσιοδότησης allowed: Παραχωρήσατε στην εφαρμογή %{app_name} πρόσβαση στον λογαριασμό σας. verification: Ο κωδικός επαλήθευσης είναι %{code}. oauthorize_failure: @@ -1749,6 +1759,8 @@ el: invalid: Το κουπόνι εξουσιοδότησης δεν είναι έγκυρο. revoke: flash: Ανακαλέσατε το κουπόνι για το %{application}. + permissions: + missing: Δεν έχετε επιτρέψει την πρόσβαση εφαρμογής σε αυτήν την λειτουργία oauth_clients: new: title: Καταχώρηση νέας εφαρμογής @@ -1758,6 +1770,12 @@ el: submit: Επεξεργασία show: title: Λεπτομέρειες OAuth για το %{app_name} + key: 'Κωδικός Καταναλωτή :' + secret: 'Μυστικό του Καταναλωτή:' + url: 'Σημείο Ζήτησης URL:' + access_url: 'Πρόσβαση στο Σημείο URL:' + authorize_url: 'Εξουσιοδοτήστε το URL:' + support_notice: Υποστηρίζουμε τα HMCA-SHA1 (συστήνονται) και υπογραφές RSA-SHA1 edit: Επεξεργασία Λεπτομερειών delete: Διαγραφή Πελάτη confirm: Είσαστε σίγουροι; @@ -1772,10 +1790,14 @@ el: index: title: Οι λεπτομέρειες του OAuth μου my_tokens: Οι Εξουσιοδοτημένες Εφαρμογές μου + list_tokens: 'Τα ακόλουθα σημεία έχουν εκδοθεί για προγράμματα στο όνομα σας:' application: Όνομα Εφαρμογής issued_at: Εκδόθηκε Στις revoke: Ανακαλέστε! my_apps: Οι Εφαρμογές Πελάτη Μου + no_apps: Έχετε ένα πρόγραμμα που θα θέλατε να εισάγετε για χρήση μαζί μας χρησιμοποιώντας + την παράμετρο % (oauth)?Πρέπει να εισάγετε την εφαρμογή σας δικτύου πριν ζητήσει + το OAuth για αυτήν την υπηρεσία. registered_apps: 'Έχετε τις παρακάτω εφαρμογές πελάτη καταχωρημένες:' register_new: Καταχωρήστε την εφαρμογή σας form: @@ -1784,6 +1806,7 @@ el: url: URL Κύριας Εφαρμογής callback_url: URL Επανάκλησης support_url: URL Υποστήριξης + requests: 'Ζητήσετε τις ακόλουθες άδειες από τον χρήστη:' allow_read_prefs: διαβάσει τις δικές τους προτιμήσεις χρήστη. allow_write_prefs: τροποποιήσει τις δικές τους προτιμήσεις χρήστη. allow_write_diary: δημιουργήσει καταχωρήσεις ημερολογίου, σχόλια και να κάνει @@ -1792,8 +1815,14 @@ el: allow_read_gpx: διαβάσει τα ιδιωτικά τους GPS ίχνη. allow_write_gpx: αποστείλει ίχνη GPS. allow_write_notes: τροποποιήσει σημειώσεις + not_found: + sorry: Λυπούμαστε, αυτός ο {τύπος}% δεν μπόρεσε να βρεθεί. create: flash: Οι πληροφορίες καταχωρήθηκαν επιτυχώς + update: + flash: Οι πληροφορίες του πελάτη ενημερώθηκαν με επιτυχία + destroy: + flash: Η εισαγωγή του προγράμματος του πελάτη χάλασε user: login: title: Σύνδεση @@ -1872,6 +1901,7 @@ el: confirm password: 'Επιβεβαίωση Κωδικού:' reset: Επαναφορά Κωδικού flash changed: Ο κωδικός σας αλλάχτηκε. + flash token bad: Δεν βρήκατε αυτό το κομμάτι, μήπως πρέπει να ελέγξετε το URL; new: title: Εγγραφή no_auto_account_create: Δυστυχώς δεν μπορούμε να δημιουργήσουμε αυτόματα έναν @@ -1901,6 +1931,8 @@ el: password: 'Κωδικός:' confirm password: 'Επιβεβαίωση Κωδικού:' use external auth: 'Εναλλακτικά, χρησιμοποιήστε τρίτην υπηρεσία για είσοδο:' + auth no password: Για την έγκριση τρίτων δεν απαιτείται κωδικός πρόσβασης, αλλά + μερικά ειδικά εργαλεία αλλιώς ο διακομιστής μπορεί να χρειάζεται ένα. continue: Εγγραφή terms accepted: Ευχαριστούμε για την αποδοχή των νέων όρων συνεισφοράς! terms declined: Λυπούμαστε για το ότι αποφασίσατε να μην αποδεχθείτε τους νέους @@ -1915,6 +1947,9 @@ el: consider_pd: Και επιπρόσθετα στην παραπάνω συμφωνία, θεωρώ τις συνεισφορές μου ως Public Domain consider_pd_why: τι είναι αυτό; + guidance: Πληροφορίες για να καταλάβετε αυτούς τους όρους:μία + αναγνώσιμη περίληψηκαι μερικές ανεπίσημες μεταφράσεις + agree: Συμφωνώ decline: Διαφωνώ you need to accept or decline: Παρακαλώ διαβάστε και αποδεχτείτε ή απορρίψτε @@ -1961,6 +1996,7 @@ el: email address: 'Διεύθυνση Ηλ. Ταχυδρομείου:' created from: 'Δημιουργήθηκε από:' status: 'Κατάσταση:' + spam score: 'Σκορ Spam:' description: Περιγραφή user location: Τοποθεσία χρήστη if set location: Ορίσετε την τοποθεσία του σπιτιού σας στις %{settings_link} @@ -2047,6 +2083,7 @@ el: gravatar: gravatar: Χρήση Gravatar link text: τι είναι αυτό; + disabled: 'Το Gravatar έχει απενεργοποιηθεί:' enabled: Εμφάνισης του Gravatar σας έχει ενεργοποιηθεί. new image: Προσθήκη εικόνας keep image: Διατήρηση της τρέχουσας εικόνας @@ -2139,7 +2176,11 @@ el: μπορείτε να επικοινωνήσετε με τον %{webmaster} αν θέλετε να συζητήσετε αυτό το θέμα.

    auth_failure: + connection_failed: Η σύνδεση στον φορέα πιστοποίησης έχει αποτύχει + invalid_credentials: Μη έγκυρα πιστοποιητικά + no_authorization_code: Δεν υπάρχει κωδικός πιστοποίησης unknown_signature_algorithm: Άγνωστος αλγόριθμος υπογραφής + invalid_scope: Μη έγκυρο φάσμα auth_association: heading: Το ID σας δεν σχετίζεται ακόμα με λογαριασμό στο OpenStreetMap. option_1: |- @@ -2161,12 +2202,16 @@ el: are_you_sure: Είστε βέβαιος ότι θέλετε να εκχωρήσετε το ρόλο `%{role}' στον χρήστη `%{name}'? confirm: Επιβεβαίωση + fail: Δεν μπόρεσε να εξουσιοδοτήσει τον χρήστη % {όνομα}. Παρακαλώ ελέγξετε + ότι ο χρήστης και ο ρόλος είναι και οι δύο έγκυροι. revoke: title: Επιβεβαίωση ανάκλησης ρόλου heading: Επιβεβαίωση ανάκλησης ρόλου are_you_sure: Σίγουρα θέλετε να ανακαλέστε τον ρόλο «%{role}» από τον χρήστη «%{name}»; confirm: Επιβεβαίωση + fail: Δεν μπόρεσε να αναιρέσει τον ρόλο %{ρόλο} από τον χρήστη %{όνομα}'. Παρακαλώ + τσεκάρετε ότι ο χρήστης και ο ρόλος είναι και οι δύο έγκυροι. user_block: model: non_moderator_update: Πρέπει να είστε συντονιστής για να δημιουργήσετε ή να @@ -2249,6 +2294,8 @@ el: helper: time_future: Τελειώνει σε %{time}. until_login: Ενεργό έως ότου ο χρήστης συνδεθεί. + time_future_and_until_login: Τελειώνει σε %{time} και μετά αφότου ο χρήστης + έχει συνδεθεί. time_past: Τελείωσε %{time} πριν. blocks_on: title: Φραγές στον %{name} @@ -2392,8 +2439,10 @@ el: edit_help: Μετακινήστε το χάρτη και να κάνετε ζουμ σε μια τοποθεσία που θέλετε να επεξεργαστείτε, στη συνέχεια, κάντε κλικ εδώ. directions: + ascend: Ανάβαση engines: graphhopper_bicycle: Ποδήλατο (GraphHopper) + graphhopper_car: Με τα πόδια (GraphHopper) graphhopper_foot: Με τα πόδια (GraphHopper) mapquest_bicycle: Ποδήλατο (MapQuest) mapquest_car: Αυτοκίνητο (MapQuest) @@ -2402,6 +2451,7 @@ el: mapzen_bicycle: Ποδήλατο (Mapzen) mapzen_car: Αυτοκίνητο (Mapzen) mapzen_foot: Με τα πόδια (Mapzen) + descend: Κατάβαση directions: Οδηγίες distance: Απόσταση errors: diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index c5b2630cf..e6ebbb6a8 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -403,7 +403,6 @@ en-GB: search: title: latlon: Results from Internal - us_postcode: Results from Geocoder.us uk_postcode: Results from NPEMap / FreeThe Postcode ca_postcode: Results from Geocoder.CA @@ -1545,6 +1544,7 @@ en-GB: date: Date reply_button: Reply unread_button: Mark as unread + delete_button: Delete back: Back to: To wrong_user: You are logged in as `%{user}' but the message you have asked to @@ -2508,6 +2508,7 @@ en-GB: ascend: Ascend engines: graphhopper_bicycle: Bicycle (GraphHopper) + graphhopper_car: Car (GraphHopper) graphhopper_foot: Foot (GraphHopper) mapquest_bicycle: Bicycle (MapQuest) mapquest_car: Car (MapQuest) diff --git a/config/locales/en.yml b/config/locales/en.yml index ac66ba0f5..7393d6efd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -371,7 +371,6 @@ en: search: title: latlon: 'Results from Internal' - us_postcode: 'Results from Geocoder.us' uk_postcode: 'Results from NPEMap / FreeThe Postcode' ca_postcode: 'Results from Geocoder.CA' osm_nominatim: 'Results from OpenStreetMap Nominatim' @@ -1050,7 +1049,7 @@ en: intro_header: Welcome to OpenStreetMap! intro_text: OpenStreetMap is a map of the world, created by people like you and free to use under an open license. intro_2_create_account: "Create a user account" - partners_html: "Hosting is supported by %{ucl}, %{bytemark} and %{ic}, and other %{partners}." + partners_html: "Hosting is supported by %{ucl}, %{bytemark}, %{ic}, and other %{partners}." partners_ucl: "UCL" partners_ic: "Imperial College London" partners_bytemark: "Bytemark Hosting" @@ -1123,9 +1122,7 @@ en: more_title_html: Finding out more more_1_html: | Read more about using our data, and how to credit us, at the OSMF Licence page and the community Legal - FAQ. + href="http://osmfoundation.org/Licence">OSMF Licence page. more_2_html: | Although OpenStreetMap is open data, we cannot provide a free-of-charge map API for third-parties. @@ -1327,7 +1324,9 @@ en: Our contributors include enthusiast mappers, GIS professionals, engineers running the OSM servers, humanitarians mapping disaster-affected areas, and many more. - To learn more about the community, see the user diaries, + To learn more about the community, see the + OpenStreetMap Blog, + user diaries, community blogs, and the OSM Foundation website. open_data_title: Open Data @@ -1544,7 +1543,7 @@ en: get_directions_title: "Find directions between two points" from: "From" to: "To" - where_am_i: "Where am I?" + where_am_i: "Where is this?" where_am_i_title: Describe the current location using the search engine submit_text: "Go" key: diff --git a/config/locales/eo.yml b/config/locales/eo.yml index ce7e57fda..202b064a7 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -390,7 +390,6 @@ eo: search: title: latlon: Rezultoj el Internal - us_postcode: Rezultoj el Geocoder.us uk_postcode: Rezultoj el NPEMap / FreeThe Postcode ca_postcode: Rezultoj el Geocoder.CA @@ -801,14 +800,14 @@ eo: beverages: Trinkaĵ-vendejo bicycle: Bicikl-vendejo books: Libro-vendejo - boutique: Galanterio + boutique: Mod-butiko butcher: Viand-vendejo car: AÅ­tomobil-vendejo car_parts: AÅ­tomobil-parta vendejo car_repair: AÅ­toriparejo carpet: Tapiŝ-vendejo charity: Almoza vendejo - chemist: Drogejo + chemist: Purigaĵ-vendejo clothes: Vesto-vendejo computer: Komputil-vendejo confectionery: Sukeraĵejo @@ -836,7 +835,7 @@ eo: greengrocer: Legom-butiko grocery: Manĝovendejo hairdresser: Frizejo - hardware: Il-vendejo + hardware: Laboril-vendejo hifi: Altfidel-son-vendejo insurance: Asekurkompaniejo jewelry: Juvel-vendejo @@ -1003,9 +1002,9 @@ eo: modifos aÅ­ uzos niajn datumojn, vi povos distribui la verkon laÅ­ la sama permesilo. La plena interkonsento de uzado klarigas viajn rajtojn kaj devojn. - intro_3_html: |- - La kartografio de niaj map-kaheloj kaj nia dokumentaro estas disponeblaj laÅ­ la permesilo Creative - Commons Atribuite-Samkondiĉe 2.0 (CC BY-SA). + intro_3_html: La kartografio de niaj map-kaheloj kaj nia dokumentaro estas disponeblaj + laÅ­ la permesilo Krea + Komunaĵo Atribuite-Samkondiĉe 2.0 (CC BY-SA). credit_title_html: Kiel atribui aÅ­torecon credit_1_html: 'Ni postulas, ke vi markos: “© Kontribuintoj de OpenStreetMap”.' credit_2_html: Vi ankaÅ­ devas klarigi, ke datumoj estas disponeblaj laÅ­ la permesilo @@ -1037,7 +1036,7 @@ eo: inkludas datumoj laÅ­ malferma permesilo el landaj kartografiaj organizaĵoj kaj el aliaj fontoj, inter ili:' contributors_at_html: |- - AÅ­strujo: enhavas datumojn el Stadt Wien (sub CC BY), + AÅ­strujo: enhavas datumojn el Stadt Wien (laÅ­ CC BY), Land Vorarlberg kaj Land Tirol (sub CC BY AT kun postaj ŝanĝoj). contributors_ca_html: |- @@ -1388,6 +1387,7 @@ eo: date: Dato reply_button: Respondi unread_button: Marki kiel nelegitan + delete_button: Forigi back: Reen to: Al wrong_user: Vi estas ensalutinta kiel '%{user}', sed la mesaĝo, kiun vi volas @@ -1529,7 +1529,7 @@ eo: text: Teksto image: Bildo alt: Kromteksto - url: Retadreso + url: URL trace: visibility: private: Privata (kunhavigita nur kiel sennomaj, malordigitaj punktoj) @@ -2270,7 +2270,7 @@ eo: key: title: Mapklarigo tooltip: Mapklarigo - tooltip_disabled: Mapklarigo estas ne disponeblas por ĉi tiu tavolo + tooltip_disabled: Mapklarigo ne disponeblas por tiu ĉi tavolo map: zoom: in: Pligrandigi @@ -2285,7 +2285,7 @@ eo: hot: Hom-helpa mapo layers: header: Tavoloj de mapo - notes: Notoj pri mapo + notes: Map-rimarkoj data: Map-datumoj gps: Publikaj GPS-spuroj overlays: Aktivigu surtavolojn por solvi problemojn kun la mapo @@ -2296,7 +2296,7 @@ eo: edit_tooltip: Redakti la mapon edit_disabled_tooltip: Pligrandigu por redakti la mapon createnote_tooltip: Aldoni rimarkon al la mapo - createnote_disabled_tooltip: Pligrandigu por aldoni noton al la mapo + createnote_disabled_tooltip: Pligrandigu por aldoni rimarkon al la mapo map_notes_zoom_in_tooltip: Pligrandigu por vidi map-rimarkoj map_data_zoom_in_tooltip: Pligrandigu por vidi map-datumoj queryfeature_tooltip: Montri informoj pri objekto @@ -2310,9 +2310,9 @@ eo: unhide_comment: malkaŝi notes: new: - intro: Vi rimarkis eraron aÅ­ iu mankas? Sciigu aliajn mapigistojn, por ili + intro: Vi rimarkis eraron aÅ­ io mankas? Sciigu aliajn mapigistojn, por ili povos ripari tion. Movu la markon al la respektivan pozicion kaj enmetu - la noton priskribantan la problemon. (Bonvolu ne enmeti personajn informojn + la rimarkon priskribantan la problemon. (Bonvolu ne enmeti personajn informojn aÅ­ informojn el kopirajtaj mapoj aÅ­ fontoj.) add: Aldoni rimarkon show: @@ -2348,20 +2348,21 @@ eo: continue_without_exit: AntaÅ­en al %{name} slight_right_without_exit: Ete dekstren al %{name} offramp_right_without_exit: Veturu la elveturejon dekstre al %{name} - onramp_right_without_exit: Turnu dekstren al la elveturejo al %{name} - endofroad_right_without_exit: Ĉe la fino de la vojo turnu dekstren al %{name} - merge_right_without_exit: Turnu dekstren al %{name} - fork_right_without_exit: Ĉe la vojforko turnu dekstren al %{name} - turn_right_without_exit: Turnu dekstren al %{name} - sharp_right_without_exit: Akute dekstren al %{name} + onramp_right_without_exit: Turniĝu dekstren al la elveturejo al %{name} + endofroad_right_without_exit: Ĉe la fino de la vojo turniĝu dekstren al %{name} + merge_right_without_exit: Turniĝu dekstren al %{name} + fork_right_without_exit: Ĉe la vojforko turniĝu dekstren al %{name} + turn_right_without_exit: Turniĝu dekstren al %{name} + sharp_right_without_exit: Ege dekstren al %{name} uturn_without_exit: U-forma ĝirado laÅ­ %{name} - sharp_left_without_exit: Akute maldekstren al %{name} - turn_left_without_exit: Turnu maldekstren al %{name} + sharp_left_without_exit: Ege maldekstren al %{name} + turn_left_without_exit: Turniĝu maldekstren al %{name} offramp_left_without_exit: Veturu la elveturejon maldekstre al %{name} - onramp_left_without_exit: Turnu maldekstren al la elveturejo al %{name} - endofroad_left_without_exit: Ĉe la fino de la vojo turnu maldekstren al %{name} - merge_left_without_exit: Turnu maldekstren al %{name} - fork_left_without_exit: Ĉe la vojforko turnu maldekstren al %{name} + onramp_left_without_exit: Turniĝu maldekstren al la elveturejo al %{name} + endofroad_left_without_exit: Ĉe la fino de la vojo turniĝu maldekstren al + %{name} + merge_left_without_exit: Turniĝu maldekstren al %{name} + fork_left_without_exit: Ĉe la vojforko turniĝu maldekstren al %{name} slight_left_without_exit: Ete maldekstren al %{name} via_point_without_exit: (tra punkto) follow_without_exit: Sekvu %{name} @@ -2373,11 +2374,11 @@ eo: against_oneway_without_exit: Iru kontraÅ­-direkte al %{name} end_oneway_without_exit: Fino de unuflanka vojo ĉe %{name} roundabout_with_exit: Ĉe trafikcirklo prenu %{exit}-an elveturejon al %{name} - turn_left_with_exit: En trafikcirklo turnu maldekstren al %{name} - slight_left_with_exit: En trafikcirklo turnetu maldekstren al %{name} - turn_right_with_exit: En trafikcirklo turnu dekstren al %{name} - slight_right_with_exit: En trafikcirklo turnetu dekstren al %{name} - continue_with_exit: En trafikcirklo veturi rekten al %{name} + turn_left_with_exit: Ĉe trafikcirklo turniĝu maldekstren al %{name} + slight_left_with_exit: Ĉe trafikcirklo turniĝetu maldekstren al %{name} + turn_right_with_exit: Ĉe trafikcirklo turniĝu dekstren al %{name} + slight_right_with_exit: Ĉe trafikcirklo turniĝetu dekstren al %{name} + continue_with_exit: Ĉe trafikcirklo veturu rekten al %{name} unnamed: sennoma vojo courtesy: Kalkulado de kurso danke al %{link} time: Tempo @@ -2412,7 +2413,7 @@ eo: title: Kreado de nova korekto show: description: 'Priskribo:' - heading: Montrado de korekto "%{title}" + heading: Montrado de redakto “%{title}” title: Montrado de korekto user: 'AÅ­toro:' edit: Redakti ĉu tiun korekton diff --git a/config/locales/es.yml b/config/locales/es.yml index 79fa198f7..869e8595a 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -16,8 +16,10 @@ # Author: Idontknow # Author: Indiralena # Author: Invadinado +# Author: Javiersanp # Author: Johnarupire # Author: Jynus +# Author: KATRINE1992 # Author: Larjona # Author: Locos epraix # Author: Luzcaru @@ -419,7 +421,6 @@ es: search: title: latlon: Resultados internos - us_postcode: Resultados de Geocoder.us uk_postcode: Resultados de NPEMap / FreeThe Postcode ca_postcode: Resultados de Geocoder.CA @@ -826,7 +827,7 @@ es: antiques: Anticuario art: Tienda de artículos de arte bakery: Panadería - beauty: Tienda de productos de belleza + beauty: Salón de belleza beverages: Tienda de bebidas bicycle: Tienda de bicicletas books: Librería @@ -994,7 +995,7 @@ es: debido a trabajos de mantenimiento. osm_read_only: La base de datos de OpenStreetMap se encuentra en modo de sólo lectura debido a trabajos de mantenimiento. - donate: Apoye a OpenStreetMap %{link} al Fondo de Actualización de Hardware. + donate: Apoya a OpenStreetMap %{link} al Fondo de modernización de hardware. help: Ayuda about: Acerca de copyright: Derechos de autor @@ -1056,8 +1057,8 @@ es: more_2_html: |- A pesar de que OpenStreetMap es contenido abierto, no podemos suminstrar una API de mapas gratuita para terceros. - Consulta nuestra Política de uso del API, - Política de uso de mosaicos de mapas y Política de uso de Nominatim. + Consulta nuestra normativa de uso de la API, la + normativa de uso de mosaicos de mapas y la normativa de uso de Nominatim. contributors_title_html: Nuestros colaboradores contributors_intro_html: 'Nuestros colaboradores son miles de personas. Incluimos también datos con licencia abierta de organismos cartográficos nacionales @@ -1124,8 +1125,9 @@ es: y actuales - esto incluye millones de edificios, carreteras, y otros detalles acerca de lugares. Puede mapear cualquier característica de la vida real que es interesante para usted. - off_html: Lo que no se incluyen son datos obstinados como clasificaciones, - características históricas o hipotéticas, y datos procedentes de fuentes con + off_html: Lo que no se incluye son datos basados en opiniones (por + ejemplo, valoraciones), características históricas que ya no existen sobre + el terreno o hipotéticas, ni datos provenientes de fuentes protegidas por derechos de autor. A menos que tenga un permiso especial, no copie de mapas en línea o en papel. basic_terms: @@ -1233,9 +1235,14 @@ es: utilizan imágenes aéreas, dispositivos GPS, mapas y otras fuentes de datos libres para verificar que los datos de OSM sean precisos y estén actualizados. community_driven_title: Impulsado por la comunidad - community_driven_html: |- - La comunidad de OpenStreetMap es diversa, apasionada y creciente día a día. Nuestros colaboradores incluyen a mapeadores entusiastas, profesionales de los SIG, ingenieros que mantienen los servidores de OSM, personas con inquietudes humanitarias que cartografían zonas afectadas por desastres y muchos más. - Para aprender más acerca de la comunidad, consulte los diarios de los usuarios, blogs de la comunidad y el sitio web de la Fundación OSM. + community_driven_html: "La comunidad de OpenStreetMap es diversa y entusiasta + y crece todos los días.\nEntre nuestros colaboradores figuran cartógrafos apasionados, + profesionales de GIS, ingenieros que hacen funcionar los servidores de OSM, + humanitarios que elaboran mapas de zonas de desastre, y muchas personas más.\nPara + obtener más información sobre la comunidad, véase el \nblog + de OpenStreetMap, los diarios de los usuarios, + los blogs comunitarios y el sitio + web de la\nthe Fundación OSM." open_data_title: Datos abiertos open_data_html: 'OpenStreetMap es datos abiertos: puedes usarlo libremente para cualquier propósito, siempre y cuando des crédito a OpenStreetMap y a sus @@ -1246,8 +1253,8 @@ es: legal_html: "Este sitio y muchos otros servicios relacionados son gestionados por la \nFundación OpenStreetMap (OSMF) \nen nombre de la comunidad. El uso de todos los servicios gestionados por la - OSMF está sujeto \na nuestra \npolítica - de uso aceptable y nuestra política + OSMF está sujeto \na nuestra \nnormativa + de uso aceptable y nuestra normativa de privacidad\n
    \nContacta con la OSMF \nsi tienes preguntas o problemas sobre licencias, derechos de autor u otro tema legal." @@ -1432,6 +1439,7 @@ es: date: Fecha reply_button: Responder unread_button: Marcar como no leído + delete_button: Eliminar back: Volver to: A wrong_user: Está conectado como `%{user}' pero el mensaje que quiere leer no @@ -1484,7 +1492,7 @@ es: get_directions_title: Encontrar indicaciones entre dos puntos from: Desde to: Hacia - where_am_i: ¿Dónde estoy? + where_am_i: ¿Dónde está esto? where_am_i_title: Define la ubicación actual por medio del motor de búsqueda submit_text: Ir key: @@ -1750,7 +1758,7 @@ es: support_notice: Soportamos HMAC-SHA1 (recomendado) y firmas RSA-SHA1. edit: Editar detalles delete: Eliminar cliente - confirm: ¿Estás seguro? + confirm: ¿Lo confirmas? requests: 'Solicitando los siguientes permisos del usuario:' allow_read_prefs: leer sus preferencias de usuario. allow_write_prefs: modificar sus preferencias de usuario. @@ -1891,9 +1899,9 @@ es: email address: 'Dirección de correo electrónico:' confirm email address: 'Confirmar la dirección de correo electrónico:' not displayed publicly: Tu dirección no se muestra de forma pública (consulta - la política de privacidad - para más información) + la normativa de privacidad para más información) display name: 'Nombre en pantalla:' display name description: Tu nombre de usuario público. Puedes cambiarlo más tarde en "preferencias". @@ -2160,14 +2168,16 @@ es: grant: title: Confirmar adjudicación de función heading: Confirmar adjudicación de función - are_you_sure: ¿Seguro que deseas otorgar la función `%{role}' al usuario `%{name}'? + are_you_sure: ¿Confirmas que quieres otorgar la función «%{role}» al usuario + «%{name}»? confirm: Confirmar fail: No pudo otorgarse la función `%{role}' al usuario `%{name}'. Por favor, comprueba que el usuario y la función sean válidos. revoke: title: Confirmar revocación de función heading: Confirmar revocación de función - are_you_sure: ¿Seguro que deseas revocar la función `%{role}' del usuario `%{name}'? + are_you_sure: ¿Confirmas que quieres revocar la función «%{role}» del usuario + «%{name}»? confirm: Confirmar fail: No se pudo revocar la función `%{role}' del usuario `%{name}'. Por favor, comprueba que el usuario y la función sean válidos. @@ -2232,7 +2242,7 @@ es: heading: Revocando el bloqueo sobre %{block_on} por %{block_by} time_future: Este bloqueo finalizará en %{time}. past: Este bloqueo terminó hace %{time} y no puede ser revocado ahora. - confirm: ¿Seguro que deseas revocar este bloqueo? + confirm: ¿Confirmas que quieres revocar este bloqueo? revoke: Revocar flash: Este bloqueo ha sido revocado. period: @@ -2242,7 +2252,7 @@ es: show: Mostrar edit: Editar revoke: Revocar - confirm: ¿Está seguro? + confirm: ¿Lo confirmas? display_name: Usuario bloqueado creator_name: Creador reason: Razón del bloqueo @@ -2277,7 +2287,7 @@ es: show: Mostrar edit: Editar revoke: Revocar - confirm: ¿Está seguro? + confirm: ¿Lo confirmas? reason: 'Razón del bloqueo:' back: Ver todos los bloqueos revoker: 'Revocador:' @@ -2401,6 +2411,7 @@ es: ascend: Ascender engines: graphhopper_bicycle: En bicicleta (GraphHopper) + graphhopper_car: Auto (GraphHopper) graphhopper_foot: A pie (GraphHopper) mapquest_bicycle: En bicicleta (MapQuest) mapquest_car: En coche (MapQuest) @@ -2492,7 +2503,7 @@ es: user: 'Creador:' edit: Editar esta redacción destroy: Eliminar esta redacción - confirm: ¿Estás seguro? + confirm: ¿Lo confirmas? create: flash: Redacción creada. update: diff --git a/config/locales/et.yml b/config/locales/et.yml index ce3983ba8..dc50ac38b 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -14,7 +14,8 @@ et: time: formats: - friendly: '%e %B %Y kell %H:%M' + friendly: '%e. %B %Y, kell %H:%M' + blog: '%e. %B %Y' activerecord: models: acl: Pääsuloend @@ -40,9 +41,9 @@ et: relation_member: Relatsiooni liige relation_tag: Relatsiooni silt session: Seanss - trace: Jälg - tracepoint: Jälje punkt - tracetag: Jälje silt + trace: Rada + tracepoint: Rajapunkt + tracetag: Rajasilt user: Kasutaja user_preference: Kasutaja eelistused user_token: Kasutaja tunnus @@ -118,11 +119,11 @@ et: title: 'Muudatuskogum: %{id}' belongs_to: Autor node: Sõlmed (%{count}) - node_paginated: Sõlmed (%{x}-%{y}/%{count}) + node_paginated: Sõlmed (%{x}–%{y} %{count}-st) way: Jooned (%{count}) - way_paginated: Jooned (%{x}-%{y}/%{count}) + way_paginated: Jooned (%{x}–%{y} %{count}-st) relation: Relatsioonid (%{count}) - relation_paginated: Relatsioonid (%{x}-%{y}/%{count}) + relation_paginated: Relatsioonid (%{x}–%{y} %{count}-st) comment: Kommentaare (%{count}) hidden_commented_by: Peidetud kommentaar kasutajalt %{user} %{when} tagasi @@ -143,8 +144,8 @@ et: history_title: 'Joone ajalugu: %{name}' nodes: Sõlmed also_part_of: - one: on osa joonest %{related_ways} - other: on osa joontest %{related_ways} + one: osa joonest %{related_ways} + other: osa joontest %{related_ways} relation: title: 'Relatsioon: %{name}' history_title: 'Relatsiooni ajalugu: %{name}' @@ -271,7 +272,7 @@ et: in_language_title: Päeviku sissekanded %{language} new: Uus päeviku sissekanne new_title: Lisa päevikusse uus sissekanne - no_entries: Päevikus pole sissekandeid + no_entries: Päevikus pole sissekandeid. recent_entries: Hiljutised päeviku sissekanded older_entries: Vanemad... newer_entries: Uuemad... @@ -295,7 +296,7 @@ et: save_button: Salvesta no_such_entry: title: Sellist päeviku sissekannet pole olemas - heading: Sissekannet id'ga %{id} pole olemas + heading: Sissekannet ID-ga %{id} pole olemas body: Kahjuks ei leidu päeviku sissekannet või kommentaari id-ga %{id}. Kontrolli sisestatud lingi õigekirja. Võimalik, et link millele sa vajutasid on vigane. diary_entry: @@ -342,18 +343,18 @@ et: area_to_export: Eksporditav ala manually_select: Vali käsitsi teine ala format_to_export: Eksporditav vorming - osm_xml_data: OpenStreetMapi andmed XML kujul + osm_xml_data: OpenStreetMapi andmed XML-kujul map_image: Kaardi pilt (kuvab tavakaardi) embeddable_html: Põimitav HTML licence: Litsents - export_details: OpenStreetMapi andmed on avaldatud Open - Data Commons Open Database litsentsi tingimustel. + export_details: OpenStreetMapi andmed on avaldatud litsentsi Open + Data Commons Open Database License (ODbL) tingimustel. too_large: advice: 'Kui ülaltoodu eksportimine ebaõnnestub, siis kasuta palun ühte alljärgnevatest allikatest:' - body: See ala on liiga suur, et eksportida OpenStreetMapi andmeid XML kujul. - Palun suurenda või vali väiksem ala või kasuta ühte allikatest suurte andmehulkade - allalaadimiseks. + body: See ala on liiga suur, et eksportida OpenStreetMapi andmeid XML-kujul. + Palun suurenda või vali väiksem ala või kasuta üht allpool loetletud allikatest, + et laadida alla suuri andmehulki. planet: title: Planet OSM description: Regulaarselt uuendatavad koopiad tervest OpenStreetMapi andmebaasist @@ -386,7 +387,6 @@ et: search: title: latlon: Sisemised tulemused - us_postcode: Geocoder.us tulemused uk_postcode: ' NPEMap / FreeThe Postcode tulemused' ca_postcode: Geocoder.CA tulemused @@ -1130,11 +1130,12 @@ et: footer: Loe kommentaari lehel %{readurl}. Võid lisada oma kommentaari lehel %{commenturl} või vastata kommentaarile lehel %{replyurl}. message_notification: - hi: Tere, %{to_user}, + hi: Tere, %{to_user} header: '%{from_user} on saatnud sulle OpenStreetMapi kaudu sõnumi teemaga %{subject}:' footer_html: Sõnumit võib lugeda samuti lehel %{readurl} ja vastata sellele %{replyurl}. friend_notification: + hi: Tere, %{to_user} subject: '[OpenStreetMap] %{user} lisas sind oma sõbraks' had_added_you: '%{user} lisas sind OpenStreetMapis sõbraks.' see_their_profile: Tema profiiliga võid tutvuda aadressil %{userurl}. @@ -1157,7 +1158,7 @@ et: signup_confirm: subject: '[OpenStreetMap] Tere tulemast OpenStreetMapi' greeting: Tere! - created: Keegi (loodetavasti sina) lõi äsja %{site_url} kasutajakonto. + created: Keegi (loodetavasti sina) lõi äsja saidil %{site_url} kasutajakonto. confirm: 'Enne kasutajakonto loomist peame saama kinnituse, et see taotlus tuli sinult ja selleks klõpsa alloleval lingil:' welcome: Peale seda, kui oled kinnitanud enda konto pakume sulle lisainfot, @@ -1166,30 +1167,30 @@ et: subject: '[OpenStreetMap] Kinnita oma e-posti aadress' email_confirm_plain: greeting: Tere! - hopefully_you: Keegi (loodetavasti sina) soovib muuta oma %{server_url} meiliaadressi - kujule %{new_address}. - click_the_link: Kui see oled sina, siis palun kliki allolevale lingile muudatuse - kinnitamiseks. + hopefully_you: Keegi (loodetavasti sina) soovib muuta oma meiliaadressi asukohas + %{server_url} kujule %{new_address}. + click_the_link: Kui see oled sina, siis klõpsa palun alloleval lingil, et muudatus + kinnitada. email_confirm_html: greeting: Tere! - hopefully_you: Keegi (loodetavasti sina) soovib muuta oma %{server_url} meiliaadressi - kujule %{new_address}. - click_the_link: Kui see oled sina, siis palun kliki allolevale lingile muudatuse - kinnitamiseks. + hopefully_you: Keegi (loodetavasti sina) soovib muuta oma meiliaadressi asukohas + %{server_url} kujule %{new_address}. + click_the_link: Kui see oled sina, siis klõpsa palun alloleval lingil, et muudatus + kinnitada. lost_password: subject: '[OpenStreetMap] Parooli lähtestamise taotlus' lost_password_plain: greeting: Tere! - hopefully_you: Keegi (tõenäoliselt sina) on esitanud taotluse oma parooli lähtestamiseks - antud meiliaadressiga openstreetmap.org kasutajakonto alt. - click_the_link: Kui see oled sina, siis palun kliki allaolevale lingile oma - parooli lähtestamiseks. + hopefully_you: Keegi (tõenäoliselt sina) on esitanud taotluse, et lähtestada + selle e-posti aadressiga openstreetmap.org-i konto parool. + click_the_link: Kui see oled sina, siis klõpsa palun alloleval lingil, et parool + lähtestada. lost_password_html: greeting: Tere! - hopefully_you: Keegi (tõenäoliselt sina) on esitanud taotluse oma parooli lähtestamiseks - antud meiliaadressiga openstreetmap.org kasutajakonto alt. - click_the_link: Kui see oled sina, siis palun kliki allaolevale lingile oma - parooli lähtestamiseks. + hopefully_you: Keegi (tõenäoliselt sina) on esitanud taotluse, et lähtestada + selle e-posti aadressiga openstreetmap.org-i konto parool. + click_the_link: Kui see oled sina, siis klõpsa palun alloleval lingil, et parool + lähtestada. note_comment_notification: anonymous: Anonüümne kasutaja greeting: Tere! @@ -1197,26 +1198,28 @@ et: subject_own: '[OpenStreetMap] %{commenter} on kommenteerinud ühte sinu märkust' subject_other: '[OpenStreetMap] %{commenter} on kommenteerinud märkust, millest oled huvitatud' - your_note: '%{commenter} on jätnud kommentaari ühele sinu %{place} lähedal - olevale märkusele.' - commented_note: '%{commenter} on jätnud kommentaari märkusele mida sa oled - kommenteerinud. Märkus on %{place} lähedal.' + your_note: '%{commenter} on jätnud kommentaari ühele sinu märkusele koha %{place} + lähedal.' + commented_note: '%{commenter} on jätnud kommentaari märkusele, mida oled kommenteerinud. + Märkus on koha %{place} lähedal.' closed: - subject_own: '[OpenStreetMap]%{commenter} on lahendanud ühe sinu märkuse' - subject_other: '[OpenStreetMap]%{commenter} on lahendanud ühe märkuse millest - sa huvitatud oled' - your_note: '%{commenter} on lahendanud ühe sinu märkuse %{place} lähedal.' - commented_note: '%{commenter} on lahendanud märkuse, mida sa oled kommenteerinud. - Märkus on %{place} lähedal.' + subject_own: '[OpenStreetMap] %{commenter} on lahendanud ühe sinu märkuse' + subject_other: '[OpenStreetMap] %{commenter} on lahendanud ühe märkuse, millest + oled huvitatud' + your_note: '%{commenter} on lahendanud ühe sinu märkuse koha %{place} lähedal.' + commented_note: '%{commenter} on lahendanud märkuse, mida oled kommenteerinud. + Märkus on koha %{place} lähedal.' reopened: subject_own: '[OpenStreetMap] %{commenter} on taasaktiveerinud ühe sinu märkustest' subject_other: '[OpenStreetMap] %{commenter} on taasaktiveerinud ühe märkuse, millest sa huvitatud oled' - your_note: '%{commenter} on taasaktiveerinud ühe sinu märkuse %{place} lähedal.' - commented_note: '%{commenter} on taasaktiveerinud märkuse, mida sa oled kommenteerinud. - Märkus on %{place} lähedal.' - details: Märkuse lisateavet leiad %{url}. + your_note: '%{commenter} on taasaktiveerinud ühe sinu märkuse koha %{place} + lähedal.' + commented_note: '%{commenter} on taasaktiveerinud märkuse, mida oled kommenteerinud. + Märkus on koha %{place} lähedal.' + details: Lisateavet märkuse kohta leiad aadressilt %{url}. changeset_comment_notification: + hi: Tere, %{to_user} greeting: Tere! commented: subject_own: '[OpenStreetMap] %{commenter} on kommenteerinud üht sinu muudatuskogumit' @@ -1226,6 +1229,11 @@ et: mis on loodud kuupäeval %{time}' commented_changeset: '%{commenter} on jätnud kommentaari kaardi muudatuskogumile, mida sa jälgid ja mille on loonud %{changeset_author} kuupäeval %{time}' + partial_changeset_with_comment: kommentaariga '%{changeset_comment}'. + partial_changeset_without_comment: ilma kommentaarita. + details: Üksikasjad muudatuskogumi kohta leiad aadressilt %{url}. + unsubscribe: Et selle muudatuskogumi uuendusteadetest ära ütelda, mine aadressile + %{url} ja klõpsa nuppu "Lõpeta tellimus". message: inbox: title: Saabunud kirjad @@ -1250,11 +1258,11 @@ et: delete_button: Kustuta new: title: Saada sõnum - send_message_to: Saada kasutajale %{name} uus sõnum + send_message_to: Sõnumi saatmine kasutajale %{name} subject: Teema body: Sisu send_button: Saada - back_to_inbox: Tagasi saabunud kirjade juurde + back_to_inbox: Tagasi minu postkasti message_sent: Sõnum saadetud limit_exceeded: Sa oled hiljuti saatnud palju sõnumeid. Palun oota mõnda aega enne kui proovid veel sõnumeid saata. @@ -1346,6 +1354,7 @@ et: table: entry: motorway: Kiirtee + main_road: Peatee trunk: Esimese klassi tee primary: Põhimaantee secondary: Tugimaantee @@ -1425,12 +1434,12 @@ et: trace: visibility: private: Privaatne (jagatud ainult anonüümselt, järjestamata punktid) - public: Avalik (nähtav jälgede loendis ja anonüümsena, järjestamata punktid) + public: Avalik (nähtav rajaloendis ja anonüümsena, järjestamata punktid) trackable: Jälgitav (jagatud ainult anonüümselt, järjestatud punktid koos ajatemplitega) - identifiable: Tuvastatav (nähtav jälgede loendis ja tuvastatav, järjestatud - punktid koos ajatemplitega) + identifiable: Tuvastatav (nähtav rajaloendis ja tuvastatav, järjestatud punktid + koos ajatemplitega) create: - upload_trace: Laadi üles GPS-rada + upload_trace: GPS-raja üleslaadimine trace_uploaded: Sinu GPX-fail on üles laaditud ja ootab andmebaasi sisestamist. See võtab aega tavaliselt pool tundi kuni tund. Peale lõpetamist saadetakse sulle meil. @@ -1448,7 +1457,7 @@ et: tags_help: komaga eraldatud save_button: Salvesta muudatused visibility: 'Nähtavus:' - visibility_help: Mida see tähendab? + visibility_help: mida see tähendab? trace_form: upload_gpx: 'Laadi üles GPX-fail:' description: 'Kirjeldus:' @@ -1465,6 +1474,8 @@ et: trace_optionals: tags: Sildid view: + title: Raja %{name} vaatamine + heading: Raja %{name} vaatamine pending: OOTEL filename: 'Failinimi:' download: laadi alla @@ -1478,19 +1489,19 @@ et: tags: 'Sildid:' none: Puuduvad edit_track: Muuda seda rada - delete_track: Kustuta see jälg - trace_not_found: Jälge ei leitud! + delete_track: Kustuta see rada + trace_not_found: Rada ei leitud! visibility: 'Nähtavus:' trace_paging_nav: showing_page: Leht %{page} - older: Vanemad jäljed - newer: Uuemad jäljed + older: Vanemad rajad + newer: Uuemad rajad trace: pending: OOTEL count_points: '%{count} punkti' ago: '%{time_in_words_ago} tagasi' more: rohkem - trace_details: Vaata jälje teavet + trace_details: Vaata raja üksikasju view_map: Vaata kaarti edit: redigeeri edit_map: Redigeeri kaarti @@ -1505,12 +1516,14 @@ et: public_traces: Avalikud GPS-rajad your_traces: Sinu GPS-rajad public_traces_from: Kasutaja %{user} avalikud GPS-rajad - description: Sirvi viimati üles laaditud GPS-radasid + description: Viimati üles laaditud GPS-radade sirvimine tagged_with: ', millel on silt %{tags}' + empty_html: Siin pole veel midagi. Laadi üles uus rada + või uuri GPS-radade kohta vikileheküljelt. application: require_cookies: - cookies_needed: Sul on ilmselt küpsised keelatud - palun luba brauseris küpsised - enne jätkamist. + cookies_needed: Paistab, et sul on küpsised keelatud. Enne jätkamist luba palun + brauseris küpsised. require_moderator: not_a_moderator: Selle tegevuse sooritamiseks pead sa olema moderaator. setup_user_auth: @@ -1522,17 +1535,18 @@ et: oauth: oauthorize: title: Lubada juurdepääs sinu kontole - request_access: See rakendus %{app_name} taotleb juurdepääsu sinu kasutajakontole, - %{user}. Palun kontrolli, kas sa soovid, et rakendus omaks järgmisi võimalusi. - Sa võid valida neist nii palju või vähe kui soovid. + request_access: Rakendus %{app_name} taotleb juurdepääsu sinu kontole %{user}. + Palun kontrolli, kas soovid, et rakendusel oleks järgmised võimalused. Võid + valida neist nii palju või vähe kui soovid. allow_to: 'Klientrakendusel lubatakse:' allow_read_prefs: lugeda sinu kasutajaeelistusi. allow_write_prefs: muuta sinu kasutajaeelistusi. allow_write_diary: luua päeviku sissekandeid, kommentaare ja saada sõbraks. allow_write_api: muuta kaarti. - allow_read_gpx: lugeda sinu privaatseid GPS jälgi. - allow_write_gpx: laadida üles GPS jälgi. + allow_read_gpx: lugeda sinu privaatseid GPS-radu. + allow_write_gpx: laadida üles GPS-radu. allow_write_notes: muuta märkuseid. + grant_access: Luba juurdepääs oauthorize_success: title: Autoriseerimise taotlemine on lubatud allowed: Oled andnud rakendusele %{app_name} juurdepääsu oma kontole. @@ -1542,7 +1556,7 @@ et: denied: Oled keelanud rakendusele %{app_name} juurdepääsu oma kontole. invalid: Autoriseerimisluba ei ole kehtiv. revoke: - flash: Oled tühistanud %{application} tõendi + flash: Oled tühistanud rakenduse %{application} loa. oauth_clients: new: title: Registreeri uus rakendus @@ -1572,7 +1586,7 @@ et: index: title: Minu OAuthi üksikasjad my_tokens: Minu autoriseeritud rakendused - list_tokens: 'Järgmised turvamärgid on rakendustele väljastatud sinu nime all:' + list_tokens: 'Sinu nimel on rakendustele väljastatud järgmised load:' application: Rakenduse nimi issued_at: Väljastatud revoke: Tühista! @@ -1731,7 +1745,7 @@ et: my diary: Minu päevik new diary entry: uus päevikusissekanne my edits: Minu muutmised - my traces: Minu jäljelogid + my traces: Minu rajaloend my notes: Minu märkused my messages: Minu sõnumid my profile: Minu profiil @@ -1743,10 +1757,10 @@ et: send message: Saada sõnum diary: Päevik edits: Muudatused - traces: Jäljelogid + traces: Rajaloend notes: Märkused remove as friend: eemalda sõprade hulgast - add as friend: lisa sõbraks + add as friend: Lisa sõbraks mapper since: 'Kaardistaja alates:' ago: (%{time_in_words_ago} tagasi) ct status: 'Kaastöötingimused:' @@ -1781,7 +1795,7 @@ et: moderator: Eemalda moderaatori õigused block_history: Aktiivsed blokeeringud moderator_history: Antud blokeeringud - comments: kommentaarid + comments: Kommentaarid create_block: Blokeeri see kasutaja activate_user: Aktiveeri see kasutaja deactivate_user: Desaktiveeri see kasutaja @@ -1907,22 +1921,23 @@ et: showing: one: Lehekülg %{page} (%{first_item} / %{items}) other: Lehekülg %{page} (%{first_item}-%{last_item} / %{items}) - summary: '%{name} loodud ip aadressilt %{ip_address} %{date}' - summary_no_ip: '%{name} loodud %{date}' + summary: '%{name} loodud IP-aadressilt %{ip_address} (%{date})' + summary_no_ip: '%{name} loodud (%{date})' confirm: Kinnita valitud kasutajad hide: Peida valitud Kasutajad empty: Sobivaid kasutajaid ei leitud! suspended: title: Konto peatatud heading: Konto peatatud - webmaster: Veebiülem + webmaster: veebimeistriga body: |-

    - Vabandame, teie konto on automaatselt peatatud kahtlase tegevuse tõttu. + Vabandust, sinu konto õigused on automaatselt peatatud + kahtlase tegevuse tõttu.

    - Käesolev otsus vaadatakse administraatori poolt peatselt üle, või - võite kontakteeruda %{webmaster} kui soovite seda arutada. + Administraator vaatab selle otsuse peagi üle. Kui soovid + seda arutada, siis võid võtta ühendust %{webmaster}.

    auth_failure: no_authorization_code: Autoriseerimiskood puudub @@ -2008,8 +2023,8 @@ et: heading: Kasutaja blokeeringute loetelu empty: Ühtegi blokeeringut pole veel antud. revoke: - title: Blokeeringu %{block_on} eemaldamine - heading: Blokeeringu %{block_on} eemaldamine, mille oli andnud %{block_by} + title: Kasutaja %{block_on} blokeeringu eemaldamine + heading: Kasutaja %{block_on} blokeeringu eemaldamine (blokeerinud %{block_by}) time_future: See blokeering lõpeb %{time} pärast. past: See blokeering lõppes %{time} tagasi ja seda ei saa enam tagasi võtta. confirm: Kas oled kindel, et soovid seda blokeeringut tühistada? @@ -2041,12 +2056,12 @@ et: heading: Kasutaja %{name} blokeeringud empty: Kasutajat %{name} ei ole veel kordagi blokeeritud. blocks_by: - title: Kasutaja %{name} antud blokeeringud - heading: Kasutaja %{name} antud blokeeringud - empty: Kasutaja %{name} ei ole veel andnud ühtegi blokeeringut. + title: Kasutaja %{name} seatud blokeeringud + heading: Kasutaja %{name} seatud blokeeringud + empty: Kasutaja %{name} pole veel kedagi blokeerinud. show: - title: '%{block_on} blokeeritud kasutaja %{block_by} poolt' - heading: '%{block_on} blokeeritud kasutaja %{block_by} poolt' + title: 'Blokeeritud: %{block_on} (blokeerinud %{block_by})' + heading: 'Blokeeritud: %{block_on} (blokeerinud %{block_by})' time_future: Lõpeb %{time} time_past: Lõppes %{time} tagasi created: Loodud @@ -2187,7 +2202,7 @@ et: distance: Vahemaa errors: no_route: Ei suutnud leida teekonda nende kahe koha vahel. - no_place: Vabandust - ei suuda leida sellist kohta. + no_place: Seda kohta kahjuks ei leitud. instructions: unnamed: nimetu time: Kestus @@ -2233,8 +2248,8 @@ et: update: flash: Salvestati muudatused. destroy: - not_empty: Redaktsioon ei ole tühi. Palun eemaldage enne selle hävitamist kõik - versioonid, mis kuuluvad selle redaktsiooni alla. + not_empty: Redaktsioon ei ole tühi. Palun eemalda enne redaktsiooni hävitamist + kõik versioonid, mis selle alla kuuluvad. flash: Redaktsioon hävitatud. error: Viga selle redaktsiooni hävitamisel. ... diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 4bd91d382..35d9092b0 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -5,10 +5,12 @@ # Author: An13sa # Author: Asieriko # Author: Gorkaazk +# Author: Mikel Ibaiba # Author: MikelEH # Author: PerroVerd # Author: Subi # Author: Theklan +# Author: Txopi # Author: Xabier Armendaritz --- eu: @@ -17,26 +19,42 @@ eu: friendly: '%e %B %Y %H:%M-ean' activerecord: models: + acl: Kontrol Zerrendara Sartu + changeset: Aldaketak + changeset_tag: Etiketa Aldaketa country: Herrialdea + diary_comment: Eguneroko iruzkina + diary_entry: Eguneroko sarrera friend: Laguna language: Hizkuntza message: Mezua node: Nodo node_tag: Nodoaren etiketa + notifier: Jakinarazpentzailea old_node: Nodo zaharra + old_node_tag: Nodo Etiketa Zaharra old_relation: Erlazio zaharra + old_relation_member: Erlazio Zaharreko Kidea + old_relation_tag: Erlazio Zaharreko Etiketa old_way: Bide zaharra + old_way_node: Nodo Bide Zaharra + old_way_tag: Bide Zahar Etiketa relation: Erlazioa + relation_member: Erlazio Kidea + relation_tag: Erlazio Etiketa session: Saioa trace: Trazoa tracepoint: Trazo puntua tracetag: Trazo etiketa - user: Lankide + user: Erabiltzailea + user_preference: Erabiltzaile hobespenak + user_token: Erabiltzaile token-a way: Bidea + way_node: Nodo Bidea way_tag: Bidearen etiketa attributes: diary_comment: - body: Testua + body: Gorputza diary_entry: user: Erabiltzailea title: Gaia @@ -62,56 +80,125 @@ eu: recipient: Hartzailea user: email: Eposta + active: Aktibo + display_name: Erakusteko izena description: Deskribapen languages: Hizkuntzak pass_crypt: Pasahitza editor: + default: Lehenetsia (orain %{name}) potlatch: name: Potlatch 1 + description: Potlatch 1 (nabigatzaile barneko editorea) + id: + name: iD-a + description: iD (nabigatzaile barneko editorea) potlatch2: name: Potlatch 2 + description: Potlatch 2 (nabigatzaile barneko editorea) remote: - name: Urrutiko Agintea + name: Urrutiko agintea description: Urrutiko kontrola (JOSM edo Merkaartor) browse: created: Sortua closed: Itxita created_html: Duela %{time} sortua closed_html: Duela %{time} itxia + created_by_html: '%{user} erabiltzaileak duela %{time} + sortua' + deleted_by_html: '%{user} erabiltzaileak duela %{time} + ezabatua' + edited_by_html: '%{user} erabiltzaileak duela %{time} + aldatua' + closed_by_html: '%{user} erabiltzaileak duela %{time} + itxia' version: Bertsioa + in_changeset: Aldaketak anonymous: anonimoa no_comment: (iruzkinik gabe) + part_of: Zati bat download_xml: XML deskargatu view_history: Ikusi historia - view_details: Ikusi Xehetasunak + view_details: Ikusi xehetasunak location: 'Kokapena:' changeset: + title: 'Aldaketa: %{id}' belongs_to: Egilea + node: Nodoak (%{count}) + node_paginated: (%{count}ren) %{x}-%{y} nodoak + way: Bideak (%{count}) + way_paginated: Bideak (%{count}ren %{x}-%{y}) + relation: Erlazioak (%{count}) + relation_paginated: Erlazioak (%{count}ren %{x}-%{y}) + comment: Iruzkinak (%{count}) + hidden_commented_by: '%{user} erabiltzaileak egindako duela %{when} + iruzkin ezkutua' + commented_by: '%{user} erabiltzaileak egindako iruzkina duela %{when}' + changesetxml: XML aldaketak + osmchangexml: XML osm-aldaketa + feed: + title: '%{id} aldaketak' + title_comment: '%{id} - %{comment} aldaketak' + join_discussion: Hasi saioa eztabaidan parte hartzeko discussion: Eztabaida + node: + title: 'Nodoa: %{name}' + history_title: 'Nodoaren historia: %{name}' way: + title: 'Bidea: %{name}' + history_title: 'Bidearen historia: %{name}' nodes: Nodoak + also_part_of: + one: bidearen zatia %{related_ways} + other: bideen zatia %{related_ways} relation: + title: 'Erlazioa: %{name}' + history_title: 'Erlazioaren historia: %{name}' members: Kideak relation_member: + entry_role: '%{type} %{name} %{role} bezala' type: node: Nodo way: Bide relation: Erlazio containing_relation: entry: '%{relation_name} erlazioa' + entry_role: '%{relation_name} erlazioa (%{relation_role} bezala)' not_found: + sorry: 'Barkatu, %{type} #%{id} ezin izan da aurkitu.' type: node: nodo way: bide relation: erlazio + changeset: aldaketak + note: oharra timeout: + sorry: Barkatu, %{id} daukan %{type}rako datuak berreskuratzeko denbora asko + behar izan da. + type: + node: nodo + way: bide + relation: erlazio + changeset: aldaketak + note: oharra + redacted: + redaction: '%{id} erredakzioa' + message_html: '%{type} honetako %{version} bertsioa ezin da ikusi erredaktatu + bezala. Xehetasunetarako %{redaction_link} ikusi mesedez.' type: + node: nodo + way: bide relation: erlazio start_rjs: + feature_warning: '%{num_features} funtzioak kargatzen, zure arakatzailea motela + edo erantzungabekoa izan ez dadin. Ziur datuak bistaratu nahi dituzula?' load_data: Kargatu datuak loading: Kargatzen... tag_details: tags: Etiketak + wiki_link: + key: '%{key} etiketarako wiki deskribapen orria' + tag: '%{key}=%{value} etiketarako wiki deskribapen orria' wikidata_link: '%{page} elementua Wikidatan' wikipedia_link: '%{page} artikulua Wikipedian' telephone_link: Deitu %{phone_number} zenbakira @@ -119,6 +206,30 @@ eu: title: 'Oharra: %{id}' new_note: Ohar berria description: Deskribapena + open_title: 'Konpondugabeko #%{note_name} oharra' + closed_title: 'Konpondutako #%{note_name} oharra' + hidden_title: 'Ezkutatuko #%{note_name} oharra' + open_by: '%{user} erabiltzaileak duela %{when} + sortua' + open_by_anonymous: Erabiltzaile ezezagun batek duela %{when} + sortua + commented_by: '%{user} duela %{when} egindako + iruzkina' + commented_by_anonymous: Erabiltzaile ezezagun batek duela %{when} + egindako iruzkina + closed_by: '%{user} erabiltzaileak duela %{when} + konpondua' + closed_by_anonymous: Erabiltzaile ezezagun batek duela %{when} + konpondua + reopened_by: '%{user} erabiltzaileak duela %{when} + berraktibatua' + reopened_by_anonymous: Ezezagun batek berraktibatua duela %{when} + hidden_by: '%{user} erabiltzaileak ezkutatua duela %{when}' + query: + title: Eskaeraren ezaugarriak + introduction: Egin klik mapan hurbileko ezaugarriak aurkitzeko. + nearby: Hurbileko ezaugarriak + enclosing: Bildutako ezaugarriak changeset: changeset_paging_nav: showing_page: '%{page}. orrialdea' @@ -127,6 +238,7 @@ eu: changeset: anonymous: Anonimoa no_edits: (aldaketarik gabe) + view_changeset_details: Ikusi aldaketen xehetasunak changesets: id: ID saved_at: Noiz gordeta @@ -134,36 +246,69 @@ eu: comment: Iruzkina area: Eremua list: + title: Aldaketak + title_user: '%{user}k egindako aldaketak' + title_friend: Zure lagunek egindako aldaketak + title_nearby: Hurbil dauden erabiltzaileek egindako aldaketak + empty: Ez da aldaketarik aurkitu. + empty_area: Inguru honetan ez dago aldaketarik. + empty_user: Erabiltzaile honek ez du aldaketarik egin. + no_more: Aldaketa gehiagorik ez da aurkitu. + no_more_area: Inguru honetan ez dago aldaketa gehiagorik. + no_more_user: Erabiltzaile honek ez du aldaketa gehiagorik egin. load_more: Gehiago kargatu + timeout: + sorry: Barkatu, zuk eskatutako aldaketen zerrenda berreskuratzeko denbora gehiegi + behar izan da. rss: + title_all: OpenStreetMap aldaketen eztabaida + title_particular: 'OpenStreetMap #%{changeset_id} eztabaida aldatu egin du.' + comment: '%{changeset_id} aldaketan %{author} iruzkin berria egin du' commented_at_html: Eguneratua duela %{when} - commented_at_by_html: '%{user}-ek duela %{when} eguneratua' + commented_at_by_html: '%{user} erabiltzaileak duela %{when} eguneratua' full: Eztabaida osoa diary_entry: new: + title: Eguneroko Sarrera Berria publish_button: Argitaratu list: title: Erabiltzaileen egunerokoak title_friends: Lagunen egunerokoak title_nearby: Hurbileko erabiltzaileen egunerokoak user_title: '%{user}(r)en egunerokoa' + in_language_title: Eguneroko Sarrerak %{language} hizkuntzan + new: Eguneroko sarrera berria + new_title: Zure erabiltzaile egunerokoan sarrera berri bat sortu + no_entries: Eguneroko sarrerarik ez + recent_entries: Azkenengoko eguneroko sarrerak older_entries: Sarrera zaharragoak newer_entries: Sarrera berriagoak edit: + title: Eguneroko sarrera aldatu subject: 'Gaia:' body: 'Testua:' language: 'Hizkuntza:' - location: Kokapena - latitude: 'Latitude:' - longitude: 'Longitude:' - use_map_link: mapa erabili + location: 'Kokapena:' + latitude: 'Latitudea:' + longitude: 'Longitudea:' + use_map_link: erabili mapa save_button: Gorde + marker_text: Eguneroko sarrera helbidea view: + title: '%{user}(r)en egunerokoa | %{title}' user_title: '%{user}(r)en egunerokoa' leave_a_comment: Iruzkin bat utzi - login: Saioa hasi + login_to_leave_a_comment: '%{login_link} iruzkin bat uzteko' + login: Hasi saioa save_button: Gorde + no_such_entry: + title: Ez dago horrelako eguneroko sarrerarik + heading: '%{id} id-arekin ez dago sarrerarik' + body: Barkatu, %{id} id-arekin ez dago eguneroko sarrerarik edo iruzkinik. Zure + hizkera egiaztatu mesedez, edo beharbada klik egin duzun esteka gaizki dago. diary_entry: + posted_by: '%{link_user}k %{created}n argitaratua %{language_link} hizkuntzan' + comment_link: Sarrera honetan iruzkina utzi reply_link: Sarrera honi erantzun comment_count: one: iruzkin %{count} @@ -171,15 +316,29 @@ eu: other: '%{count} iruzkin' edit_link: Sarrera hau editatu hide_link: Sarrera hau ezkutatu - confirm: Berretsi + confirm: Baieztatu diary_comment: - hide_link: Iruzkin hau ezkutatu + comment_from: '%{link_user} erabiltzailearen iruzkina %{comment_created_at}n' + hide_link: Ezkutatu iruzkin hau confirm: Baieztatu location: location: 'Kokapena:' view: Ikusi edit: Aldatu + feed: + user: + title: '%{user} erabiltzailearentzako OpenStreetMap eguneroko sarrerak' + description: '%{user} erabiltzailearen azkeneko OpenStreetMap eguneroko sarrerak' + language: + title: '%{language_name} hizkuntzan egindako OpenStreetMap eguneroko sarrerak' + description: '%{language_name} hizkuntzan OpenStreetMap erabiltzaileek azkenaldian + egindako eguneroko sarrerak' + all: + title: OpenStreetMap eguneroko sarrerak + description: OpenStreetMap erabiltzaileek azkenaldian egindako eguneroko sarrerak comments: + has_commented_on: Hurrengo eguneroko sarreretan iruzkinak egin ditu %{display_name}k + post: Argitaratu when: Noiz comment: Iruzkina ago: Duela %{ago} @@ -188,73 +347,108 @@ eu: export: title: Esportatu start: - area_to_export: Esportatzeko eremua + area_to_export: Esportatu beharreko eremua manually_select: Aukeratu eskuz eremu ezberdin bat format_to_export: Esportatzeko formatua - osm_xml_data: OpenStreetMap XML Data - map_image: Maparen Irudia (geruza estandarra erakusten du) - embeddable_html: HTML integragarria + osm_xml_data: OpenStreetMap XML Datuak + map_image: Maparen irudia (geruza estandarra erakusten du) + embeddable_html: HTML kapsulagarria licence: Lizentzia export_details: OpenStreetMap-eko datuak Open Data Commons Datu-base Irekiko Lizentzia baimen baten mende daude. too_large: + advice: 'Goiko esportazioak kale egiten badu, behean zerrendatutako iturrietako + bat erabiltzea kontuan hartu mesedez:' + body: Area hau oso handia da OpenStreetMap XML datu bezala esportatzeko. Zooma + handitu edo eremu txikiagoa hautatu edo behean zerrendatutako iturrietako + bat erabili datuak bulkatze-deskargak egiteko mesedez. planet: title: OSM Planeta + description: OpenStreetMap datu-base osoko aldizkako kopia eguneratuak overpass: title: Overpass API + description: Deskargatu muga kutxa hau OpenStreetMap datu-basearen ispilu + batetik geofabrik: title: Geofabrik Deskargak + description: Kontinenteen, herrialdeen eta hautatutako hirien laburpen eguneratuak + maiztasun handiz + metro: + title: Metro Laburpenak + description: Munduko hiri handienetako eta inguruko hirien laburpenak other: - title: Bestelako Jatorriak + title: Bestelako Iturriak + description: OpenStreetMap wikian zerrendatutako iturri osagarriak options: Aukerak format: Formatua scale: Eskala max: max image_size: Irudiaren tamaina zoom: Zooma + add_marker: Mapari markatzailea gehitu latitude: 'Lat:' longitude: 'Lon:' output: Irteera + paste_html: Itsatsi HTMLa webgunean kapsulatzeko export_button: Esportatu geocoder: + search: + title: + latlon: 'Emaitzak hemendik: Internal' + uk_postcode: 'Emaitzak hemendik: NPEMap + / FreeThe Postcode' + ca_postcode: 'Emaitzak hemendik: Geocoder.CA' + osm_nominatim: 'Emaitzak hemendik: OpenStreetMap + Nominatim' + geonames: 'Emaitzak hemendik: GeoNames' + osm_nominatim_reverse: 'Emaitzak hemendik: OpenStreetMap + Nominatim' + geonames_reverse: 'Emaitzak hemendik: GeoNames' search_osm_nominatim: prefix: aerialway: cable_car: Teleferikoa chair_lift: Teleaulkia + drag_lift: Arrastatuzko Igogailua + gondola: Gondola Igogailua + station: Antena Estazioa aeroway: aerodrome: Aerodromoa apron: Pista gate: Atea helipad: Heliportua runway: Lurreratze pista + taxiway: Taxi bidea terminal: Terminala amenity: + animal_shelter: Animalia Aterpea arts_centre: Arte Zentroa atm: Kutxazain automatikoa bank: Banku bar: Taberna bbq: Barbakoa - bench: Eserleku + bench: Bankua bicycle_parking: Txirrinduentzako aparkalekua bicycle_rental: Txirrindu Alokairua biergarten: Terraza boat_rental: Txalupen alokairua brothel: Putetxea bureau_de_change: Diru-truke Bulegoa - bus_station: Autobus-geltoki - cafe: Kafetegi - car_rental: Ibilgailu-alokairu + bus_station: Autobus-geltokia + cafe: Kafetegia + car_rental: Ibilgailu-alokairua car_sharing: Autoa partekatzea car_wash: Auto Garbiketa casino: Kasinoa + charging_station: Kargatzeko Geltokia + childcare: Haur hezkuntza cinema: Zinema clinic: Klinika clock: Erlojua - college: Kolegioa + college: Unibertsitatea community_centre: Komunitate Zentroa courthouse: Epaitegia - crematorium: Errauste labe + crematorium: Erraustegia dentist: Dentista doctors: Medikuak dormitory: Ikasle egoitza @@ -263,59 +457,65 @@ eu: embassy: Enbaxada emergency_phone: Larrialdi Telefonoa fast_food: Janari Azkarra - ferry_terminal: Ferry terminal + ferry_terminal: Ferry Terminala fire_hydrant: Suteetako ur-hartunea - fire_station: Suhiltzaileak + fire_station: Suhiltzaile Egoitza food_court: Jatetxe-eremua - fountain: Iturri + fountain: Iturria fuel: Gasolindegia + gambling: Jokoak grave_yard: Hilerria gym: Fitness Zentroa / Gimnasioa health_centre: Osasun Zentroa hospital: Ospitalea hunting_stand: Ehiza postua ice_cream: Izozkiak - kindergarten: Haurtzaindegi + kindergarten: Haurtzaindegia library: Liburutegia market: Merkatu marketplace: Merkatua monastery: Monastegia motorcycle_parking: Motorrentzako aparkalekua - nightclub: Gau-klub - nursery: Haurtzaindegi + nightclub: Gau-kluba + nursery: Haurtzaindegia nursing_home: Zaharren egoitza - office: Bulego - parking: Aparkaleku + office: Bulegoa + parking: Aparkalekua parking_entrance: Aparkalekuko sarrera pharmacy: Farmazia place_of_worship: Otoitzerako Lekua police: Polizia post_box: Postontzia - post_office: Postetxe - preschool: Eskolaurre - prison: Espetxe + post_office: Postetxea + preschool: Haurreskola + prison: Espetxea + pub: Pub-a public_building: Eraikin publiko reception_area: Harrera lekua recycling: Birziklatze gune - restaurant: Jatetxe + restaurant: Jatetxea retirement_home: Nagusien etxea sauna: Sauna - school: Ikastetxe + school: Eskola shelter: Aterpea shop: Denda shower: Dutxa social_centre: Gizarte zentroa - studio: Estudio + social_club: Klub soziala + social_facility: Gizarte Instalazioa + studio: Estudioa swimming_pool: Igerilekua taxi: Taxi - telephone: Telefono publiko + telephone: Telefono publikoa theatre: Antzokia toilets: Komunak - townhall: Udaletxe - university: Unibertsitate - vending_machine: Salmenta automatiko + townhall: Udaletxea + university: Unibertsitatea + vending_machine: Salmenta automatikodun makina veterinary: Albaitaritza klinika village_hall: Herriko aretoa + waste_basket: Hondakin Saskia + waste_disposal: Hondakin Ezabatze Puntua youth_centre: Gaztelekua boundary: administrative: Muga Administratiboa @@ -349,110 +549,144 @@ eu: highway: abandoned: Errepide abandonatua bridleway: Oinezkoen gunea - bus_stop: Autobus-geraleku - construction: Eraikitze-lanetan dagoen Autopista + bus_guideway: Autobus Gidatuen Linea + bus_stop: Autobus-geralekua + construction: Eraikitze-lanetan dagoen autopista cycleway: Bidegorria elevator: Igogailua emergency_access_point: Larrialdi Sarbide Gunea - footway: Oinezkoen bide + footway: Oinezkoen bidea ford: Ibia + living_street: Etxebizitzen kalea milestone: Mugarria - motorway: Autobide + motorway: Autobidea + motorway_junction: Autopista lotunea motorway_link: Autobidea path: Bidea pedestrian: Oinezkoen gunea platform: Nasa - primary: Lehen mailako errepide - primary_link: Errepide nagusi + primary: Errepide Nagusia + primary_link: Errepide Nagusia proposed: Proiektatutako errepidea raceway: Lasterketa pista - residential: Kalea - rest_area: Atsedenlekua - road: Errepide - secondary: Bigarren mailako errepide - secondary_link: Bigarren mailako errepide - service: Zerbitzu Errepidea - services: Autobide Zerbitzuak - speed_camera: Radarra - steps: Eskailera-mailak + residential: Etxebizitza Bidea + rest_area: Atseden Lekua + road: Errepidea + secondary: Bigarren Mailako Errepidea + secondary_link: Bigarren Mailako Errepidea + service: Zerbitzu errepidea + services: Autobide zerbitzuak + speed_camera: Abiadura Kamera + steps: Pausoak street_lamp: Farola - tertiary: Hirugarren mailako errepide - tertiary_link: Hirugarren mailako errepide + tertiary: Hirugarren Mailako Errepidea + tertiary_link: Hirugarren Mailako Errepidea track: Pista - traffic_signals: Trafiko seinaleak + traffic_signals: Trafiko Seinaleak + trail: Ibilbidea + trunk: Errepide nagusia + trunk_link: Errepide nagusia unclassified: Sailkatu gabeko errepidea - unsurfaced: Alfastatu gabeko errepidea + unsurfaced: Asfaltatu gabeko errepidea "yes": Errepidea historic: - archaeological_site: Aztarnategi arkeologiko + archaeological_site: Aztarnategi arkeologikoa battlefield: Bataila-eremua boundary_stone: Mugarria building: Eraikin historikoa bunker: Bunkerra - castle: Gaztelu + castle: Gaztelua church: Eliza + city_gate: Hirirako sarbidea citywalls: Hiriko harresiak fort: Gotorlekua - heritage: Gizateriaren Ondarea + heritage: Gizateriaren ondarea house: Etxea icon: Ikonoa + manor: Jauregia memorial: Memoriala - mine: Meategi - monument: Monumentu - roman_road: Erromatar bidea + mine: Meategia + monument: Monumentua + roman_road: Erromatar Bidea ruins: Hondakinak stone: Harria tomb: Hilobia - tower: Dorre + tower: Dorrea + wayside_cross: Bide-gurutzea + wayside_shrine: Ermitarako bidea + wreck: Aztarnak + junction: + "yes": Bide-gurutzea landuse: - cemetery: Hilerri - commercial: Merkataritza Eremua + allotments: Alokatutako baratzeak + basin: Arroa + brownfield: Antzinako industria eremua + cemetery: Hilerria + commercial: Merkataritza eremua + conservation: Kontserbazioa construction: Eraikuntza farm: Baserria + farmland: Nekazari landa + farmyard: Nekazari zelaia forest: Baso garages: Garajeak grass: Belardia + greenfield: Eraiki gabeko lurra industrial: Industrialdea landfill: Zabortegia - meadow: Larre - military: Eremu Militarra - mine: Meategi - quarry: Harrobi - railway: Trenbide - reservoir: Urtegi - retail: Merkataritza gunea - village_green: Udal parkea + meadow: Larrea + military: Eremu militarra + mine: Meategia + orchard: Baratza + quarry: Harrobia + railway: Trenbidea + recreation_ground: Aisialdi gunea + reservoir: Urtegia + reservoir_watershed: Urtegiko arroa + residential: Etxebizitza Ingurua + retail: Txikizkako merkataritza gunea + road: Errepide Area + village_green: Udal Berdegunea vineyard: Mahastia + "yes": Lur-erabilera leisure: - beach_resort: Hondartza konplexu + beach_resort: Hondartza Konplexua + bird_hide: Hegazti Aterpea + club: Kluba common: Lur Komunak - dog_park: Txakurrentzako parkea + dog_park: Txakurrentzako Parkea fishing: Arrantza Lekua - fitness_centre: Ginmasioa - fitness_station: Gimnasioa - garden: Lorategi - golf_course: Golf-zelai + fitness_centre: Gimnasioa + fitness_station: Fitness Geltokia + garden: Lorategia + golf_course: Golf Zelaia horse_riding: Zalditegia ice_rink: Izotz-pista - marina: Kirol-portu + marina: Kirol-portua miniature_golf: Minigolfa - nature_reserve: Natura Erreserba + nature_reserve: Natura-erreserba park: Parkea pitch: Kirolgunea - playground: Jolastoki + playground: Jolastokia + recreation_ground: Aisialdi-gunea + resort: Estazioa sauna: Sauna slipway: Harmaila sports_centre: Kiroldegia stadium: Estadioa swimming_pool: Igerilekua + track: Korrika egiteko pista water_park: Ur jolas-parkea "yes": Aisialdia man_made: lighthouse: Itsasargia + pipeline: Hodia tower: Dorrea works: Lantegia + "yes": Gizakiak egindakoa military: airfield: Aireportu militarra + barracks: Kuartelak bunker: Bunkerra mountain_pass: "yes": Mendatea @@ -460,93 +694,113 @@ eu: bay: Badia beach: Hondartza cape: Lurmuturra - cave_entrance: Kobazulo Sarrera + cave_entrance: Kobazulo sarrera + cliff: Labarra crater: Kraterra dune: Duna + fell: Ebakia fjord: Fiordoa forest: Basoa geyser: Geiserra glacier: Glaziarra grassland: Belardia + heath: Mortua hill: Muinoa island: Irla land: Lurra marsh: Zingira - mud: Lohi - peak: Gailur - point: Puntu - reef: Arrezife + moor: Mortua + mud: Lohia + peak: Gailurra + point: Puntua + reef: Arrezifea + ridge: Gailurra rock: Arroka - sand: Hondarra - scree: Harritza + saddle: Jarlekua + sand: Harea + scree: Pilaketa + scrub: Sasiak + spring: Udaberria stone: Harria - strait: Itsasertza + strait: Itsasartea tree: Zuhaitza - valley: Haran - volcano: Sumendi + valley: Harana + volcano: Sumendia water: Ura - wood: Baso + wetland: Hezegunea + wood: Basoa office: - accountant: Kontuhartzailea + accountant: Kontu-hartzailea administrative: Administrazioa architect: Arkitektoa company: Enpresa - employment_agency: Enplegu agentzia - estate_agent: Inmobiliaria - government: Gobernuko bulegoa - insurance: Aseguruetako bulegoa + employment_agency: Enplegu Agentzia + estate_agent: Higiezinen Agentea + government: Gobernuko Bulegoa + insurance: Aseguruetako Bulegoa lawyer: Abokatua ngo: GKE bulegoa - telecommunication: Telekomunikazio Bulegoa + telecommunication: Telekomunikazio bulegoa travel_agent: Bidaia-agentzia "yes": Bulegoa place: - airport: Aireportu + allotments: Alokatutako baratzeak + block: Blokea + airport: Aireportua city: Hiria country: Herrialdea county: Konderria farm: Baserria hamlet: Herrixka - house: Etxe + house: Etxea houses: Etxeak island: Irla islet: Uhartea - locality: Lokalitate - municipality: Udalerri + isolated_dwelling: Etxebizitza isolatua + locality: Lokalitatea + moor: Mortua + municipality: Udalerria neighbourhood: Auzoa - postcode: Posta-kode - region: Eskualde + postcode: Posta-kodea + region: Eskualdea sea: Itsasoa state: Estatua - subdivision: Azpibanaketa + subdivision: Azpi-banaketa suburb: Aldiri town: Herria - unincorporated_area: Elkartu Gabeko Gunea + unincorporated_area: Elkartu gabeko gunea village: Herrixka "yes": Tokia railway: - abandoned: Abandonatutako trenbidea - construction: Eraikitze-lanetan dagoen Trenbidea - disused: Trenbide ez-erabilia - disused_station: Tren geltoki ez-erabilia + abandoned: Abandonatutako Trenbidea + construction: Eraikitze-lanetan dagoen trenbidea + disused: Erabili gabeko trenbidea + disused_station: Erabili gabeko tren geltokia funicular: Funikularra halt: Tren Geralekua historic_station: Tren Geltoki Historikoa + junction: Trenbide lotunea level_crossing: Trenbide-pasagunea - light_rail: Tren Arina + light_rail: Tren arina + miniature: Miniaturazko trenbidea monorail: Monoraila - narrow_gauge: Bide Estuko Trenbidea - platform: Trenbide Plataforma + narrow_gauge: Bide estuko trenbidea + platform: Trenbide Nasa + preserved: Kontserbatutako trenbidea proposed: Proposatutako trenbidea - station: Tren Geltokia + spur: Tren-espioia + station: Tren geltokia stop: Tren geralekua subway: Metroa - subway_entrance: Metro Sarbidea + subway_entrance: Metro sarbidea + switch: Trenbide puntuak tram: Tranbia tram_stop: Tranbia geltoki shop: + alcohol: Lizentziarik gabea + antiques: Antigoalekoak art: Arte-denda - bakery: Okindegi + bakery: Okindegia beauty: Edergintza denda beverages: Edari-denda bicycle: Bizikleta-denda @@ -554,83 +808,112 @@ eu: boutique: Boutique butcher: Harategia car: Auto-denda - car_parts: Autoaldagaiak - car_repair: Autoen konponketa-lantegia + car_parts: Autoen Aldagaiak + car_repair: Autoen Konponketa carpet: Alfonbra-denda + charity: Karitate-denda chemist: Farmazia - clothes: Arropa denda + clothes: Jantzi-denda computer: Ordenagailu-denda - confectionery: Gozotegi + confectionery: Gozotegia + convenience: Erosotasun-denda copyshop: Kopia-denda cosmetics: Kosmetika-denda + deli: Urdaitegia + department_store: Departamendu-denda + discount: Deskontudun Item-denda + doityourself: Zuk-Zeuk-Egin + dry_cleaning: Lehorreko Garbiketa electronics: Elektronika-denda - estate_agent: Higiezinen agente + estate_agent: Higiezinen agentea + farm: Baserri-denda + fashion: Moda-denda fish: Arrantza-denda - florist: Loradenda + florist: Lore-saltzailea food: Janari-denda - furniture: Altzari + funeral_directors: Hileta-zuzendariak + furniture: Altzari-denda gallery: Galeria - general: Denetariko denda + garden_centre: Lorategia + general: Denetariko-denda gift: Opari-denda - greengrocer: Barazki-saltzaile - grocery: Janaridenda - hairdresser: Ileapaindegi - hardware: Burdindegia + greengrocer: Barazki-saltzailea + grocery: Janari-denda + hairdresser: Ileapaindegia + hardware: Hardware-denda hifi: Hi-Fi insurance: Aseguruak jewelry: Bitxi-denda - kiosk: Kiosko - laundry: Garbitegi + kiosk: Kioskoa + laundry: Garbitegia mall: Merkataritza-gunea - market: Merkatu - mobile_phone: Mugikor-denda + market: Azoka + mobile_phone: Sakelakoen denda motorcycle: Motozikleta-denda music: Musika-denda - newsagent: Kioskoa - optician: Optika + newsagent: Kiosko-saltzailea + optician: Optikaria + organic: Janari organikoko denda + outdoor: Kanpoko denda pet: Animalia-denda pharmacy: Farmazia photo: Argazki-denda + salon: Apaindegia second_hand: Bigarren eskuko denda shoes: Zapatadenda - shopping_centre: Merkatal Gunea + shopping_centre: Merkataritza-gunea sports: Kirol denda - supermarket: Supermerkatu + stationery: Paper-denda + supermarket: Supermerkatua tailor: Jostuna - toys: Jostailu Denda + toys: Jostailu denda travel_agency: Bidaia-agentzia + video: Bideo-denda + wine: Lizentziarik Gabekoa "yes": Denda tourism: alpine_hut: Aterpe alpinoa + apartment: Apartamentua artwork: Artelana - attraction: Atrakzio + attraction: Atrakzioa bed_and_breakfast: Ohe eta gosari (B&B) cabin: Kabina camp_site: Kanpin - chalet: Txalet + caravan_site: Karabana gunea + chalet: Txaleta gallery: Galeria - guest_house: Aterpe - hostel: Ostatu - hotel: Hotel + guest_house: Aterpea + hostel: Ostatua + hotel: Hotela information: Informazioa - motel: Motel + motel: Motela museum: Museoa picnic_site: Piknik-gune - theme_park: Parke tematiko - viewpoint: Behatoki - zoo: Zoologiko + theme_park: Parke tematikoa + viewpoint: Behatokia + zoo: Zoologikoa tunnel: + culvert: Estolda "yes": Tunela waterway: - canal: Kanal + artificial: Urbide artifiziala + boatyard: Ontziola + canal: Kanala dam: Urtegia + derelict_canal: Baztertutako Kanala ditch: Lubakia dock: Kaia drain: Isurbidea + lock: Kaia + lock_gate: Kaia Sarrera + mooring: Ontziralekua rapids: Ur-lasterrak - river: Ibai - waterfall: Ur-jauzi + river: Ibaia + stream: Erreka + wadi: Uadia + waterfall: Ur-jauzia weir: Uharka + "yes": Urbidea admin_levels: level2: Herrialdeko muga level4: Estatuko muga @@ -640,6 +923,10 @@ eu: level9: Herriko muga level10: Auzoko muga description: + title: + osm_nominatim: 'Helbidea hemendik: OpenStreetMap + Nominatim' + geonames: 'Helbidea hemendik: GeoNames' types: cities: Hiriak towns: Herriak @@ -653,18 +940,36 @@ eu: home: Hasierara joan logout: Itxi saioa log_in: Saioa hasi + log_in_tooltip: Saioa hasi existitzen den kontu batekin sign_up: Eman izena start_mapping: Hasi mapeatzen + sign_up_tooltip: Editatzeko kontu bat sortu edit: Aldatu history: Historia export: Esportatu data: Datuak export_data: Esportatu datuak - intro_header: Ongi etorri OpenStreetMapera! + gps_traces: GPS Aztarnak + gps_traces_tooltip: GPS aztarnak kudeatu + user_diaries: Erabiltzaileen egunerokoak + user_diaries_tooltip: Erabiltzaile egunerokoak ikusi + edit_with: '%{editor}rekin editatu' + tag_line: Doako Wiki Mundu Mapa + intro_header: Ongi etorri OpenStreetMap-era! + intro_text: OpenStreetMap munduko mapa da, zu bezalako jendeak sortutakoa eta + doako lizentzia irekiarekin erabiltzeko dagoena. intro_2_create_account: Erabiltzaile kontua sortu - partners_ic: Londresko Imperial College - partners_bytemark: Bytemark Hosting + partners_html: '%{ucl}, %{bytemark}, %{ic}, eta beste %{partners}-k babestua.' + partners_ucl: UCLa + partners_ic: Londreseko Imperial College + partners_bytemark: Bytemark Ostatua partners_partners: bazkideak + osm_offline: OpenStreetMap datu-basea orain konexiorik gabe dago funtsezko datu-basearen + mantentze lanak burutzen diren bitartean. + osm_read_only: OpenStreetMap datu-basea irakurtzeko soilik moduan dago, oinarrizko + datu-basearen mantentze lanak egiten diren bitartean. + donate: OpenStreetMap lagundu, Hardware Berritze Funtsaren bidez %{link}-n klik + eginez. help: Laguntza about: Honi buruz copyright: Egile-eskubideak @@ -674,27 +979,126 @@ eu: foundation: Fundazioa foundation_title: OpenStreetMap Fundazioa make_a_donation: + title: Diru laguntza batekin OpenStreetMap lagundu text: Dohaintza egin - learn_more: Gehiago ikasi + learn_more: Ikasi gehiago more: Gehiago license_page: foreign: title: Itzulpen honi buruz + text: Itzulitako orrialde hau eta %{english_original_link} arteko gatazka izanez + gero, ingelesezko orrialdeak lehentasuna hartuko du english_link: jatorrizkoa ingelesez native: title: Orrialde honi buruz + text: Copyright-aren bertsio ingelesez ikusten ari zara. Orrialde honen %{native_link} + orrira itzuli edo copyrightarekin eta %{mapping_link}-ri buruz irakurtzeari + utzi diezaiokezu. native_link: Euskara version + mapping_link: kartografiarekin hasi legal_babble: title_html: Egile-eskubideak eta lizentzia + intro_1_html: |- + OpenStreetMap® irekitako datua multzoa da, Datu irekiak + Commons Open Database Lizentzia (ODbL) darama OpenStreetMap Fundazioaren babespean (OSMF). + intro_2_html: |- + Kopiatu, banatu, transmititu eta gure datuak egokitzeko baimena duzu, betiere kredituetan OpenStreetMap eta bere + laguntzaileak sartuz. Zure datuak aldatzen edo erauzten badituzu, lizentzia horren azpian soilik banatzea gerta daiteke. legal + kodeak zure eskubideak eta erantzukizunak azaltzen ditu. + intro_3_html: |- + Gure mapa fitxen kartografia, eta gure dokumentazioa, Creative + Commons Attribution-ShareAlike 2.0 lizentziapean eskaintzen dira (CC BY-SA). + credit_title_html: OpenStreetMap nola kreditatu + credit_1_html: '“© OpenStreetMap contributors” kreditua erabiltzeko + eskatzen dizugu.' + credit_2_html: "Halaber, argi utzi behar duzu datuak Open azpian erabilgarri + dauden\nDatu-basearen lizentziapean, eta gure mapa fitxak erabiltzen badituzu, + kartografia CC BY-SA lizentziatu daramala. Horretarako \n + copyright-orri honetan egin dezakezu.\nBestela, eta behar izanez gero, + OSM banatzen ari zarenean\ndatu-inprimakian, izen-abizenak eta baimenak zuzenean + lotu ditzakezu. Loturak posibleak ez diren komunikabideetan\n(adibidez, inprimatutako + lanak), gomendatzen dizugu\nzure irakurleei openstreetmap.org (agian hedapenean)\n'OpenStreetMap' + helbide honetaraino), opendatacommons.org helbidera, eta\ndagokionean, creativecommons.org-era + zuzentzea." + credit_3_html: |- + Mapa elektroniko bateragarrientzat, kredituak maparen izkinan agertu behar dira. + Adibidez: + attribution_example: + alt: Web-orri batean OpenStreetMap nola esleitu erakusteko adibidea + title: Eskuduntza adibidea more_title_html: Jakin ezazu gehiago + more_1_html: |- + Irakurri gehiago gure datuak erabiltzeari buruz, eta nola gu kreditatu, hemen:OSMF Licence page. + more_2_html: |- + OpenStreetMap datuak irekita dauden arren, ezin dugu eman + aplikazio libreko maparen APIa hirugarrenentzat. + Ikusi gure API erabileraren gidalerroak , + Tile erabileraren gidalerroak + eta Nominatim Erabilera-gidalerroak aztertzeko. + contributors_title_html: Gure kolaboratzaileak + contributors_intro_html: |- + Gure laguntzaileen taldea milaka pertsonek osatzen dute. Horrez gain, nazio mailan aginte publikoko lizentziak + dituzten mapak eta beste iturri batzuk eskeintzen ditugu, besteak beste: contributors_at_html: |- Austria: Honako iturrietatik ateratako datuak ditu: Stadt Wien (CC BY lizentziapean), Land Vorarlberg eta Land Tirol (CC BY AT zuzenketekin lizentziapean). + contributors_ca_html: |- + Canada: Datuak + GeoBase®, GeoGratis (© Department of Natural + Resources Canada), CanVec (© Department of Natural + Resources Canada), eta StatCan (Geography Division, + Statistics Canada) biltegietatik hartzen ditu. + contributors_fi_html: |- + Finland: Datuak hemendik hartzen ditu: Finlandiako topografia datu-baseko inkesta nazionala + eta beste datubase batzuk, honen azpian: + NLSFI License. contributors_fr_html: 'Frantzia: Direction Générale des Impôts-etik ateratako datuak ditu.' + contributors_nl_html: |- + Herbehereak: Contains © AND data, 2007 + (www.and.com) + contributors_nz_html: |- + Zeelanda Berria: datuak biltzen ditu + Zeelanda Berriko Landako informaziotik. Erregin Copyright erreserbatuta. + contributors_si_html: |- + Eslovenia: datuak biltzen ditu + Burutzea eta Mapping Agintaritzatik eta + Nekazaritza, Basogintza eta Elikadura Ministeriotik + (Esloveniako informazio publikoa). + contributors_za_html: |- + Hego Afrika : + Zuzendaritza Nagusia datuen jatorria: + Geo-Lurralde Informazio Nazionala , Estatuko copyright erreserbatuta. + contributors_gb_html: |- + Erresuma Batua: Ordnance + Inkestaren datuak eta kopiak biltzen ditu; Crown copyright eta datu-basearen eskubidea 2010-12. + contributors_footer_1_html: |- + OpenStreetMap hobetzen laguntzeko lagundu dutenen xehetasun gehiago eta erabilitako beste iturri batzuk ezagutzeko, mesedez OpenStreetMap Wikian ikusi Contributors + page. + contributors_footer_2_html: |- + OpenStreetMap-en datuak sartzeak ez du beharrez jatorrizko + datu-hornitzaileak OpenStreetMap onartzea baieztatzen, edozein berme ematen, edota inolako erantzukizunik onartzen. infringement_title_html: Egile-eskubideen urraketa + infringement_1_html: |- + OSMren laguntzaileek ez dute inolako daturik gehitu behar + copyright iturrietatik (adibidez, Google Maps edo inprimatutako mapak) copyright-jabeen baimen espliziturik gabe. + infringement_2_html: |- + Uste baduzu copyrightako materiala ez dela egokia izan + OpenStreetMap datu-baseari edo gune honi gehitu zaionean, mesedez + Gure bajazioa + prozedura edo zuzenean gure fitxategian + lineako aurkezpen orrira jo. + trademarks_title_html: Marka komertzialak + trademarks_1_html: OpenStreetMap, lupa-logotipoa eta Maparen egoera OpenStreetMap + Fundazioaren marka erregistratuak dira. Marka erabiltzeari buruzko galderarik + baduzu, bidali zure galderak + Lizentzia-lan taldera. welcome_page: title: Ongi etorri! introduction_html: Ongi etorri OpenStreetMapera, edonork alda dezakeen munduko @@ -702,69 +1106,250 @@ eu: gida laburra jakin behar dituzun gauzarik garrantzitsuenak dituena. whats_on_the_map: title: Mapan dagoena + on_html: |- + OpenStreetMap erreal eta egungo gauzak mapeatzeko lekua da - milioika eraikin, errepide eta beste leku batzuei buruzko xehetasunak biltzen ditu. Mapa jar ditzakezu + mundu errealeko zuretzat interesgarriak diren ezaugarriak. + off_html: Zer ez baditu balorazio bezalako datu iritziak ematen, historiko + edo ezaugarri hipotetikoak eta copyright-iturrietatik datozen datuak. Ez baduzu + baimen berezia, ez kopiatu lineako edo papereko mapetatik. + basic_terms: + title: Kartografiarako Oinarrizko Terminoak + paragraph_1_html: OpenStreetMap-ek bere parekatze propioa du. Hemen daude erabilgarriak + diren zenbait hitz gako. + editor_html: Editore bat mapa editatzeko erabil dezakezun programa + edo webgunea da. + node_html: Nodo bat maparen puntu bat da, jatetxe bakar bat + edo zuhaitz bat bezalakoa. + way_html: Bide bat linea edo eremu bat da, errepidea, erreka, + aintzira edo eraikin bat bezalakoa. + tag_html: Etiketa nodo edo modu bati buruzko datu bitxi bat + da, adibidez jatetxe izena edo errepideen abiadura muga. rules: title: Arauak! + paragraph_1_html: |- + OpenStreetMap-ek arau formal gutxi ditu baina parte-hartzaile guztiek bete dezaten espero dugu eta komunitatearekin komunikatzea. Eskuz editatzea ez den beste jarduera batean pentsatzen ari bazara, irakurri eta jarraitu jarraibideak + Importazioak eta Edizio automatizatuetan . questions: title: Galderarik? + paragraph_1_html: |- + OpenStreetMap-ek proiektuari buruz ikasteko baliabideak ditu, galdetuz eta erantzunez, eta mapping gaiak eztabaidatu eta dokumentatuz lankidetzan. + Jaso laguntza hemen. start_mapping: Hasi mapeatzen + add_a_note: + title: Editatzeko denborarik ez? Gehitu ohar bat! + paragraph_1_html: Zerbait txiki eta finkoa bada eta ez baduzu denbora erregistratzeko + eta nola editatzen ikasteko, ohar bat gehitzea erraza da. + paragraph_2_html: |- + Joan besterik gabe mapara eta egin klik oharraren ikonoan: + . Honek markatzailea gehituko dio mapari, arrastatuz mugitu ahal izateko. Gehitu zure mezua, ondoren sakatu gorde eta beste erabiltzaileek ikertu egingo dute. fixthemap: title: Arazo baten berri eman / Mapa zuzendu how_to_help: title: Nola lagundu + join_the_community: + title: Komunitateko kide bihurtu + explanation_html: Arazoren bat nabaritu baduzu maparen datuekin, adibidez, + errepide edo zure helbidea faltan daudela, jarraitzeko modurik onena OpenStreetMap + komunitatean sartzea da datuak berreskuratu edo konpontzeko. + add_a_note: + instructions_html: |- + Egin klik edo ikono berean maparen pantailan. + Honek markatzailea gehituko dio mapari, arrastatuz mugitu ahal izateko. Gehitu zure mezua, ondoren sakatu gorde eta beste erabiltzaileek ikertu egingo dute. other_concerns: title: Bestelako kezkak + explanation_html: |- + Zure datuak nola erabiltzen diren edo edukiari buruzko kezka baduzu, kontsultatu gure + copyright orria informazio juridiko gehiago lortzeko, edo jar zaitez dagokionarekin harremanetan + OSMF lan taldean . help_page: title: Laguntza Lortu + introduction: OpenStreetMap-ek proiektuari buruz ikasteko hainbat baliabide ditu, + galderak egin eta erantzun, edota mapping gaiak eztabaidatu eta dokumentazeko + elkarlana. welcome: url: /welcome title: Ongi etorri OSM-ra + description: OpenStreetMap-en oinarrizkoak betetzen dituen gida azkar honekin + hasi. beginners_guide: url: http://wiki.openstreetmap.org/wiki/Eu:Beginners%27_guide title: Hasiberrientzako gida + description: Hasiberrientzako mantentze-gida komunitarioa. help: url: https://help.openstreetmap.org/ title: help.openstreetmap.org + description: Egin galdera bat edo begiratu OSM-en galdera-eta-erantzun gunean. + mailing_lists: + title: Posta Bidaltze Zerrendak + description: Galdera bat egin edo eztabaidatu gai interesgarriak gaikako edo + eskualdekako posta zerrendetan. forums: title: Foroak + description: Galderak eta eztabaidak iragarki taula estilo interfazea nahiago + dutenentzat. irc: title: IRC + description: Hizkuntza eta gai askotako hizketaldi interaktiboa. + switch2osm: + title: switch2osm + description: Laguntza enpresei eta erakundeei OpenStreetMap-en oinarritutako + mapetara eta beste zerbitzuetara aldatzeko. wiki: url: http://wiki.openstreetmap.org/wiki/Eu:Main_Page title: wiki.openstreetmap.org + description: OSM informazio zehatzerako wiki arakatu. about_page: next: Hurrengoa + copyright_html: ©OpenStreetMap
    kolaboratzaileak + used_by: '%{name}-k eskuliburuen mapak milaka web gune, mugikorretako aplikazio + eta hardware gailuetan ahalbidetzen ditu' + lede_text: OpenStreetMap mundu osoan zehar errepideak, bideak, kafetegiak, tren + geltokiak eta askoz gehiago mapatzaileen komunitate batek eskeinitako datuen + eta haien mantentzearen laguntzaz eraiki ditu. local_knowledge_title: Tokiko Ezagutza + local_knowledge_html: OpenStreetMap tokiko ezagutzak azpimarratzen ditu. Laguntzaileek + aireko irudiak erabiltzen dituzte, GPS gailuak eta teknologia baxuko eremuko + mapak OSMrako egiaztapen zehatza eta eguneratua egiteko. + community_driven_title: Komunitatearen Ahotsa + community_driven_html: "OpenStreetMap komunitatea anitza, sutsua eta egunero hazten + den mugimendua da.\nGure laguntzaileen artean, mapa zaleak, GIS profesionalek, + \nOSM zerbitzariak exekutatzen dituzten ingeniariak, hondamendia kaltetutako + eremuak mapatzen dituztenek,\neta askoz gehiagok osatzen dute.\nKomunitateari + buruz gehiago jakiteko, ikusi erabiltzaileen egunkariak + ,\n komunitatearen blogak , + eta\n OSM Fundazio webgunea." open_data_title: Datu Irekiak + open_data_html: |- + OpenStreetMap datu irekiak ditu: edozein gauzarako erabil dezakezu betiere OpenStreetMap-ek eta bere kolaboratzaileek aipatzen badituzu. Moduren batean datuen gainean edukia eraikiz, emaitza bakarrik banatu ahal izango duzu lizentzia beraren azpian. Ikusi Copyright eta + Lizentzia orria xehetasunak lortzeko. + legal_title: Legala + legal_html: |- + Gune hau eta beste hainbat zerbitzu lotzen dira formalki + OpenStreetMap Foundation (OSMF) + komunitatearen izenean. OSMF operatutako zerbitzu guztien erabilera gaia da + gure + Politika Erabilpen Onargarria eta gure Pribatutasun-gidalerroak + Mesedez jarri harremanetan OSMF-ekin + lizentziak, copyrightak edo bestelako lege-galderak eta arazoak badituzu. + partners_title: Parte-hartzaileak notifier: diary_comment_notification: + subject: '[OpenStreetMap] %{user} eguneroko sarrera batean iruzkina utzi du' hi: Kaixo %{to_user}, + header: '%{from_user}k OpenStreetMap eguneroko sarrera batean iruzkina utzi + du %{subject} gaiaren barnean:' + footer: Iruzkina ere irakurri dezakezu %{readurl}-n eta %{commenturl} -n iruzkindu + edo %{replyurl}-n erantzun dezakezu. message_notification: hi: Kaixo %{to_user}, + header: '%{from_user}-k OpenStreetMap-en bidez mezua bidali dizu %{subject} + gaiarekin:' + footer_html: Mezua irakurri dezakezu %{readurl}-n ere eta erantzun %{replyurl}-n + friend_notification: + hi: Kaixo %{to_user}, + subject: '[OpenStreetMap] %{user} lagun bezala gehitu zaitu' + had_added_you: '%{user} lagun bezala gehitu zaitu OpenStreetMap-en.' + see_their_profile: Haien profila %{userurl}n ikusi dezakezu. + befriend_them: Haiek ere lagun bezala gehitu ditzakezu %{befriendurl}n. gpx_notification: greeting: Kaixo, + your_gpx_file: Zure GPX fitxategia bezala dirudi + with_description: deskribapenarekin + and_the_tags: 'eta hurrengo etiketak:' + and_no_tags: eta etiketarik ez. + failure: + subject: '[OpenStreetMap] GPX Inportazioan porrota' + failed_to_import: 'inportzean kale egin du. Hemen dago akatsa:' + more_info_1: GPX inportazio akatsei buruzko informazio gehiago eta hauek nola + saihesteari buruz. + more_info_2: 'hemen aurkitu daitezke:' + success: + subject: '[OpenStreetMap] GPX Inportazioan arrakasta' + loaded_successfully: '%{trace_points} puntuekin %{possible_points} puntuetatik + arrakastaz kargatu da.' signup_confirm: - subject: '[OpenStreetMap] Ongi etorri OpenStreetMapera' + subject: '[OpenStreetMap] Ongi etorri OpenStreetMap-era' greeting: Kaixo! + created: Norbaitek (zuk espero) %{site_url}n kontua sortu egin du. + confirm: 'Ezer egin baino lehen, eskaera hau zugandik datorrela baieztatu behar + dugu, horrela izan bada beheko estekan klik egin zure kontua baieztatzeko:' + welcome: Zure kontua baieztatzen duzunean, informazio gehigarria emango dizugu + hasteko. email_confirm: subject: '[OpenStreetMap] Baieztatu zure eposta helbidea' email_confirm_plain: greeting: Kaixo, + hopefully_you: Norbaitek (zuk zorionez) zure helbide elektronikoa aldatu nahi + du %{server_url}en %{new_address}ra. + click_the_link: Hau zu bazara, beheko estekan klik egin aldaketa baieztatzeko. email_confirm_html: greeting: Kaixo, + hopefully_you: Norbaitek (zuk zorionez) zure helbide elektronikoa aldatu nahi + du %{server_url}en %{new_address}ra. + click_the_link: Hau zu bazara, beheko estekan klik egin aldaketa baieztatzeko. + lost_password: + subject: '[OpenStreetMap] Pasahitza berrezartzeko eskaera' lost_password_plain: greeting: Kaixo, + hopefully_you: Norbaitek (zuk posibleki) helbide elektroniko kontu honetara + openstreetmap.org berrezartzeko pasahitza eskatu du. + click_the_link: Hau zu bazara, egin klik beheko estekan zure pasahitza berrezartzeko. lost_password_html: greeting: Kaixo, + hopefully_you: Norbaitek (zuk posibleki) helbide elektroniko kontu honetara + openstreetmap.org berrezartzeko pasahitza eskatu du. + click_the_link: Hau zu bazara, egin klik beheko estekan zure pasahitza berrezartzeko. note_comment_notification: - anonymous: Erabiltzale anonimoa + anonymous: Erabiltzale anonimo bat greeting: Kaixo, + commented: + subject_own: '[OpenStreetMap] %{commenter} zure ohar batean iruzkina utzi + du' + subject_other: '[OpenStreetMap] %{commenter} zuk interesa duzun ohar batean + iruzkina utzi du' + your_note: '%{commenter} %{place}tik hurbil dagoen zure mapa oharrean iruzkina + utzi du.' + commented_note: '%{commenter} iruzkina utzi du zuk iruzkina utzi duzun mapa + oharrean. Oharra %{place}tik hurbil dago.' + closed: + subject_own: '[OpenStreetMap] %{commenter} zure ohar bat ebatzi du' + subject_other: '[OpenStreetMap] %{commenter} intereskoa duzun ohar bat ebatzi + du' + your_note: '%{commenter} %{place}tik hurbil dagoen zure mapa oharra ebatzi + du' + commented_note: '%{commenter} zuk komentatu duzun mapa ohar bat ebatzi du. + Oharra %{place}tik hurbil dago.' + reopened: + subject_own: '[OpenStreetMap] %{commenter} zure oharretako bat berraktibatu + egin du' + subject_other: '[OpenStreetMap] %{commenter} zure interesekoa den ohar bar + berraktibatu egin du' + your_note: '%{commenter} %{place}tik hurbil dagoen zure mapa oharra berraktibatu + egin du.' + commented_note: '%{commenter} zuk komentatu duzun mapa oharra berraktibatu + egin du. Oharra %{place}tik hurbil dago.' + details: Oharrari buruzko xehetasun gehiago %{url}n aurki daitezke. changeset_comment_notification: - hi: Kaixo, %{to_user} + hi: Kaixo %{to_user}, greeting: Kaixo, + commented: + subject_own: '[OpenStreetMap] %{commenter} zure aldaketa batean iruzkina utzi + du' + subject_other: '[OpenStreetMap] %{commenter} zuk interesa duzun aldaketa batean + iruzkina utzi du' + your_changeset: '%{commenter} iruzkina utzi du %{time}n egin zenuen aldaketan' + commented_changeset: '%{commenter}k iruzkin bat utzi du %{changeset_author}ek + duela %{time}n sortutako ikusten ari zaren mapa aldaketan.' + partial_changeset_with_comment: '''%{changeset_comment}'' iruzkinarekin' + partial_changeset_without_comment: iruzkinik gabe + details: Aldaketari buruzko xehetasun gehiago %{url}n aurki daitezke. + unsubscribe: Aldaketaren aldaketa eguneratzeak ezeztatzeko, bisitatu %{url} + eta sakatu "Ezabatu harpidetza". message: inbox: title: Sarrera-ontzia my_inbox: Nire sarrera-ontzia + outbox: irteerako ontzia messages: '%{new_messages} eta %{old_messages} dituzu' new_messages: one: '%Mezu berri {count}' @@ -775,6 +1360,9 @@ eu: from: Igorlea subject: Gaia date: Data + no_messages_yet: Ez duzu mezurik jaso oraindik. Zergatik ez konektatuan jarri + %{people_mapping_nearby_link} batzuekin? + people_mapping_nearby: kartografiatzen ari diren hurbileko pertsonak message_summary: unread_button: Markatu irakurri gabekotzat read_button: Markatu irakurritzat @@ -782,17 +1370,36 @@ eu: delete_button: Ezabatu new: title: Bidali mezua + send_message_to: '%{name}ri mezu berri bat bidali' subject: Gaia body: Testua send_button: Bidali back_to_inbox: Itzuli sarrera-ontzira message_sent: Mezua bidalita + limit_exceeded: Berriki mezu asko bidali dituzu. Itxaron pixka bat gehiago bidaltzen + saiatu aurretik. + no_such_message: + title: Horrelako mezurik ez dago + heading: Horrelako mezurik ez dago + body: Barkatu baina id horrekin ez dago mezurik. outbox: + title: Irteerako ontzia my_inbox: Nire %{inbox_link} inbox: Sarrera-ontzia + outbox: irteerako ontzia + messages: + one: '%{count} Mezua bidali duzu' + other: ' %{count} Mezuak bidali dituzu' to: Hartzailea subject: Gaia date: Data + no_sent_messages: Ez duzu mezurik bidali oraindik. Zergatik ez konektatuan jarri + %{people_mapping_nearby_link} batzuekin? + people_mapping_nearby: kartografiatzen ari diren hurbileko pertsonak + reply: + wrong_user: '''%{user}'' bezala saioa hasi duzu baina erantzuteko eskatu duzun + mezua ez da erabiltzaile horri bidali. Hasi saioa erabiltzaile zuzenarekin + erantzuteko.' read: title: Irakurri mezua from: Igorlea @@ -800,8 +1407,12 @@ eu: date: Data reply_button: Erantzun unread_button: Markatu irakurri gabekotzat + delete_button: Ezabatu back: Atzera to: Hartzailea + wrong_user: '''%{user}'' bezala saioa hasi duzu baina irakurtzeko eskatu duzun + mezua ez da erabiltzaile horri bidali edo berak ez du bidali. Hasi saioa erabiltzaile + zuzenarekin irakurtzeko.' sent_message_summary: delete_button: Ezabatu mark: @@ -811,55 +1422,99 @@ eu: deleted: Mezua ezabatuta site: index: - permalink: Lotura iraunkorra - shortlink: Lotura laburra + js_1: Javascript onartzen ez duen arakatzailea erabiltzen ari zara edo JavaScript + desgaitu duzu. + js_2: OpenStreetMap-ek Javascript erabiltzen du bere mapa irriztagarrirako. + permalink: Esteka iraunkorra + shortlink: Esteka laburra createnote: Gehitu oharra + license: + copyright: OpenStreetMap eta laguntzaileen Copyright-a erabili, lizentzia + irekiaren babespean + remote_failed: Editatzeak huts egin du - Ziurtatu JOSM edo Merkaartor kargatu + dela eta urruneko kontrolaren aukera gaituta dagoela edit: + not_public: Zure ezarpenak publikoak izateko ez dituzu jarri. + not_public_description: Ezin duzu mapa editatu jadanik egin ez baduzu. Aldaketak + publiko gisa ezar ditzakezu zure %{user_page}-tik. user_page_link: Lankide orria + anon_edits_link_text: Aurkitu zergatik hau kasua den. + flash_player_required: Potlatch, OpenStreetMap Flash editorea erabiltzeko Flash + erreproduzitzailea behar duzu. + Adobe Flash Player-tik deskargatu dezakezu . + Beste hainbat aukera ere eskuragarri daude OpenStreetMap editatzeko. + potlatch_unsaved_changes: Aldaketak gorde gabe dituzu. (Potlatch-en gordetzeko, + uneko bidea edo puntuazioa desautatu beharko zenituzke, modu zuzenean editatzen + baduzu, edo egin klik gorde botoian.) + potlatch2_not_configured: Potlacth 2 ez da konfiguratu - mesedez ikusi http://wiki.openstreetmap.org/wiki/The_Rails_Port#Potlatch_2 + informazio gehiagorako + potlatch2_unsaved_changes: Gorde gabeko aldaketak dituzu. (Potlatch 2 gordetzeko, + egin klik gorde botoian.) + id_not_configured: iD-a ez da konfiguratu + no_iframe_support: Zure nabigatzaileak ez ditu onartzen HTML iframe-ak, funtzio + honetarako ezinbestekoak direnak. sidebar: search_results: Bilaketaren emaitzak close: Itxi search: search: Bilatu + get_directions: Norabideak lortu + get_directions_title: Bi puntuen arteko norabideak aurkitu from: Abiagunea to: Helmuga - where_am_i: Non nago? + where_am_i: Non dago hau? + where_am_i_title: Deskribatu uneko kokapena bilatzailearen bidez submit_text: Joan key: table: entry: motorway: Autobidea main_road: Errepide nagusia + trunk: Errepide nagusia primary: Lehen mailako errepidea secondary: Bigarren mailako errepidea unclassified: Sailkatu gabeko errepidea track: Pista bridleway: Oinezkoen gunea cycleway: Bidegorria + cycleway_national: Bizikleta bide nazionala + cycleway_regional: Eskualde bizikleta bidea + cycleway_local: Bizikleta bide lokala footway: Oinezkoen bidea rail: Trenbidea subway: Metroa tram: - 1: tranbia + - Tren arina + - tranbia cable: - Funikularra - teleaulkia runway: - Aireportuko Pista + - taxi bidea apron: - 1: terminala + - Aireportu plataforma + - terminala admin: Muga administratiboa forest: Baso wood: Basoa golf: Golf-zelai park: Parke + resident: Etxebizitza ingurua + common: + - Arrunta + - belardia + retail: Txikizkako azalera industrial: Industrialdea commercial: Merkataritza eremua + heathland: Txilardia lake: - Aintzira - urtegia farm: Baserria + brownfield: Landarik gabeko gunea cemetery: Hilerri + allotments: Alokatutako Baratzeak pitch: Kirolgunea centre: Kiroldegi reserve: Natura-erreserba @@ -867,11 +1522,16 @@ eu: school: - Eskola - unibertsitate + building: Eraikin garrantzitsua station: Tren geltokia summit: - Tontorra - gailurra + tunnel: Marratxodun estalkia = tunela + bridge: Estalki beltza = zubia private: Sarbide pribatua + destination: Helmuga sarbidea + construction: Eraikitzen ari diren errepideak bicycle_shop: Bizikleta-denda bicycle_parking: Bizikleta-aparkalekua toilets: Komunak @@ -879,13 +1539,34 @@ eu: edit: Aldatu preview: Aurrikusi markdown_help: - link: Lotura + title_html: Honekin analizatua:Markdown + headings: Goiburuak + heading: Goiburua + subheading: Azpi-goiburua + unordered: Ordenik gabeko zerrenda + ordered: Ordenatutako zerrenda + first: Lehenengo itema + second: Bigarren itema + link: Esteka text: Testua image: Irudia alt: Testu alternatiboa url: URLa trace: + visibility: + private: Pribatua (puntu anonimo eta desordenatu gisa soilik partekatzen da) + public: Publikoa (arrasto-zerrendan eta anonimoki, ordenatu gabeko puntuetan) + trackable: Jarraigarria (anonimoki, antolatua eta denbora-markekin partekatuak + bakarrik) + identifiable: Identifikagarria (arrasto-zerrendan eta identifikagarri gisa, + puntuak denbora-markekin antolatuz) + create: + upload_trace: GPS Aztarna igo + trace_uploaded: Zure GPX fitxategia kargatu da eta datu basean sartzeko zain + dago. Ordu erdi barru egongo da eta posta elektronikoz bidaliko zaizu amaitzean. edit: + title: '%{name} aztarna aldatzen' + heading: '%{name} aztarna aldatzen' filename: 'Fitxategi izena:' download: jaitsi uploaded_at: 'Noiz igota:' @@ -896,6 +1577,7 @@ eu: owner: 'Jabea:' description: 'Deskribapena:' tags: 'Etiketak:' + tags_help: koma mugatua save_button: Aldaketak gorde visibility: Ikusgarritasuna; visibility_help: Zer esan nahi du honek? @@ -903,56 +1585,190 @@ eu: upload_gpx: 'GPX fitxategi igo:' description: 'Deskribapena:' tags: 'Etiketak:' + tags_help: koma mugatua visibility: 'Ikusgarritasuna:' visibility_help: Zer esan nahi du honek? upload_button: Igo help: Laguntza + trace_header: + upload_trace: Aztarna bat igo + see_all_traces: Aztarna guztiak ikusi + see_your_traces: Zure aztarnak ikusi + traces_waiting: + one: '%{count} aztarna daukazu kargatzeko zain. Kontutan hartu gehiago igotzeko + agindua ez ematea zain zauden bitartean, beste erabiltzaile batzuei ilarak + ez blokeatzeko.' + other: '%{count} aztarnak dauzkazu kargatzeko zain. Kontutan hartu gehiago + igotzeko agindua ez ematea zain zauden bitartean, beste erabiltzaile batzuei + ilarak ez blokeatzeko.' trace_optionals: tags: Etiketak view: + title: '%{name} aztarna ikusten' + heading: '%{name} aztarna ikusten' pending: EGITEKE filename: 'Fitxategi-izena:' download: jaitsi uploaded: 'Noiz igota:' points: 'Puntuak:' + start_coordinates: 'Koordenatuak hasi:' map: mapa edit: aldatu owner: 'Jabea:' description: 'Deskribapena:' tags: 'Etiketak:' none: Ezer + edit_track: Aztarna hau aldatu + delete_track: Aztarna hau ezabatu + trace_not_found: Ez da aztarnarik aurkitu! visibility: 'Ikusgarritasuna:' + trace_paging_nav: + showing_page: '%{page}. orria' + older: Aztarna zaharragoak + newer: Aztarna berriagoak trace: pending: PRIBATUA count_points: '%{count} puntu' ago: duela %{time_in_words_ago} more: gehiago + trace_details: Ikusi Aztarna Xehetasunak view_map: Mapa ikusi edit: aldatu edit_map: Mapa aldatu public: PUBLIKOA + identifiable: IDENTIFIKAGARRIA private: PRIBATUA + trackable: JARRAIGARRIA + by: 'honen arabera:' + in: barruan map: mapa + list: + public_traces: GPS aztarna publikoak + your_traces: Zure GPS aztarnak + public_traces_from: '%{user} erabiltzailearen GPS aztarna publikoak' + description: Arakatu azkenaldian egin dire GPS ibilbide igoerak + tagged_with: '%{tags}(r)ekin etiketatua' + empty_html: Ez dago ezer hemen oraindik. Kargatu arrasto + berria edo GPS birziklatzeari buruz gehiago jakin nahi baduzu + wiki orrira jo . + delete: + scheduled_for_deletion: Ezabatzear dauden aztarnak + make_public: + made_public: Publikoak egindako aztarnak + offline_warning: + message: GPX fitxategia kargatzeko sistema ez dago erabilgarri + offline: + heading: Offline GPX Biltegia + message: GPX fitxategien biltegiratze eta kargatze sistema ez dago erabilgarri. + georss: + title: OpenStreetMap GPS Aztarnak + description: + description_with_count: + one: '%{user} %{count} puntua duen GPX fitxategia' + other: '%{user} %{count} puntuak dituen GPX fitxategia' + description_without_count: '%{user}ren GPX fitxategia' + application: + require_cookies: + cookies_needed: Cookieak desgaituta dituzu - gaitu cookie-ak zure nabigatzailean + jarraitu aurretik mesedez. + require_moderator: + not_a_moderator: Ekintza hori burutzeko moderatzaile izan behar duzu. + setup_user_auth: + blocked_zero_hour: OpenStreetMap webguneko premiazko mezu bat duzu. Zure aldaketak + gorde ahal izango dituzu mezua irakurri eta gero. + blocked: Zure APIrako sarbidea blokeatu egin da. Mesedez hasi ezazu saioa web-interfazean, + gehiago jakiteko. + need_to_see_terms: Zure APIrako sarbidea eten da aldi baterako. Hasi saioa web-interfazean, + Laguntzaileen Baldintzak ikusteko. Ez duzu ados egon behar, baina horiek ikusi + behar dituzu. oauth: oauthorize: + title: Zure kontuan sartzeko baimena eman + request_access: '%{app_name} aplikazioak zure konturako sarbidea eskatzen du, + %{user}. Egiaztatu eskaera hurrengo gaitasunak izatea nahi duzula. Nahi dituzun + edo ez bezalakoak aukeratu ditzakezu.' + allow_to: 'Baimendu bezeroaren aplikazioa:' + allow_read_prefs: Irakurri zure erabiltzaile hobespenak + allow_write_prefs: aldatu zure erabiltzaile hobespenak. + allow_write_diary: sortu eguroko sarreak, iruzkinak eta lagunak egin. allow_write_api: mapa aldatu. + allow_read_gpx: irakurri zure GPS aztarna pribatuak. + allow_write_gpx: GPS aztarnak igo. allow_write_notes: Oharrak aldatu. grant_access: Baimena Eman + oauthorize_success: + title: Baimen eskaera onartua + allowed: '%{app_name} aplikazioari zure kontura sartzeko baimena eman diozu.' + verification: Egiaztapen kodea %{code} da. + oauthorize_failure: + title: Baimen eskaerak kale egin du + denied: '%{app_name} aplikazioari zure kontura sartzeko baimena kendu diozu.' + invalid: Baimen token-a ez du balio. + revoke: + flash: '%{application}-rako token-a ezeztatu egin duzu' + permissions: + missing: Ez duzu aplikaziorako sarbidea baimendu instalazio honetan oauth_clients: new: + title: Aplikazio berri bat erregistratu submit: Erregistratu edit: + title: Zure aplikazioa editatu submit: Aldatu show: + title: '%{app_name}rako OAuth xehetasunak' + key: 'Kontsumitzaile Giltza:' + secret: 'Kontsumitzaile Sekretua:' + url: 'Token URLa eskatu:' + access_url: Token URLra sartu + authorize_url: 'URLa baimendu:' + support_notice: HMAC-SHA1 (gomendatua) eta RSA-SHA1 sinadurak onartzen ditugu. edit: Editatu xehetasunak delete: Ezabatu bezeroa confirm: Ziur zaude? + requests: 'Erabiltzaile honen ondorengo baimenak eskatu:' + allow_read_prefs: Irakurri haien erabiltzaile hobespenak. + allow_write_prefs: aldatu haien erabiltzaile hobespenak. + allow_write_diary: sortu eguroko sarreak, iruzkinak eta lagunak egin. allow_write_api: mapa aldatu. + allow_read_gpx: irakurri haien GPS aztarna pribatuak. + allow_write_gpx: GPS aztarnak igo. + allow_write_notes: oharrak aldatu. index: + title: Nire OAuth xehetasunak + my_tokens: Nire Baimendutako Aplikazioak + list_tokens: 'Honako tokenak zure izenean dituzun aplikazioetara igorri dira:' application: Aplikazioaren izena + issued_at: Hor emandakoa + revoke: Ezeztatu! + my_apps: Nire Bezero Aplikazioak + no_apps: Gurekin erabiltzeko erregistratu nahi duzun aplikazio bat duzu %{oauth} + estandarraren bidez? Zure web aplikazioa erregistratu behar duzu OAuth zerbitzurako + eskaera egin aurretik. + registered_apps: 'Ondorengo bezero aplikazio erregistratuak dituzu:' + register_new: Zure aplikazio erregistratu form: name: Izena required: Nahitaezkoa + url: URL Aplikazio Nagusia + callback_url: Berriz deitzeko URLa + support_url: Laguntza URLa + requests: 'Erabiltzaile honen ondorengo baimenak eskatu:' + allow_read_prefs: irakurri haien erabiltzaile hobespenak. + allow_write_prefs: aldatu haien erabiltzaile hobespenak. + allow_write_diary: sortu eguroko sarreak, iruzkinak eta lagunak egin. + allow_write_api: mapa aldatu. + allow_read_gpx: irakurri haien GPS aztarna pribatuak. + allow_write_gpx: GPS aztarnak igo. + allow_write_notes: oharrak aldatu. + not_found: + sorry: Barkatu, %{type} hori ezin izan da aurkitu. + create: + flash: Informazioa arrakastaz erregistratu da + update: + flash: Bezero informazioa arrakastaz eguneratu da + destroy: + flash: Bezeroaren eskaera erregistroa suntsitua user: login: title: Saio-hasiera @@ -964,19 +1780,51 @@ eu: lost password link: Pasahitza ahaztu duzu? login_button: Saioa hasi register now: Erregistratu orain + with username: 'Dagoeneko OpenStreetMap kontu bat duzu? Mesedez, saioa hasi + zure erabiltzaile-izenarekin eta pasahitzarekin:' + with external: 'Bestela, erabili hirugarrenen bat saioa hasteko:' new to osm: Berria zara OpenStreetMapen? + to make changes: OpenStreetMap-en aldaketak egiteko, kontu bat izatea beharrezkoa + duzu. create account minute: Sortu kontu bat. Minutu bat besterik ez duzu behar. no account: Ez al duzu konturik? + account not active: Barkatu, zure kontua ez dago aktibo oraindik.
    Mesedez, + erabili esteka kontuko berrespena mezu elektronikoa zure kontua aktibatzeko + edo baieztapen mezu elektroniko berri bat eskatzeko + . + account is suspended: Barkatu, zure kontua eten egin da jarduera susmagarriak + direla-eta.
    Mesedez, jarri harremanetan webmasterrekin + honi buruz hitz egin nahi baduzu. + auth failure: Barkatu, ezin izan da saioa hasi xehetasun horiekin. + openid_logo_alt: ID irekiarekin saioa hasi auth_providers: + openid: + title: ID irekiarekin saioa hasi + alt: Hasi saioa ID irekia duen URL batekin google: title: Saioa hasi Googlekin + alt: Google ID irekiarekin saioa hasi facebook: title: Saioa hasi Facebookekin alt: Saioa hasi Facebookekin windowslive: title: Saioa hasi Windows Livekin + alt: Windows Live kontu batekin saioa hasi + github: + title: GitHub-rekin saioa hasi + alt: GitHub kontuarekin saioa hasi + wikipedia: + title: Saioa hasi Wikipediarekin + alt: Wikipedia kontuarekin saioa hasi yahoo: title: Saioa hasi Yahoorekin + alt: Yahoo Open IDarekin saioa hasi + wordpress: + title: Wordpress bidez saioa hasi + alt: Wordpress ID irekiarekin saioa hasi + aol: + title: AOL erabiliz saioa hasi + alt: AOL ID irekiarekin saioa hasi logout: title: Saio-itxiera heading: OpenStreetMap-etik saioa itxi @@ -986,69 +1834,145 @@ eu: heading: Pasahitza ahaztuta? email address: 'Eposta helbidea:' new password button: Pasahitza berrezarri + help_text: Sartu saioa hastean erabiltzen zenuen helbide elektronikoa, zure + pasahitza berrezarri ahal izateko erabil dezakezu bidaliko dizugun esteka. + notice email on way: Sentitzen duzu hau galdu izatea :-( baina posta elektronikoa + bidaltzen ari zaizu laster berrabiarazi dezakezun. notice email cannot find: Eposta helbide hori ezin izan dugu aurkitu, barkatu. reset_password: title: Pasahitza berrezarri + heading: '%{user}-ren pasahitza berrezarri' password: 'Pasahitza:' confirm password: 'Pasahitza berretsi:' reset: Pasahitza berrezarri flash changed: Zure pasahitza aldatu da. + flash token bad: Token hori ez da aurkitu, URL egiaztatu beharbada? new: title: Eman izena + no_auto_account_create: Zoritxarrez ezin dizugu automatikoki kontu bat sortu. + contact_webmaster: Mesedez, jarri harremanetan web-arduradunarekin + kontu bat sortzerako - eskaera ahalik eta azkarren kudeatuko dugu. about: header: Doakoa eta editagarria + html: |- +

    Beste mapei ez bezala, OpenStreetMap zure gustuko pertsonek sortutakoa da guztiz, + eta doakoa da edonork konpontzeko, eguneratzeko, deskargatzeko eta erabiltzeko.

    +

    Erregistratu lehenengo laguntzeko. Zure kontua baieztatzeko mezu elektronikoa bidaliko dizugu.

    + license_agreement: Kontua baieztatzen duzunean + laguntzako terminoak adostu beharko dituzu. email address: 'Eposta Helbidea:' confirm email address: 'Eposta Helbidea baieztatu:' - not displayed publicly: Ez da erakutsiko (ikus, pribatutasun - politika) + not displayed publicly: Zure helbidea ez da publikoki erakutsiko, ikusi gure + pribatutasun politika) + informazio gehiagorako display name: 'Erakusteko izena:' + display name description: Zuk publikoki erakutsitako erabiltzaile izena. Hau + geroago alda dezakezu hobespenetan. + external auth: 'Hirugarrenen Autentifikazioa:' password: 'Pasahitza:' confirm password: 'Pasahitza berretsi:' + use external auth: Bestela, erabili hirugarrenen bat saioa hasteko + auth no password: Hirugarrenen autentifikazioarekin pasahitza ez da beharrezkoa, + baina zenbait tresna edo zerbitzari gehigarri batek oraindik ere behar izatea + gerta daiteke. continue: Eman izena + terms accepted: Eskerrik asko laguntzaileen termino berriak onartzeagatik! + terms declined: Sentitzen dugu Kolaboratzaileen baldintza berriak onartu ez + dituzula. Informazio gehiagorako, ikus wiki orri hau . terms: + title: Kolaboratzaile terminoak + heading: Kolaboratzaile terminoak + read and accept: Irakurri akordioa eta sakatu ados botoia akordioaren baldintzak + onartzen dituzula adierazteko zure lehendik dauden eta etorkizuneko ekarpenetarako + aplikatu daitezen. + consider_pd: Goiko hitzarmenaz gain, nire ekarpenak Domeinu Publikoan egon behar + direla uste dut consider_pd_why: zer da hau? + guidance: 'Termino hauek ulertzeko informazioa: giza laburpen + irakurgarria eta batzuk itzulpen informalak + ' agree: Ados decline: Ez onartu + you need to accept or decline: Irakurri eta gero, onartu edo ezetsi Kolaboratzaileen + termino berriak jarraitzeko. legale_select: 'Mesedez bizi zaren herrialdean aukeratu:' legale_names: france: Frantzia italy: Italy + rest_of_world: Gainerako mundua + no_such_user: + title: Ez dago horrelako erabiltzailerik + heading: '%{user} erabiltzailea ez da existitzen' + body: Barkatu, ez dago %{user} izenarekin erabiltzailerik. Egiaztatu ortografia, + edo agian egin duzun esteka gaizki dago. + deleted: ezabatua view: my diary: Nire egunerokoa + new diary entry: eguneroko sarrera berria my edits: Nire aldaketak + my traces: Nire Aztarnak my notes: Nire oharrak my messages: Nire mezuak my profile: Nire profila my settings: Nire Hobespenak my comments: Nire Iruzkinak + oauth settings: oauth ezarpenak + blocks on me: Nireganako blokeoak + blocks by me: Nik egindako blokeoak send message: Mezua bidali diary: Egunerokoa edits: Aldaketak + traces: Aztarnak + notes: Mapa Oharrak remove as friend: Lagun bezala kendu add as friend: Lagun bezala gehitu mapper since: 'Noiztik mapatzaile:' ago: (duela %{time_in_words_ago}) + ct status: 'Kolaboratzaile terminoak:' + ct undecided: Erabakigabea + ct declined: Ez da onartu + ct accepted: Duela %{ago} onartua + latest edit: 'Azken aldaketa %{ago}:' email address: 'Eposta helbidea:' + created from: 'Hemendik sortua:' status: 'Egoera:' + spam score: 'Spam Puntuazioa:' description: Deskribapen user location: Lankidearen kokapena + if set location: '%{settings_link} orrian zure helbidea ezarri hurbileko erabiltzaileak + ikusteko.' settings_link_text: hobespenak your friends: Zure lagunak + no friends: Oraindik ez duzu lagunik gehitu. km away: '%{count} km-tara' m away: '%{count} m-tara' nearby users: Gertuko beste erabiltzaile batzuk + no nearby users: Ez dago oraindik hurbileko mapa editatzea onartzen duen erabiltzailerik. role: administrator: Lankide hau administratzailea da moderator: Lankide hau moderatzailea da + grant: + administrator: Eman administratzaile sarbidea + moderator: Eman moderadorearen sarbidea + revoke: + administrator: Kendu administratzaile sarbidea + moderator: Kendu moderatzaile sarbidea + block_history: Blokeo Aktiboak + moderator_history: Emandako Blokeoak comments: Iruzkinak create_block: Blokeatu erabiltzaile hau activate_user: Erabiltzaile hau gaitu deactivate_user: Erabiltzaile hau ezgaitu confirm_user: Erabiltzaile hau baieztatu hide_user: Erabiltzaile hau ezkutatu + unhide_user: Erabiltzaile honen ezkutaketa kendu delete_user: Erabiltzaile hau ezabatu confirm: Berretsi + friends_changesets: Lagunen aldaketak + friends_diaries: Lagunen eguneroko sarrerak + nearby_changesets: inguruko erabiltzaileen aldaketak + nearby_diaries: inguruko erabiltzaileen eguneroko sarrerak popup: your location: Zure kokapena nearby mapper: Hurbileko mapeatzaileak @@ -1058,71 +1982,303 @@ eu: my settings: Nire aukerak current email address: 'Egungo eposta helbidea:' new email address: 'E-posta helbide berria:' + email never displayed publicly: (inoiz ez da publikoki bistaratuko) + external auth: 'Kanpoko Autentifikazioa:' openid: + link: http://wiki.openstreetmap.org/wiki/OpenID link text: zer da hau? public editing: heading: 'Aldaketa publikoak:' + enabled: Gaituta. Ez da anonimoa eta datuak editatu ditzake. enabled link: http://wiki.openstreetmap.org/wiki/Anonymous_edits enabled link text: zer da hau? + disabled: Ezgaituta dago eta ezin ditu datuak editatu, aurreko aldaketa guztiak + anonimoak dira. disabled link text: Zergatik ezin dut aldatu? public editing note: heading: Aldaketa publikoa + text: Gaur egun, zure aldaketak anonimoak dira eta jendeak ezin dizu mezurik + bidali edo zure kokapena ikusi. Editatu duzuna erakusteko eta webgunearen + bidez zurekin harremanetan jartzeko, hautatu beheko botoia. 0.6 API + aldaketaz geroztik, erabiltzaile publikoek soilik mapa datuak aldatu ditzakete + . ( jakin + zergatik ).
    • Zure helbide elektronikoa ez da agerian utziko + publikoa bihurtzearekin.
    • Ekintza hau ezin da alderantzikatu + eta erabiltzaile berri guztiek lehenespenez publikoak direlako.
    contributor terms: + heading: 'Kolaboratzaile Terminoak:' + agreed: Kolaboratzaile-termino berriak onartu dituzu. + not yet agreed: Oraindik ez duzu Laguntzaileen Baldintza berririk onartu. + review link text: Mesedez, jarraitu esteka hau zure Kolaboratzaile Terminoaen + erosotasuna berrikusteko eta onartzeko. + agreed_with_pd: Zure aldaketak domeinu publikoan egongo direla adierazi duzu. link text: zer da hau? profile description: 'Profilaren Deskribapena:' preferred languages: 'Hobetsitako hizkuntzak:' preferred editor: 'Lehenetsitako Editorea:' image: 'Irudia:' gravatar: + gravatar: Gravatar erabili link text: zer da hau? + disabled: Gravatar desgaitu egin da. + enabled: Zure Gravatar bistaratzea gaitu da. new image: Irudi bat gehitu + keep image: Oraingo irudia mantendu + delete image: Oraingo irudia kendu + replace image: Oraingo irudia ordezkatu + image size hint: (gutxienez 100x100ko irudi koadroak hobeto funtzionatzen dute) + home location: 'Etxeko Kokalekua:' + no home location: Zure etxe-helbidea ez duzu txertatu. latitude: 'Latitude:' longitude: 'Longitude:' + update home location on click: Eguneratu etxeko kokalekua mapan klik egiten + dudanean? save changes button: Aldaketak gorde + make edits public button: Nire aldaketa guztiak publikoak egin return to profile: Profilera itzuli + flash update success confirm needed: Erabiltzaile informazio igoera arrakastatsua. + Zure email-a begiratu posta elektroniko berria egiaztatzeko oharra ikusteko. + flash update success: Erabiltzailearen informazioa behar bezala eguneratu da. confirm: heading: Helbide elektronikoa begiratu! + introduction_1: Berrespen-mezu bat bidali dizugu. + introduction_2: Berretsi kontua posta elektronikoaren estekan klik eginez eta + mapak hasteko gai izango zara. + press confirm button: Sakatu beheko berresteko botoia zure kontua aktibatzeko. button: Berretsi + success: Zure kontua berretsi du, erregistratzeagatik milesker! + already active: Kontu hau dagoeneko berretsi da. + unknown token: Berrespen-kodea iraungi egin da edo ez da existitzen. + reconfirm_html: Berrespen-mezu elektronikoa bidaltzea behar baduzu, egin + klik hemen. + confirm_resend: + success: Berrespen ohar bat bidali dugu %{email} helbidera eta zure kontua berretsi + bezain laster, mapak eskuratu ahal izango dituzu.

    Berrespen eskaerak + bidaltzen dituen antispam sistema erabiltzen baduzu, mesedez ziurta zaitez + %{sender} zurien zerrenda duzula, baieztapen eskaerei erantzun ezin diegulako. + failure: '%{name} erabiltzailea ez da aurkitu.' confirm_email: + heading: Helbide elektronikoan aldaketa bat baieztatu + press confirm button: Sakatu beheko berresteko botoia zure helbide elektroniko + berria berresteko. button: Berretsi + success: Helbide elektronikoan aldaketa baieztatu da! + failure: Helbide elektroniko bat egiaztatu da token honekin. + unknown_token: Baieztapen-kode hori iraungi egin da edo ez da existitzen. + set_home: + flash success: Etxeko helbidea modu egokian gorde da. + go_public: + flash success: Zure aldaketa guztiak publikoak dira orain, eta orain editatzeko + baimena daukazu. + make_friend: + heading: '%{user} lagun bezala gehitu?' + button: Gehitu lagun gisa + success: '%{name} zure laguna de orain!' + failed: Barkatu, %{name} lagun bezala ezin izan da gehitu. + already_a_friend: '%{name} eta zuk lagunak zarete jada.' remove_friend: + heading: '%{user} lagun moduan kendu?' + button: Lagun bezala kendu + success: '%{name} zure lagunetatik kendu egin da.' not_a_friend: '%{name} ez da zure laguna.' + filter: + not_an_administrator: Ekintza hori burutzeko administratzaile izan behar duzu. list: title: Erabiltzaileak heading: Erabiltzaileak + showing: + one: '%{page} orria (%{items}n %{first_item})' + other: '%{page} orria (%{items}ko %{first_item}-%{last_item})' + summary: '%{date}n %{ip_address}tik %{name} sortu da' + summary_no_ip: '%{name} %{date} datan sortua' + confirm: Berretsi Hautatutako Erabiltzaileak + hide: Ezkutatu Hautatutako Erabiltzaileak + empty: No matching users found suspended: title: Kontua bertan behera geratu da heading: Kontua bertan behera geratu da webmaster: webmaster + body: |- +

    +    Barkatu, zure kontua automatikoki eten egin da +    jarduera susmagarriak direla eta. +

    +

    +    Erabaki hau administrari batek berrikusiko du laster, edo +    %{webmaster}rekin harremanetan jar zaitezke horri buruz eztabaidatu nahi baduzu. +

    + auth_failure: + connection_failed: Autentifikazioaren hornitzailearekin konexioa huts egin du + invalid_credentials: Autentifikazio kredentzialak baliogabekoak dira + no_authorization_code: Baimen koderik ez + unknown_signature_algorithm: Algortimo sinadura ezezaguna + invalid_scope: Baliogabeko esparrua + auth_association: + heading: Zure IDa oraindik ez dago OpenStreetMap kontuarekin lotuta. + option_1: OpenStreetMap-en berria bazara, sortu kontu berria beheko formularioa + erabiliz mesedez. + option_2: |- + Kontua baduzu dagoeneko, zure kontuan saioa has dezakezu + zure erabiltzaile-izena eta pasahitza erabiliz eta kontua lotu + zure IDarekin zure erabiltzaileen ezarpenekin. user_role: + filter: + not_an_administrator: Administratzaileek bakarrik erabiltzailearen rolak kudeatu + ditzakete, eta ez zara administratzailerik. + not_a_role: '''%{role}'' katea ez da baliozko rola.' + already_has_role: Erabiltzaileak %{role} rola dauka jadanik. + doesnt_have_role: Erabiltzaileak ez dauka %{role} rolik. grant: + title: Berretsi eginkizuna ematea + heading: Berretsi eginkizuna ematea + are_you_sure: Ziur zaude `%{role}' rola eman nahi diozula`%{name}' erabiltzaileari? confirm: Berretsi + fail: Ezin izan da "%{role} rola esleitu `%{name}' erabiltzailearentzat. Egiaztatu + erabiltzaile eta rola baliagarriak direla. revoke: + title: Berretsi eginkizuna kentzea + heading: Berretsi eginkizuna kentzea + are_you_sure: Ziur zaude `%{role}' rola kendu nahi diozula`%{name}' erabiltzaileari? confirm: Berretsi + fail: '%{name} erabiltzaileari ezin izan zaio %{role} rola ezeztatu. Egiaztatu + erabiltzailea eta rola balio duten mesedez.' user_block: + model: + non_moderator_update: Moderatzailea izan behar du blokeo bat sortu edo eguneratzeko. + non_moderator_revoke: Moderatzaile izan behar da blokeo bat ezeztatzeko. + not_found: + sorry: Barkatu, %{id} ID-aren erabiltzaile-blokea ezin da aurkitu. + back: Itzuli sarrerara + new: + title: '%{name}n blokeoa sortzen' + heading: '%{name}n blokeoa sortzen' + reason: ' %{name} blokeatuta dagoen zergatia. Behar bezain lasai eta ahalik + eta arrazoizkoa izan, egoeraren inguruko xehetasun guztiak emanez, mezu hori + publikoki ikusgai egongo dela gogoratuz. Gogoan izan, erabiltzaile guztiek + ez dutela komunitatearen jargia ulertzen, beraz, saiatu laymans terminoak + erabiltzen.' + period: Zenbat denbora, orain hasita, erabiltzaileak APIan blokeoa jasoko duen. + submit: Blokea sortu + tried_contacting: Erabiltzailearekin kontaktuan jarri naiz eta gelditzeko eskatu + diet. + tried_waiting: Denbora egokia eman diet erabiltzaileei komunikazio horiei erantzuteko. + needs_view: Erabiltzaileak saioa hasi behar du blokeoa kendu baino lehen. + back: Ikusi bloke guztiak + edit: + title: '%{name}n blokeoa editatzen' + heading: '%{name}n blokeoa editatzen' + reason: ' %{name} blokeatuta dagoen zergatia. Behar bezain lasai eta ahalik + eta arrazoizkoa izan, egoeraren inguruko xehetasun guztiak emanez. Gogoan + izan, erabiltzaile guztiek ez dutela komunitatearen jargia ulertzen, beraz, + saiatu laymans terminoak erabiltzen.' + period: Zenbat denbora, orain hasita, erabiltzaileak APIan blokeoa jasoko duen. + submit: Blokea eguneratu + show: Ikusi bloke hau + back: Ikusi bloke guztiak + needs_view: Erabiltzaileak saioa hasi behar al du bloke hau garbitu aurretik? + filter: + block_expired: Blokea dagoeneko iraungi da eta ezin da editatu. + block_period: Blokeoaren iraupena goitibeherako zerrendan hautatutako balioetariko + bat izan behar da. + create: + try_contacting: Mesedez, jarri harremanetan erabiltzailearekin blokeatu aurretik + eta erantzuteko arrazoizko denbora bat emanez. + try_waiting: Saiatu erabiltzaileari denbora errekurtso egokia ematen, blokeatu + aurretik. + flash: '%{name} erabiltzailean blokeoa sortu da.' + update: + only_creator_can_edit: Soilik blokeoa sortu zuen moderatzaileak editatu dezake. + success: Blokea eguneratu da. + index: + title: Erabiltzaile blokeak + heading: Erabiltzaile blokeen zerrenda + empty: Blokeorik ez da egin oraindik. + revoke: + title: '%{block_on} blokeoa ezeztatzen' + heading: '%{block_by} erabiltzaileak egindako %{block_on} blokeoa ezeztatzen' + time_future: Blokeo hau %{time}-n bukatuko da. + past: Blokeo hau duela %{time} bukatu da eta ezin da orain ezeztatu. + confirm: Blokeo hau ezeztatu nahi duzula argi daukazu? + revoke: Ezeztatu! + flash: Bloke hau ezeztatu egin da. period: one: ordu bat other: '%{count} ordu' partial: show: Erakutsi edit: Aldatu + revoke: Ezeztatu! confirm: Ziur zaude? + display_name: Blokeatutako Erabiltzailea creator_name: Egilea + reason: Blokeatzeko arrazoia status: Egoera + revoker_name: -k ezeztatua + not_revoked: (ez da ezeztatu) + showing_page: '%{page} orria' next: Hurrengoa » previous: « Aurrekoa + helper: + time_future: '%{time}n bukatzen du' + until_login: Erabiltzaileak saioa hasi arte aktiboa. + time_future_and_until_login: '%{time} denbora barru bukatzen du eta erabiltzaileak + saioa hasi eta gero.' + time_past: Duela %{time} bukatua. + blocks_on: + title: '%{name}n dauden blokeoak' + heading: '%{name}n blokeoen zerrenda' + empty: '%{name} erabiltzaileak oraindik ez du blokeorik jaso.' + blocks_by: + title: '%{name} erabiltzailearen blokeoak' + heading: '%{name} erabiltzailearen blokeo zerrendak' + empty: '%{name} erabiltzaileak oraindik ez du blokeorik egin.' show: + title: '%{block_on} %{block_by}k blokeatu du' + heading: '%{block_on} %{block_by}k blokeatu du' + time_future: '%{time}n bukatzen du' + time_past: Duela %{time} bukatua + created: Sortua + ago: duela %{time} status: Egoera show: Erakutsi edit: Aldatu + revoke: Ezeztatu! confirm: Ziur zaude? + reason: 'Blokeatzeko arrazoia:' + back: Blokeo guztiak ikusi + revoker: 'Ezeztatu duena:' + needs_view: Erabiltzaileak saioa hasi behar du blokeoa kendu baino lehen. note: description: opened_at_html: Duela %{when} sortua + opened_at_by_html: '%{user}-ek duela %{when} sortua' commented_at_html: Duela %{when} eguneratua + commented_at_by_html: Duela %{when} %{user}k eguneratua + closed_at_html: Duela %{when} ebatzia + closed_at_by_html: Duela %{when} %{user}k ebatzia + reopened_at_html: Duela %{when} berraktibatua + reopened_at_by_html: Duela %{when} %{user}k berraktibatua + rss: + title: OpenStreetMap oharrak + description_area: Iruzkinak dituzten, itxi diren edota iragarki diren oharren + zerrenda [(%{min_lat}|%{min_lon}) -- (%{max_lat}|%{max_lon})] + description_item: Rss feed bat %{id} oharrarentzako + opened: ohar berria (%{place} ingurutik) + commented: iruzkin berria (%{place} ingurutik) + closed: ohar itxia (%{place} ingurutik) + reopened: birraktibatutako oharra (%{place} ingurutik) + entry: + comment: Iruzkina + full: Ohar osoa mine: + title: '%{user}k igotako edo iruzkinak utzitako oharrak' + heading: '%{user} erabiltzailearen oharrak' + subheading: '%{user}k igotako edo iruzkinak utzitako oharrak' + id: Id-a creator: Sortzailea description: Deskribapena + created_at: 'Non sortua:' + last_changed: Azkenik aldaketua ago_html: Duela %{when} javascripts: close: Itxi @@ -1130,41 +2286,87 @@ eu: title: Partekatu cancel: Utzi image: Irudia - long_link: Lotura - short_link: Lotura laburra + link: Esteka edo HTMLa + long_link: Esteka + short_link: Esteka laburra + geo_uri: Geo URI + embed: HTML + custom_dimensions: Dimentsio ezarpen pertsonalizatuak ezarri format: 'Formatua:' scale: 'Eskala:' + image_size: 'Irudia geruza estandarra erakutsiko du hor:' download: Deskargatu short_url: URL laburra + include_marker: Markatzailea sartu + center_marker: Markatzailean mapa erdiratu + paste_html: Itsatsi HTMLa webgunean kapsulatzeko view_larger_map: Ikusi mapa handiagoa + only_standard_layer: Geruza estandarra soilik irudi gisa esportatu daiteke embed: report_problem: Arazo baten berri eman + key: + title: Maparen gakoa + tooltip: Maparen gakoa + tooltip_disabled: Maparen gakoa ez dago eskuragarri geruza honetarako map: + zoom: + in: Handiagotu + out: Txikiagotu locate: title: Erakutsi nire kokapena + popup: Puntu honetatik {distance} {unit}-ra zaude base: - transport_map: Garraio-mapa + standard: Arrunta + cycle_map: Bizikletentzako mapa + transport_map: Garraioen mapa + hot: Humanitarioa layers: header: Maparen geruzak notes: Maparen oharrak data: Maparen datuak + gps: GPS aztarna publikoak + overlays: Gaitu maparen konponketa egiteko gainjartzen direnak title: Geruzak + copyright: © OpenStreetMap kolaboratzaileak + donate_link_text: site: edit_tooltip: Editatu mapa + edit_disabled_tooltip: Handiagotu mapa aldatzeko + createnote_tooltip: Gehitu oharra mapari + createnote_disabled_tooltip: Handiagotu mapari ohar bat gehitzeko + map_notes_zoom_in_tooltip: Handiagotu mapa oharrak ikusteko + map_data_zoom_in_tooltip: Handiagotu mapa datuak ikusteko + queryfeature_tooltip: Eskaera ezaugarriak + queryfeature_disabled_tooltip: Handiagotu ezaugarriak eskatzeko changesets: show: + comment: Iruzkina subscribe: Harpidetu unsubscribe: Harpidetza kendu hide_comment: ezkutatu unhide_comment: erakutsi notes: new: + intro: Akats bat edo zerbait falta zaizu? Utzi beste mapa editatzaileek jakin + dezaten, beraz konpon dezakegun. Mugitu markatzailea posizio egokira eta + idatzi ohar bat arazoa azaltzeko. (Mesedez, ez sartu informazio pertsonala + edo informazioa copyrighteko mapa edo direktorioa zerrendetatik.) add: Gehitu oharra show: + anonymous_warning: Ohar honek independenteak izan behar diren erabiltzaile + anonimoen iruzkinak barne hartzen ditu. hide: Ezkutatu + resolve: Konpondu + reactivate: Berriz aktibatu + comment_and_resolve: Utzi iruzkina eta Konpondu + comment: Iruzkina + edit_help: Mugitu mapa eta zooma editatu nahi duzun kokaleku batean erabili, gero + klik hemen egin. directions: + ascend: Igo engines: graphhopper_bicycle: Bizikletaz (GraphHopper) + graphhopper_car: Autoz(GraphHopper) graphhopper_foot: Oinez (GraphHopper) mapquest_bicycle: Bizikletaz (MapQuest) mapquest_car: Autoz (MapQuest) @@ -1173,18 +2375,93 @@ eu: mapzen_bicycle: Bizikletaz (Mapzen) mapzen_car: Autoz (Mapzen) mapzen_foot: Oinez (Mapzen) + descend: Jaitsi + directions: Norabideak distance: Distantzia + errors: + no_route: Ezin izan da bi lekuen artean ibilbidea aurkitu. + no_place: Barkatu - ezin izan da toki hori aurkitu. instructions: + continue_without_exit: '%{name}n jarraitu' + slight_right_without_exit: '%{name}-ra jo eskumara pixka bat biratuz' + offramp_right_without_exit: Eskumako arranpala hartu %{name}-ra + onramp_right_without_exit: Arranpalan eskumara bira egin %{name}-ra + endofroad_right_without_exit: Errepide bukaeran eskumara bira egin %{name}-ra + merge_right_without_exit: Eskumara batu %{name}-ra + fork_right_without_exit: Desbideratzean eskumara bira egin %{name}-ra + turn_right_without_exit: '%{name}-ra eskumara bira egin' + sharp_right_without_exit: Eskumara bira handia egin %{name}-ra + uturn_without_exit: '%{name}-ra U-biraketa egin' + sharp_left_without_exit: Ezkerrera bira handia egin %{name}-ra + turn_left_without_exit: '%{name}-ra ezkerrera bira egin' + offramp_left_without_exit: Ezkerreko arranpala hartu %{name}-ra + onramp_left_without_exit: Arranpalan %{name}-ra bira egin ezkerrera + endofroad_left_without_exit: Errepide bukaeran ezkerrera bira egin %{name}-ra + merge_left_without_exit: Ezkerrera batu %{name}-ra + fork_left_without_exit: Desbideratzean ezkerrera bira egin %{name}-ra + slight_left_without_exit: '%{name}-ra jo ezkerrera pixka bat biratuz' + via_point_without_exit: (puntutik) + follow_without_exit: '%{name} jarraitu' + roundabout_without_exit: Biribilgunean hartu %{name} + leave_roundabout_without_exit: Utzi biribilgunea - %{name} + stay_roundabout_without_exit: Biribilgunean geratu - %{name} + start_without_exit: '%{name} bukaeran hasi' + destination_without_exit: Helmugara iritsi + against_oneway_without_exit: '%{name}n bide-bakarreraren kontra joan' + end_oneway_without_exit: 'Bide-bakarreko bukaera hemen: %{name}' + roundabout_with_exit: Biribilgunean %{exit} irteera %{name}rantz + turn_left_with_exit: Biribilgunean ezkerra jo %{name}ra joateko + slight_left_with_exit: Biribilgunean ezkerra pixka bat jo %{name} norabiderantza + turn_right_with_exit: Biribilgunean eskumara bira egin %{name} norabiderantza + slight_right_with_exit: Biribilgunean eskumara pixka bat jo %{name} norabiderantza + continue_with_exit: Biribilgunean jarraitu zuzen %{name} norabiderantza unnamed: izenik gabe + courtesy: Helbideak %{link}-ren adeitasunez. + time: Denbora + query: + node: Nodo + way: Bidea + relation: Erlazioa + nothing_found: Ez da ezaugarririk aurkitu + error: '%{server} konektatzerakoan akatsa: %{error}' + timeout: '%{server} kontaktatzeko denbora bukatu da' context: + directions_from: Hemendik norabideak + directions_to: Norabideak hona + add_note: Gehitu ohar bat hemen show_address: Erakutsi helbidea + query_features: Eskaera ezaugarriak + centre_map: Mapa hona zentratu redaction: edit: description: Deskribapena + heading: Aldatu erredakzioa + submit: Gorde erredakzioa + title: Aldatu erredakzioa + index: + empty: Ez dago erakusteko erredakziorik. + heading: Erredakzio zerrenda + title: Erredakzio zerrenda new: description: Deskribapena + heading: Erredakzio berrirako informazioa sartu + submit: Erredakzioa sortu + title: Erredakzio berria sortzen show: description: 'Deskribapena:' + heading: '"%{title}" erredakzioa erakusten' + title: Erredakzioa erakusten user: 'Sortzailea:' + edit: Aldatu erredakzio hau + destroy: Erredakzio hau kendu confirm: Ziur zaude? + create: + flash: Erredakzioa sortu egin da. + update: + flash: Aldaketak gorde dira. + destroy: + not_empty: Erredakzioa ez dago hutsik. Berreskuratu honen bertsio guztiak suntsitu + aurretik. + flash: Erredakzioa suntsitu egin da. + error: Erredakzio hau suntsitzerakoan akats bat egon da. ... diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 715eb80b1..45891c424 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -405,7 +405,6 @@ fa: search: title: latlon: نتایج داخلی - us_postcode: نتایج Geocoder.us uk_postcode: نتایج NPEMap / FreeThe Postcode ca_postcode: نتایج Geocoder.CA osm_nominatim: نتایج OpenStreetMap @@ -1393,6 +1392,7 @@ fa: date: تاریخ reply_button: پاسخ unread_button: علامت‌گذاری به عنوان خوانده‌شده + delete_button: حذف back: عقب to: به wrong_user: شما بعنوان `%{user}' وارد سامانه شده‌اید اما پیامی که درخواست خواندنش @@ -1794,6 +1794,9 @@ fa: github: title: ورود با GitHub alt: با یک حساب کاربری در GitHub وارد شوید + wikipedia: + title: ورود با ویکی‌پدیا + alt: ورود با حساب کاربر ویکی‌پدیا yahoo: title: ورود با یاهو alt: ورود با OpenID یاهو @@ -2295,6 +2298,7 @@ fa: header: لایه های نقشه notes: یادداشت های نقشه data: داده های نقشه + gps: پیگیری‌های GPS عمومی overlays: فعال سازی همپوشانی ها برای اشکال زدایی نقشه title: لایه ها copyright: © شرکت کنندگانOpenStreetMap @@ -2332,8 +2336,10 @@ fa: edit_help: نقشه را جابجا کنید و روی مکانی که میخواهید ویرایش کنید بزرگنمایی کنید، سپس اینجا کلیک کنید. directions: + ascend: صعود engines: graphhopper_bicycle: دوچرخه (GraphHopper) + graphhopper_car: ماشین (GraphHopper) graphhopper_foot: پیاده (GraphHopper) mapquest_bicycle: دوچرخه (MapQuest) mapquest_car: اتومبیل (MapQuest) diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 19777376f..1d48d2c50 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -2,6 +2,7 @@ # Exported from translatewiki.net # Export driver: phpyaml # Author: Alluk. +# Author: BriskyBlizzard # Author: Centerlink # Author: Crt # Author: Daeron @@ -412,7 +413,6 @@ fi: search: title: latlon: Sisäiset tulokset - us_postcode: Tulokset palvelusta Geocoder.us uk_postcode: Tulokset palvelusta NPEMap / FreeThe Postcode ca_postcode: Tulokset palvelusta Geocoder.CA @@ -977,8 +977,8 @@ fi: intro_text: OpenStreetMap on tavallisten ihmisten luoma maailmankartta. Palvelun käyttäminen on ilmaista avoimen lisenssin ansiosta. intro_2_create_account: luomalla ensin käyttäjätunnuksen - partners_html: Palvelinta ylläpitää %{ucl}, %{ic} ja %{bytemark} sekä muut %{partners}. - partners_ucl: UCL VR Centre + partners_html: Palvelinta ylläpitävät %{ucl}, %{bytemark}, %{ic} sekä muut %{partners}. + partners_ucl: UCL partners_ic: Imperial College London partners_bytemark: Bytemark Hosting partners_partners: kumppanimme @@ -1043,8 +1043,8 @@ fi: title: Nimeämisesimerkki more_title_html: Lisätietoja more_1_html: |- - Lue lisää aineiston käyttämisestä OSM-säätiön lisensointiohjeesta ja yhteisön keräämistä lakiasioiden useimmin kysytyimmistä kysymyksistä. + Lue lisää aineistomme käyttämisestä ja kuinka mainita meidät lähteenä OSM-säätiön lisensointiohjeesta. more_2_html: "Vaikka OpenStreetMap on avointa dataa, emme voi tarjota maksutonta karttarajapintaa (API) kolmannen osapuolen kehittäjille.\n\nTutustu karttarajapinnan käyttöehtoihin,\nkartta-aineiston @@ -1225,7 +1225,7 @@ fi: ajan tasalla. community_driven_title: Yhteisön voima community_driven_html: |- - OpenStreetMap-yhteisö on monipuolinen, intohimoinen ja kasvaa joka päivä. Yhteisöön kuuluu harrastajakartoittajia, GIS-ammattilaisia, järjestelmää ylläpitäviä insinöörejä, humanitaarisia auttajia, jotka kartoittavat katastrofin kärsineitä alueita sekä monia muita. Lisätietoja yhteisöstä saa lukemalla käyttäjien päiväkirjoja, + OpenStreetMap-yhteisö on monipuolinen, intohimoinen ja kasvaa joka päivä. Yhteisöön kuuluu harrastajakartoittajia, GIS-ammattilaisia, järjestelmää ylläpitäviä insinöörejä, humanitaarisia auttajia, jotka kartoittavat katastrofin kärsineitä alueita sekä monia muita. Lisätietoja yhteisöstä saa lukemalla OpenStreetMap-blogia, käyttäjien päiväkirjoja, yhteisöblogeja ja OSM-säätiön verkkosivua. open_data_title: Avoin data @@ -1412,6 +1412,7 @@ fi: date: Päiväys reply_button: Vastaa unread_button: Merkitse lukemattomaksi + delete_button: Poista back: Takaisin to: 'Vastaanottaja:' wrong_user: Olet kirjautunut sisään tunnuksella `%{user}' mutta viestiä, jonka @@ -1463,7 +1464,7 @@ fi: get_directions_title: Hae reittiohjeet kahden paikan välille from: Lähtöpaikka to: Määränpää - where_am_i: Nykyinen sijainti? + where_am_i: Missä tämä on? where_am_i_title: Määrittää nykyisen sijainnin hakukoneella submit_text: Hae key: @@ -2350,6 +2351,7 @@ fi: directions: engines: graphhopper_bicycle: Pyörällä (GraphHopper) + graphhopper_car: Auto (GraphHopper) graphhopper_foot: Kävellen (GraphHopper) mapquest_bicycle: Pyörällä (MapQuest) mapquest_car: Ajaen (MapQuest) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index a32ce85a0..f310a7aaa 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -353,7 +353,7 @@ fr: l’id %{id}. Veuillez vérifier votre orthographe ou la validité du lien que vous avez cliqué. diary_entry: - posted_by: Posté par %{link_user} à %{created} en %{language_link} + posted_by: Publié par %{link_user} à %{created} en %{language_link} comment_link: Commenter cette entrée reply_link: Répondre à cet article comment_count: @@ -442,7 +442,6 @@ fr: search: title: latlon: Résultats internes - us_postcode: Résultats depuis Geocoder.us uk_postcode: Résultats depuis NPEMap / FreeThe Postcode ca_postcode: Résultats depuis Geocoder.CA @@ -608,8 +607,8 @@ fr: living_street: Rue en zone de rencontre milestone: Borne kilométrique motorway: Autoroute - motorway_junction: Bretelle d’autoroute / Sortie - motorway_link: Voie autoroutière + motorway_junction: Sortie / Échangeur + motorway_link: Bretelle d’autoroute path: Chemin pedestrian: Rue piétonne platform: Plateforme @@ -711,7 +710,7 @@ fr: horse_riding: Équitation ice_rink: Patinoire marina: Port de plaisance - miniature_golf: Golf miniature + miniature_golf: Mini golf nature_reserve: Réserve naturelle park: Parc pitch: Terrain de sport @@ -853,7 +852,7 @@ fr: beverages: Magasin de boissons bicycle: Magasin de vélos books: Librairie - boutique: Boutique + boutique: Boutique de mode butcher: Boucherie car: Concession automobile car_parts: Pièces d’automobile @@ -894,7 +893,7 @@ fr: jewelry: Bijouterie kiosk: Kiosque laundry: Blanchisserie - mall: Galerie marchande + mall: Centre commercial market: Marché mobile_phone: Boutique de téléphones mobiles motorcycle: Magasin de motos @@ -1007,7 +1006,7 @@ fr: intro_text: OpenStreetMap est une carte du monde, créée par des gens comme vous et libre d’utilisation sous licence libre. intro_2_create_account: Créez un compte d’utilisateur - partners_html: L’hébergement est pris en charge par %{ucl}, %{ic}, %{bytemark} + partners_html: L’hébergement est pris en charge par %{ucl}, %{bytemark}, %{ic} et d’autres %{partners}. partners_ucl: L’''University College'' de Londres partners_ic: le Collège impérial de Londres @@ -1268,12 +1267,12 @@ fr: La communauté d’OpenStreetMap est diverse, passionnée et grossit chaque jour. Nos contributeurs incluent des cartographes enthousiastes, des professionnels du SIG, des ingénieurs qui font fonctionner les serveurs d’OSM, des humanitaires cartographiant les zones dévastées par une catastrophe et bien d’autres. Pour en savoir plus sur la communauté, consultez les annuaires d’utilisateurs, les blogues communautaires et le site web de la Fondation OSM. open_data_title: Données libres - open_data_html: 'OpenStreetMap est en open data : vous êtes libre de l’utiliser - pour n’importe quel but tant que vous créditez OpenStreetMap et ses contributeurs. - Si vous modifiez ou vous appuyez sur les données d’une façon quelconque, vous - pouvez distribuer le résultat seulement suivant la même licence. Consultez la - page sur les droits d’auteur et licence pour - plus de détails.' + open_data_html: 'OpenStreetMap est en données ouvertes : vous êtes libre + de l’utiliser pour n’importe quel but tant que vous créditez OpenStreetMap et + ses contributeurs. Si vous modifiez ou vous appuyez sur les données d’une façon + quelconque, vous pouvez distribuer le résultat seulement suivant la même licence. + Consultez la page sur les droits d’auteur et licence + pour plus de détails.' legal_title: Juridique legal_html: "Ce site et de nombreux autres services connexes sont formellement exploités par la \nFondation OpenStreetMap @@ -1286,9 +1285,10 @@ fr: partners_title: Partenaires notifier: diary_comment_notification: - subject: '[OpenStreetMap] %{user} a posté un commentaire sur un article de journal' + subject: '[OpenStreetMap] %{user} a publié un commentaire sur un article de + journal' hi: Bonjour %{to_user}, - header: '%{from_user} a posté un commentaire sur un article récent du journal + header: '%{from_user} a publié un commentaire sur un article récent du journal OpenStreetMap avec le sujet %{subject} :' footer: Vous pouvez également lire le commentaire sur %{readurl}, le commenter sur %{commenturl} ou répondre sur %{replyurl} @@ -1463,6 +1463,7 @@ fr: date: Date reply_button: Répondre unread_button: Marque comme non lu + delete_button: Supprimer back: Retour to: À wrong_user: Vous êtes identifié comme « %{user} » mais le message que vous essayez @@ -1497,8 +1498,8 @@ fr: user_page_link: page utilisateur anon_edits_link_text: Trouvez pourquoi ici. flash_player_required: Vous avez besoin d’un lecteur Flash pour utiliser Potlatch, - l’éditeur Flash de OpenStreetMap. Vous pouvez télécharger - Flash Player sur le site d’Adobe. D’autres + l’éditeur Flash d’OpenStreetMap. Vous pouvez télécharger + Flash Player depuis le site d’Adobe. D’autres options sont également disponibles pour modifier OpenStreetMap. potlatch_unsaved_changes: Vous avez des modifications non enregistrées. (Pour enregistrer dans Potlatch, désélectionnez la ligne ou le nœud actuel lors @@ -1520,7 +1521,7 @@ fr: get_directions_title: Trouvez des itinéraires entre deux points from: De to: À - where_am_i: Où suis-je ? + where_am_i: Où est-ce ? where_am_i_title: Décrit la position actuelle en utilisant le moteur de recherche submit_text: Aller key: diff --git a/config/locales/fur.yml b/config/locales/fur.yml index ba6225930..66dff0829 100644 --- a/config/locales/fur.yml +++ b/config/locales/fur.yml @@ -354,7 +354,6 @@ fur: search: title: latlon: Risultâts cjolts dal sît interni - us_postcode: Risultâts cjolts di Geocoder.us uk_postcode: Risultâts cjolts di NPEMap / FreeThe Postcode ca_postcode: Risultâts cjolts di Geocoder.CA diff --git a/config/locales/ga.yml b/config/locales/ga.yml index f32a5cb06..a575b3224 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -382,7 +382,6 @@ ga: search: title: latlon: Torthaí Inmheánach - us_postcode: Torthaí ó Geocoder.us uk_postcode: Torthaí ó NPEMap / FreeThe Postcode ca_postcode: Torthaí ó Geocoder.CA diff --git a/config/locales/gd.yml b/config/locales/gd.yml index 4b25790c2..09c5570f7 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -402,7 +402,6 @@ gd: search: title: latlon: Toraidhean on taobh a-staigh - us_postcode: Toraidhean o Geocoder.us uk_postcode: Toraidhean o NPEMap / FreeThe Postcode ca_postcode: Toraidhean o Geocoder.CA diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 324b9723a..9003bb3ce 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -384,7 +384,6 @@ gl: search: title: latlon: Resultados internos - us_postcode: Resultados desde Geocoder.us uk_postcode: Resultados desde NPEMap / FreeThe Postcode ca_postcode: Resultados desde Geocoder.CA @@ -951,7 +950,7 @@ gl: intro_2_create_account: Cree unha conta de usuario partners_html: O aloxamento é posible grazas ao %{ucl}, %{ic} e %{bytemark}, e outros %{partners}. - partners_ucl: centro de realidade virtual do UCL + partners_ucl: UCL partners_ic: Imperial College London partners_bytemark: Bytemark Hosting partners_partners: socios @@ -1423,6 +1422,7 @@ gl: date: Data reply_button: Responder unread_button: Marcar como non lida + delete_button: Borrar back: Volver to: Para wrong_user: Accedeu ao sistema como "%{user}", pero a mensaxe que pediu ler @@ -2384,6 +2384,7 @@ gl: ascend: Ascendente engines: graphhopper_bicycle: Bicicleta (GraphHopper) + graphhopper_car: En coche (GraphHopper) graphhopper_foot: A pé (GraphHopper) mapquest_bicycle: Bicicleta (MapQuest) mapquest_car: Coche (MapQuest) diff --git a/config/locales/he.yml b/config/locales/he.yml index 522eaaebc..31ed5c2b9 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -9,6 +9,7 @@ # Author: ExampleTomer # Author: GilCahana # Author: Guycn2 +# Author: HarelM # Author: Inkbug # Author: Itay naor # Author: LaG roiL @@ -94,11 +95,11 @@ he: display_name: שם לתצוגה description: תיאור languages: שפות - pass_crypt: ססמה + pass_crypt: סיסמה printable_name: with_name_html: '%{name} (%{id})' editor: - default: בררת מחדל (כעת %{name}) + default: ברירת מחדל (כעת %{name}) potlatch: name: Potlatch 1 description: Potlatch 1 (עורך בתוך הדפדפן) @@ -392,7 +393,6 @@ he: search: title: latlon: תוצאות מתוך האתר הזה - us_postcode: תוצאות מאתר Geocoder.us uk_postcode: תוצאות מאתר NPEMap / FreeThe Postcode ca_postcode: תוצאות מאתר Geocoder.CA @@ -1288,17 +1288,17 @@ he: בשרת %{server_url} אל %{new_address}. click_the_link: אם באמת עשית את זה, נא ללחוץ על הקישור להלן כדי לאשר את השינוי. lost_password: - subject: '[אופן סטריט מאפ OpenStreetMap] בקשת איפוס ססמה' + subject: '[אופן סטריט מאפ OpenStreetMap] בקשת איפוס סיסמה' lost_password_plain: greeting: שלום, - hopefully_you: מישהו (אולי את או אתה) ביקש שהססמה המשויכת לחשבון המזוהה עם כתובת - הדוא"ל הזאת באתר openstreetmap.org. - click_the_link: אם אכן עשית את זה, יש ללחוץ על הקישור להלן כדי לאפס את הססמה. + hopefully_you: מישהו (אולי את או אתה) ביקש שהסיסמה המשויכת לחשבון המזוהה עם + כתובת הדוא"ל הזאת באתר openstreetmap.org. + click_the_link: אם אכן עשית זאת, יש ללחוץ על הקישור להלן כדי לאפס את הסיסמה. lost_password_html: greeting: שלום, - hopefully_you: מישהו (בתקווה מדובר בך) ביקש כי הססמה לחשבון המזוהה עם כתובת + hopefully_you: מישהו (בתקווה שמדובר בך) ביקש כי הסיסמה לחשבון המזוהה עם כתובת הדוא״ל הזאת באתר openstreetmap.org תאופס. - click_the_link: אם באמת ביקשת את זה, נא ללחוץ על הקישור להלן כדי לאפס את הססמה. + click_the_link: אם באמת ביקשת את זה, נא ללחוץ על הקישור להלן כדי לאפס את הסיסמה. note_comment_notification: anonymous: משתמש אלמוני greeting: שלום, @@ -1398,6 +1398,7 @@ he: date: תאריך reply_button: להשיב unread_button: לסימון כהודעה שלא נקראה + delete_button: מחיקה back: חזרה to: אל wrong_user: נכנסת בשם „%{user}”, אבל ההודעה שביקשת לקרוא לא נשלחה לאותו המשתמש. @@ -1547,8 +1548,8 @@ he: זמן) create: upload_trace: העלאת מסלול GPS - trace_uploaded: קובץ ה־GPX שלך הועלה ומחכה להכנסה אל מסד הנתונים. זה בדרך יקרה - בתוך חצי שעה ויישלח לך מכתב עם השלמת הפעולה. + trace_uploaded: קובץ ה־GPX שלך הועלה ומחכה להכנסה אל מסד הנתונים. זה בדרך כלל + יקרה בתוך חצי שעה ויישלח לך מכתב עם השלמת הפעולה. edit: title: עריכת מסלול %{name} heading: עריכת המסלול %{name} @@ -1752,13 +1753,13 @@ he: title: כניסה heading: כניסה email or username: 'כתובת דואר אלקטרוני או שם משתמש:' - password: 'ססמה:' + password: 'סיסמה:' openid: '%{logo} OpenID:' remember: לזכור אותי - lost password link: איבדת את הססמה שלך? + lost password link: איבדת את הסיסמה שלך? login_button: כניסה register now: להירשם עכשיו - with username: 'כבר יש לך חשבון OpenStreetMap? נא להיכנס עם שם משתמש וססמה:' + with username: 'כבר יש לך חשבון OpenStreetMap? נא להיכנס עם שם משתמש וסיסמה:' with external: 'לחלופין, השתמשו בצד שלישי כדי להיכנס:' new to osm: הגעת עכשיו ב־OpenStreetMap? to make changes: כדי לשנות את נתוני OpenStreetMap, צריך שיהיה לך חשבון. @@ -1804,22 +1805,22 @@ he: heading: יציאה מ־OpenStreetMap logout_button: יציאה lost_password: - title: הססמה הלכה לאיבוד - heading: שכחת ססמה? + title: הסיסמה הלכה לאיבוד + heading: שכחת סיסמה? email address: 'כתובת דוא״ל:' - new password button: נא לשלוח לי ססמה חדשה + new password button: נא לשלוח לי סיסמה חדשה help_text: נא להזין את כתובת הדוא״ל שהשתמשת בה כדי להירשם. אנו נשלח אליה קישור - שאפשר להשתמש בו כדי לאפס את ססמתך. + שאפשר להשתמש בו כדי לאפס את סיסמתך. notice email on way: אנו מצטערים לשמוע שאיבדת אותה :-( אבל נשלח לדואר האלקטרוני שלך מכתב שבאמצעותו אפשר לאפס אותה. notice email cannot find: סליחה, הכתובת הזאת לא נמצאה. reset_password: - title: איפוס ססמה + title: איפוס סיסמה heading: איפוס הססמה עבור %{user} - password: 'ססמה:' - confirm password: 'אימות הססמה:' + password: 'סיסמה:' + confirm password: 'אימות הסיסמה:' reset: איפוס הססמה - flash changed: ססמתך שונתה. + flash changed: סיסמתך שונתה. flash token bad: לא מצאנו את האסימון ההוא, אולי בדיקת הכתובת תעזור? new: title: הרשמה @@ -1836,18 +1837,17 @@ he: התרומה. email address: 'כתובת דוא״ל:' confirm email address: 'אימות כתובת דוא״ל:' - not displayed publicly: הכתובת שלף לא מוצגת בפומבי, ר׳ את מידיניות - פרטיות למידע נוסף - display name: 'שם התצוגה:' - display name description: שם המשתמש שלך, שמוצג בפומבי. אפשר לשנות את זה בהעפות + not displayed publicly: הכתובת שלך לא מוצגת בפומבי, למידע נוסף ראה מדיניות פרטיות + display name: 'שם להצגה:' + display name description: שם המשתמש שלך, שמוצג בפומבי. אפשר לשנות את זה בהעדפות שלך. external auth: 'אימות עם צד שלישי:' - password: 'ססמה:' - confirm password: 'אימות ססמה:' + password: 'סיסמה:' + confirm password: 'אימות סיסמה:' use external auth: 'לחלופין, השתמשו בצד שלישי כדי להיכנס:' - auth no password: עם אימות צד שלישי אין צורך בססמה, אבל כלים נוספים או שרת יכולים - להזדקק לכזה. + auth no password: עם אימות צד שלישי אין צורך בסיסמה, אבל כלים נוספים או שרת + יכולים להזדקק לכזה. continue: הרשמה terms accepted: תודה על קבלת תנאי התרומה החדשים! terms declined: אנחנו מצטערים שהחלטת לא לקבל את תנאי התרומה החדשים. למידע נוסף @@ -1970,7 +1970,7 @@ he: לערוך נתוני מפה. (הסבר למה זה ככה).
    • כתובת הדוא"ל שלך לא תיחשף כתוצאה מזה שתהיה משתמש ציבורי.
    • לא ניתן להפוך את הפעולה הזאת וכל המשתמשים החדשים יהיו מעתה - ציבוריים לפי בררת המחדל.
    + ציבוריים לפי ברירת המחדל.
  • contributor terms: heading: 'תנאי תרומה:' agreed: הסכמת לתנאי התרומה החדשים. @@ -2082,7 +2082,7 @@ he: heading: המזהה שלך עדיין אינו משויך לחשבון לחשבון OpenStreetMap. option_1: אם התחלת רק עכשיו עם OpenStreetMap, נא ליצור חשבון חדש באמצעות הטופס להלן. - option_2: אם כבר יש לך חשבון, אפשר להיכנס לחשבון שלך באמצעות שם המשתמש והססמה + option_2: אם כבר יש לך חשבון, אפשר להיכנס לחשבון שלך באמצעות שם המשתמש והסיסמה שלך ואז לשייך את החשבון שלך למזהה מהגדרות המשתמש שלך. user_role: filter: @@ -2318,6 +2318,7 @@ he: ascend: מעלה engines: graphhopper_bicycle: באופניים (GraphHopper) + graphhopper_car: במכונית (GraphHopper) graphhopper_foot: ברגל (GraphHopper) mapquest_bicycle: באופניים (MapQuest) mapquest_car: במכונית (MapQuest) diff --git a/config/locales/hr.yml b/config/locales/hr.yml index 2864ba2f0..636a7cad2 100644 --- a/config/locales/hr.yml +++ b/config/locales/hr.yml @@ -1,6 +1,7 @@ # Messages for Croatian (hrvatski) # Exported from translatewiki.net # Export driver: phpyaml +# Author: Bugoslav # Author: Ex13 # Author: Janjko # Author: Macofe @@ -387,7 +388,6 @@ hr: search: title: latlon: Rezultati iz Internal - us_postcode: Rezultati iz Geocoder.us uk_postcode: Rezultati iz NPEMap / FreeThe Postcode ca_postcode: Rezultati iz Geocoder.CA @@ -573,7 +573,9 @@ hr: steps: Stepenice street_lamp: Ulična rasvjeta tertiary: Lokalna cesta + tertiary_link: Lokalna cesta track: Makadam + traffic_signals: Semafori trail: Staza trunk: Cesta rezervirana za motorna vozila trunk_link: Cesta rezrevirana za mot. voz. - prilazna cesta @@ -588,20 +590,25 @@ hr: bunker: Bunker castle: Dvorac church: Crkva + city_gate: Gradska vrata citywalls: Gradske zidine fort: Tvrđava house: Kuća icon: Ikona manor: Zamak - memorial: Spomen dom + memorial: Spomenik mine: Rudnik monument: Spomenik + roman_road: Rimska cesta ruins: RuÅ¡evine + stone: Kamen tomb: Grob tower: Toranj wayside_cross: KrajputaÅ¡ wayside_shrine: Usputno svetiÅ¡te wreck: Olupina + junction: + "yes": Križanje landuse: allotments: Vrtovi basin: Bazen @@ -633,8 +640,11 @@ hr: vineyard: Vinograd leisure: beach_resort: Plaža + club: Klub common: Općinsko zemljiÅ¡te + dog_park: Park za pse fishing: Ribičko područje + fitness_centre: Fitness centar garden: Vrt golf_course: Golf igraliÅ¡te ice_rink: KlizaliÅ¡te @@ -652,9 +662,17 @@ hr: swimming_pool: Bazen track: Staza za trčanje water_park: Vodeni park + man_made: + lighthouse: Svjetionik + pipeline: Cjevovod + tower: Toranj + works: Tvornica + "yes": Ljudska građevina military: barracks: Barake bunker: Bunker + mountain_pass: + "yes": Planinski prijevoj natural: bay: Zaljev beach: Plaža @@ -680,6 +698,8 @@ hr: reef: Greben ridge: Greben rock: Stijena + saddle: Sedlo + sand: Pijesak scree: Å ljunak scrub: GuÅ¡tara spring: Izvor @@ -693,6 +713,7 @@ hr: wood: Å uma office: accountant: Računovođa + administrative: Administracija architect: Arhitekt company: Tvrtka employment_agency: Agencija za zapoÅ¡ljavanje @@ -722,6 +743,7 @@ hr: town: grad unincorporated_area: Slobodna zemlja village: Selo + "yes": Mjesto railway: abandoned: NapuÅ¡tena pruga construction: Pruga u izgradnji @@ -733,12 +755,15 @@ hr: junction: Željeznički čvor level_crossing: Pružni prijelaz light_rail: Laka željeznica + miniature: Maketa željeznice monorail: Jednotračna pruga narrow_gauge: Uskotračna pruga platform: Željeznička platforma preserved: Sačuvana pruga + proposed: Predložena trasa željeznice spur: Pruga station: Željeznički kolodvor + stop: Željezničko stajaliÅ¡te subway: Podzemna željeznica subway_entrance: Podzemna - ulaz switch: Skretnica @@ -746,12 +771,14 @@ hr: tram_stop: Tramvajska stanica shop: alcohol: Trgovina pićem + antiques: Antikviteti art: Atelje bakery: Pekara beauty: Parfumerija beverages: Trgovina pićem bicycle: Trgovina biciklima books: Knjižara + boutique: Butik butcher: Mesnica car: Autokuća car_parts: Autodijelovi @@ -765,6 +792,7 @@ hr: convenience: Minimarket copyshop: Kopiraona cosmetics: Parfumerija + deli: Delikatesni dućan department_store: Robna kuća discount: Diskont doityourself: Uradi sam @@ -801,6 +829,7 @@ hr: organic: Trgovina zdrave hrane outdoor: Trgovina za slobodno vrijeme pet: Trgovina za kućne ljubimce + pharmacy: Ljekarna photo: Fotograf salon: Salon shoes: Trgovina obućom @@ -808,12 +837,15 @@ hr: sports: Trgovina sportskom opremom stationery: Papirnica supermarket: Supermarket + tailor: Krojač toys: Trgovina igračkama travel_agency: Putnička agencija video: Videoteka wine: Vinoteka + "yes": Prodavaonica tourism: alpine_hut: Alpska kuća + apartment: Apartmani artwork: Umjetničko djelo attraction: Atrakcija bed_and_breakfast: Noćenje i doručak @@ -821,6 +853,7 @@ hr: camp_site: Kamp caravan_site: Kamp-kućice (mjesto) chalet: Planinska kuća + gallery: Galerija guest_house: Apartman hostel: Hostel hotel: Hotel @@ -850,6 +883,14 @@ hr: wadi: Suho korito rijeke waterfall: Vodopad weir: Brana + "yes": Vodotok + admin_levels: + level2: Državna granica + level5: Granica regije + level6: Granica županije + level8: Granica grada + level9: Granica sela + level10: Granica predgrađa description: title: osm_nominatim: Lokacija sa OpenStreetMap @@ -1095,6 +1136,13 @@ hr: title: Dolazna poÅ¡ta my_inbox: Dolazna poÅ¡ta outbox: odlazna poÅ¡ta + messages: Imate %{new_messages} i %{old_messages} + new_messages: + one: '%{count} nova poruka' + other: '%{count} nove poruke' + old_messages: + one: '%{count} stara poruka' + other: '%{count} stare poruke' from: Od subject: Tema date: Datum @@ -1125,6 +1173,9 @@ hr: my_inbox: ' %{inbox_link}' inbox: dolazna poÅ¡ta outbox: odlazna poÅ¡ta + messages: + one: Imate %{count} poslanu poruku + other: Imate %{count} poslane poruke to: Za subject: Tema date: Datum @@ -1142,6 +1193,7 @@ hr: date: Datum reply_button: Odgovori unread_button: Označi kao nepročitano + delete_button: ObriÅ¡i back: Natrag to: Za wrong_user: 'Prijavljeni ste kao: `%{user}'', ali poruka za koju ste zamoljeni @@ -1182,6 +1234,7 @@ hr: SPREMI ako imate taj gumb.) potlatch2_unsaved_changes: Neke promjene nisu spremljene. (Da biste spremili u Potlatch 2, trebali bi kliknuti Spremi.) + id_not_configured: iD nije konfiguriran no_iframe_support: Tvoj preglednik ne podržava HTML iframes, koji su potrebni za ovu značajku. sidebar: @@ -1189,6 +1242,9 @@ hr: close: Zatvori search: search: Traži + get_directions_title: Nađi upute između dvije točke + from: Od + to: Do where_am_i: Gdje sam? where_am_i_title: OpiÅ¡i trenutnu lokaciju koristeći pretraživač submit_text: Idi @@ -1196,6 +1252,7 @@ hr: table: entry: motorway: Autocesta + main_road: Glavna cesta trunk: Brza cesta primary: Primarna cesta secondary: Sekundarna cesta @@ -1203,6 +1260,9 @@ hr: track: Neasfaltirani put bridleway: Staza za konje cycleway: Biciklistička staza + cycleway_national: Državna biciklistička staza + cycleway_regional: Regionalna biciklistička staza + cycleway_local: Lokalna biciklistička staza footway: PjeÅ¡ačka staza rail: Željeznica subway: Podzemna željeznica @@ -1255,6 +1315,9 @@ hr: private: Privatni pristup destination: Pristup odrediÅ¡tu construction: Ceste u izgradnji + bicycle_shop: Biciklistička prodavaonica + bicycle_parking: ParkiraliÅ¡te za bicikle + toilets: Zahodi richtext_area: edit: Uredi markdown_help: @@ -1477,6 +1540,35 @@ hr: Molimo vas da koristite link u e-poÅ¡ti potvrde da biste aktivirali svoj račun, ili zatražiti novu e-poÅ¡tu potvrde . auth failure: Žao mi je, ne mogu prijaviti s ovim detaljima. + openid_logo_alt: Prijavi se sa OpenID-om + auth_providers: + openid: + title: Prijavi se sa OpenID-om + alt: Prijavi se sa URL-om OpenID-a + google: + title: Prijavi se sa Google-om + alt: Prijavi se sa Google-ovim OpenID-om + facebook: + title: Prijavi se sa Facebook-om + alt: Prijavi se sa računom Facebook-a + windowslive: + title: Prijavi se sa Windows Live-om + alt: Prijavi se sa računom Windows Live-a + github: + title: Prijavi se sa Github-om + alt: Prijavi se sa računom Github-a + wikipedia: + title: Prijavi se preko Wikipedije + alt: Prijavi se s Wikipedijinim računom + yahoo: + title: Prijavi se sa Yahoo-om + alt: Prijavi se sa Yahoo-ovim OpenID-om + wordpress: + title: Prijavi se sa Wordpressom + alt: Prijavi se sa Wordpressovim OpenID-om + aol: + title: Prijavi se sa AOL-om + alt: Prijavi se sa AOL-ovim OpenID-om logout: title: Odjava heading: Odjava iz OpenStreetMap @@ -1506,17 +1598,27 @@ hr: contact_webmaster: Molim kontaktirajte webmastera da priredi za stvaranje korisničkog računa - pokuÅ¡ati ćemo se pozabaviti s ovime u najkraćem vremenu. + about: + header: Slobodna i može ju svatko uređivati + html: |- +

    Za razliku od drugih karata, OpenStreetMap su u potpunosti napravili ljudi kao vi, + i slobodno ju svatko može popraviti, osvježiti, skinuti i koristiti.

    +

    Prijavite se i krenite uređivati. Poslat ćemo vam e-mail kako bi potvrdili vaš račun.

    license_agreement: Kada potvrdiÅ¡ svoj račun trebati ćeÅ¡ pristati na uvjete pridonositelja. email address: 'Email:' confirm email address: 'Potvrdi e-mail:' - not displayed publicly: Nije javno prikazano (vidi privacy policy) + not displayed publicly: VaÅ¡a adresa nije javno prikazana, vidi naÅ¡a pravila o privatnosti) display name: 'Korisničko ime:' display name description: Javno prikazano korisničko ime. Možete ga promjeniti i kasnije u postavkama. + external auth: 'Prijavljivanje sa drugog servisa:' password: 'Lozinka:' confirm password: 'Potvrdi zaporku:' + use external auth: Alternativno, koristite drugi servis za prijavljivanje + auth no password: Sa prijavljivanjem sa drugog servisa ne trebate lozinku, ali + drugi alati ili serveri će možda trebati. continue: Otvori račun terms accepted: Hvala za prihvaćanje novih pridonositeljskih uvjeta! terms: @@ -1541,6 +1643,7 @@ hr: heading: Korisnik %{user} ne postoji body: Žao mi je, ne postoji korisnik s imenom %{user}. Molim provjerite ukucano ili je link na koji ste kliknuli neispravan. + deleted: obrisano view: my diary: Moj dnevnik new diary entry: novi unos u dnevnik @@ -1564,6 +1667,8 @@ hr: mapper since: 'Maper od:' ago: prije (%{time_in_words_ago}) ct status: 'Uvjeti doprinositelja:' + ct undecided: Neopredjeljen + ct declined: Odbio ct accepted: Prihvaćeno prije %{ago} latest edit: 'Najnovija izmjena %{ago}:' email address: 'Email adresa:' @@ -1602,6 +1707,7 @@ hr: unhide_user: Otkrij ovog korisnika delete_user: ObriÅ¡i ovog korisnika confirm: Potvrdi + friends_changesets: changesetovi prijatelja popup: your location: VaÅ¡a lokacija nearby mapper: Obližnji maper @@ -1935,6 +2041,30 @@ hr: comment_and_resolve: Komentiraj i razrijeÅ¡i comment: Komentiraj edit_help: Pomakni kartu i približi dio koji želiÅ¡ urediti, zatim klikni ovdje. + directions: + engines: + graphhopper_bicycle: Bicikl (GraphHopper) + graphhopper_car: Automobil (GraphHopper) + graphhopper_foot: PjeÅ¡ke (GraphHopper) + mapquest_bicycle: Bicikl (MapQuest) + mapquest_car: Automobil (MapQuest) + mapquest_foot: PjeÅ¡ke (MapQuest) + osrm_car: Automobil (OSRM) + mapzen_bicycle: Bicikl (Mapzen) + mapzen_car: Automobil (Mapzen) + mapzen_foot: PjeÅ¡ke (Mapzen) + descend: Silazno + directions: Upute + distance: Udaljenost + errors: + no_route: Nismo mogli naći put između ta dva mjesta. + no_place: Žao nam je - nismo mogli naći to mjesto. + instructions: + continue_without_exit: Nastavi na %{name} + slight_right_without_exit: Lagano desno na %{name} + offramp_right_without_exit: Siđi sa autoceste desno na %{name} + onramp_right_without_exit: Skreni desno na autocestu %{name} + endofroad_right_without_exit: Na kraju ceste skreni desno na %{name} redaction: edit: description: Opis diff --git a/config/locales/hsb.yml b/config/locales/hsb.yml index 4fd0ed828..756e2e76c 100644 --- a/config/locales/hsb.yml +++ b/config/locales/hsb.yml @@ -383,7 +383,6 @@ hsb: search: title: latlon: Wuslědki wot Internal - us_postcode: Wuslědki wot Geocoder.us uk_postcode: Wuslědki wot NPEMap / FreeThe Postcode ca_postcode: Wuslědki wot Geocoder.CA diff --git a/config/locales/hu.yml b/config/locales/hu.yml index df42831f7..fda5a8278 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -8,6 +8,7 @@ # Author: Csega # Author: Dani # Author: Dj +# Author: GBAB # Author: Glanthor Reviol # Author: Grin # Author: Kempelen @@ -397,7 +398,6 @@ hu: search: title: latlon: Eredmények az Internalról - us_postcode: Eredmények a Geocoder.us-ról uk_postcode: Eredmények a NPEMap / FreeThe Postcode-ról ca_postcode: Eredmények a Geocoder.CA-ről @@ -609,7 +609,7 @@ hu: manor: Majorság memorial: Emlékmű mine: Bánya - monument: Műemlék + monument: Monumentális, épületszerű emlékmű roman_road: Római út ruins: Rom stone: Kő @@ -962,8 +962,8 @@ hu: intro_text: Az OpenStreetMap egy világtérkép, amelyet hozzád hasonló emberek készítenek és szabad licenc alatt elérhető. intro_2_create_account: Felhasználói fiók létrehozása - partners_html: A szerver üzemeltetését támogatja az %{ucl}, %{ic} és %{bytemark}, - valamint további %{partners}. + partners_html: A szerver üzemeltetését az %{ucl}, a %{bytemark}, az %{ic} és további + %{partners} támogatják. partners_ucl: UCL partners_ic: Imperial College London partners_bytemark: Bytemark Hosting @@ -1037,9 +1037,7 @@ hu: more_title_html: Tudj meg többet! more_1_html: |- További információ adataink használatáról az OSMF Licenc lapon és a közösség Jogi - GYIK gyűjteményében. + href="http://osmfoundation.org/License">OSMF Licenc lapon. more_2_html: |- Habár az OpenStreetMap egy nyílt adatforrás, nem tudunk ingyenes térkép API elérést biztosítani a harmadik feleknek. @@ -1223,7 +1221,8 @@ hu: nap növekszik. Lelkes térképezők, GIS profik, az OSM szervereket üzemeltető technikusok, katasztrófa-sújtotta területeket térképező önkéntesek működnek közre a térkép szerkesztésében. Ha többet szeretnél megtudni a közösségről, - lásd a felhasználói naplókat, közösségi + lásd az OpenStreetMap Blogot, a + felhasználói naplókat, a közösségi blogokat, és az OSM Foundation weboldalát. open_data_title: Szabad adatok @@ -1415,6 +1414,7 @@ hu: date: Érkezett reply_button: Válasz unread_button: Jelölés olvasatlanként + delete_button: Törlés back: Vissza to: Ide wrong_user: „%{user}” néven jelentkeztél be, de a levelet, amit lekérdeztél @@ -1468,7 +1468,7 @@ hu: get_directions_title: Útirány keresése két pont között from: Innen to: Ide - where_am_i: Hol vagyok? + where_am_i: Hol található? where_am_i_title: A jelenlegi helyszín leírása a keresőmotor segítségével submit_text: Menj key: @@ -2372,6 +2372,7 @@ hu: ascend: Emelkedés engines: graphhopper_bicycle: Kerékpár (GraphHopper) + graphhopper_car: Autó (GraphHopper) graphhopper_foot: Gyalog (GraphHopper) mapquest_bicycle: Kerékpár (MapQuest) mapquest_car: Autó (MapQuest) @@ -2432,8 +2433,8 @@ hu: error: 'Hiba a %{server} szerverhez való kapcsolódáshoz: %{error}' timeout: Időtúllépés a %{server}szerverhez kapcsolódás során context: - directions_from: Útvonaltervezés innen - directions_to: Útvonaltervezés ide + directions_from: Navigáció innen + directions_to: Navigáció ide add_note: Jegyzet hozzáadása itt show_address: Cím megjelenítése query_features: Funkciók lekérdezése diff --git a/config/locales/ia.yml b/config/locales/ia.yml index 31f96a683..4f810c5d2 100644 --- a/config/locales/ia.yml +++ b/config/locales/ia.yml @@ -180,8 +180,8 @@ ia: way: via relation: relation start_rjs: - feature_warning: Le cargamento de %{num_features} elementos pote relentar o - congelar tu navigator. Es tu secur de voler visualisar iste datos? + feature_warning: Le cargamento de %{num_features} objectos pote relentar o congelar + tu navigator. Es tu secur de voler visualisar iste datos? load_data: Cargar datos loading: Cargamento... tag_details: @@ -214,8 +214,8 @@ ia: retro hidden_by: Celate per %{user} %{when} retro query: - title: Cercar objectos proxime - introduction: Clicca sur le carta pro cercar elementos a proximitate. + title: Cercar objectos + introduction: Clicca sur le carta pro cercar objectos a proximitate. nearby: Objectos proxime enclosing: Objectos inglobante changeset: @@ -385,7 +385,6 @@ ia: search: title: latlon: Resultatos interne - us_postcode: Resultatos de Geocoder.us uk_postcode: Resultatos de NPEMap / FreeThe Postcode ca_postcode: Resultatos de Geocoder.CA @@ -1096,11 +1095,11 @@ ia: Ecce un guida curte con le cosas le plus importante a saper. whats_on_the_map: title: Que es sur le carta? - on_html: OpenStreetMap es un loco pro cartographiar cosas real e actual; + on_html: OpenStreetMap es un loco pro cartographar cosas real e actual; illo include milliones de edificios, stratas e altere detalios sur locos. - Tu pote cartographiar qualcunque elemento del mundo real que te interessa. + Tu pote cartographar qualcunque cosa del mundo real que te interessa. off_html: Illo non include datos subjective como punctos de appreciation, - elementos historic o hypothetic. Le datos ab fontes sub copyright es equalmente + objectos historic o hypothetic. Le datos ab fontes sub copyright es equalmente excludite; non copia cosas ab cartas in linea o de papiro sin permission special! basic_terms: title: Vocabulario de base pro le cartographia @@ -1208,8 +1207,11 @@ ia: community_driven_title: Dirigite per le communitate community_driven_html: |- Le communitate de OpenStreetMap es diverse, passionate e cresce cata die. Nostre contributores include cartographos enthusiasta, professionales de GIS, ingenieros gerente le servitores de OSM, humanitarios cartographiante areas devastate per un disastro, e multe alteres. - Pro apprender plus sur le communitate, vide le diarios del usatores, le - blogs del communitate e le sito web del Fundation OSM. + Pro apprender plus sur le communitate, vide + le blog de OpenStreetMap, + le diarios del usatores, + le blogs del communitate + e le sito web del Fundation OSM. open_data_title: Datos aperte open_data_html: |- OpenStreetMap es constituite per datos aperte: tu es libere de usar lo pro qualcunque scopo a condition que tu da credito a OpenStreetMap e su contributores. Si tu altera o extende le datos in certe manieras, tu pote distribuer le resultato solmente sub le mesme licentia. Vide le pagina Copyright e @@ -1402,6 +1404,7 @@ ia: date: Data reply_button: Responder unread_button: Marcar como non legite + delete_button: Deler back: Retornar to: A wrong_user: Tu es authenticate como "%{user}", ma le message que tu vole leger @@ -2334,8 +2337,8 @@ ia: createnote_disabled_tooltip: Face zoom avante pro adder un nota al carta map_notes_zoom_in_tooltip: Face zoom avante pro vider le notas del carta map_data_zoom_in_tooltip: Face zoom avante pro vider le datos del carta - queryfeature_tooltip: Cercar objectos proxime - queryfeature_disabled_tooltip: Face zoom avante pro cercar objectos a proximitate + queryfeature_tooltip: Cercar objectos + queryfeature_disabled_tooltip: Face zoom avante pro cercar objectos changesets: show: comment: Commento @@ -2364,6 +2367,7 @@ ia: ascend: Ascender engines: graphhopper_bicycle: Bicycletta (GraphHopper) + graphhopper_car: Auto (GraphHopper) graphhopper_foot: Pedestre (GraphHopper) mapquest_bicycle: Bicycletta (MapQuest) mapquest_car: Auto (MapQuest) @@ -2419,7 +2423,7 @@ ia: node: Nodo way: Via relation: Relation - nothing_found: Nulle elemento trovate + nothing_found: Nulle objecto trovate error: 'Error al contactar %{server}: %{error}' timeout: Tempore limite excedite contactante %{server} context: @@ -2427,6 +2431,7 @@ ia: directions_to: Itinerario verso hic add_note: Adder un nota hic show_address: Monstrar adresse + query_features: Cercar objectos centre_map: Centrar le carta hic redaction: edit: diff --git a/config/locales/id.yml b/config/locales/id.yml index aa67456c3..915eeed68 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -3,6 +3,7 @@ # Export driver: phpyaml # Author: Arief # Author: Arifin.wijaya +# Author: Atriwidada # Author: C5st4wr6ch # Author: Dewisulistio # Author: Emirhartato @@ -16,6 +17,7 @@ # Author: JakArtisan # Author: Kenrick95 # Author: Macofe +# Author: Rachmat04 # Author: Relly Komaruzaman # Author: Rizkiahmadz # Author: Vasanthi @@ -403,7 +405,6 @@ id: search: title: latlon: Hasil dari Internal - us_postcode: Hasil dari Geocoder.us uk_postcode: Hasil dari NPEMap / FreeThe Postcode ca_postcode: Hasil dari Geocoder.CA @@ -970,7 +971,7 @@ id: intro_2_create_account: Buat Akun partners_html: Hosting didukung oleh %{ucl}, %{ic} dan %{bytemark} dan %{partners} lainnya. - partners_ucl: Pusat UCL VR + partners_ucl: UCL partners_ic: Imperial College London partners_bytemark: Hosting Bytemark partners_partners: mitra @@ -1045,10 +1046,10 @@ id: Baca lebih lanjut tentang pemakaian data kami, dan cara memberi kami kredit, di halaman lisensi OSMF dan Pertanyaan Legal yang sering diajukan (FAQ) komunitas. more_2_html: |- - Meskipun OpenStreetMap merupakan data yang terbuka, kami tidak dapat menyediakan API peta gratis bagi pengembang (developer) pihak ketiga. - Lihat Kebijakan Penggunaan API, - Kebijakan Penggunaan Tile - dan Kebijakan Penggunaan Nominatim. + Meskipun OpenStreetMap merupakan data yang terbuka, kami tidak dapat menyediakan API peta gratis bagi pihak ketiga. + Lihat Kebijakan Penggunaan API, + Kebijakan Penggunaan Tile + dan Kebijakan Penggunaan Nominatim. contributors_title_html: Kontributor kami contributors_intro_html: 'Kontributor kami terdiri dari ribuan orang. Kami juga memasukkan data dengan lisensi terbuka yang didapat dari badan-badan pemetaan @@ -1253,10 +1254,10 @@ id: partners_title: Rekan notifier: diary_comment_notification: - subject: '[OpenStreetMap] %{user} mengomentari entri catatan harian Anda' + subject: '[OpenStreetMap] %{user} mengomentari sebuah entri catatan harian' hi: Halo %{to_user}, header: '%{from_user} mengomentari entri terbaru dari catatan harian OpenStreetMap - Anda dengan subjek %{subject}:' + dengan subjek %{subject}:' footer: Anda juga dapat membaca komentar pada %{readurl} dan Anda juga dapat berkomentar pada %{commenturl} atau membalas pada %{replyurl} message_notification: @@ -1266,6 +1267,7 @@ id: footer_html: Anda juga dapat membaca pesan di %{readurl} dan membalasnya di %{replyurl} friend_notification: + hi: Halo %{to_user}, subject: '[OpenStreetMap] %{user} menambahkan Anda sebagai teman' had_added_you: '%{user} telah menambahkan Anda sebagai teman pada OpenStreetMap.' see_their_profile: Anda dapat melihat profilnya pada %{userurl}. @@ -1355,6 +1357,7 @@ id: yang Anda komentari. Catatan ini dekat %{place}.' details: Rincian lebih lanjut mengenai catatan dapat ditemukan di %{url}. changeset_comment_notification: + hi: Halo %{to_user}, greeting: Halo, commented: subject_own: '[OpenStreetMap] %{commenter} mengomentari salah satu perubahan @@ -1429,6 +1432,7 @@ id: date: Tanggal reply_button: Balas unread_button: Tandai belum dibaca + delete_button: Hapus back: Kembali to: Kepada wrong_user: Anda login sebagai '%{user}' tetapi pesan yang anda balas tidak @@ -1726,6 +1730,8 @@ id: invalid: Otorisasi token ini tidak berlaku. revoke: flash: Anda telah menolak token untuk %(application} + permissions: + missing: Anda tidak mengizinkan akses aplikasi ke fasilitas ini oauth_clients: new: title: Daftar aplikasi baru @@ -1830,6 +1836,9 @@ id: github: title: Masuk dengan GitHub. alt: Masuk dengan Akun GitHub. + wikipedia: + title: Masuk log dengan Wikipedia + alt: Masuk log dengan akun Wikipedia yahoo: title: Masuk log dengan Yahoo alt: Masuk log dengan Yahoo OpenID @@ -2243,6 +2252,7 @@ id: helper: time_future: Berakhir pada %{time}. until_login: Aktif sampai pengguna melakukan log in. + time_future_and_until_login: Berakhir dalam %{time} dan setelah pengguna masuk. time_past: Berakhir %{time} yang lalu. blocks_on: title: Diblokir pada %{name} @@ -2327,7 +2337,7 @@ id: key: title: Kunci Peta tooltip: Kunci Peta - tooltip_disabled: Kunci Peta tersedia hanya untuk lapisan standar + tooltip_disabled: Legenda tidak tersedia untuk lapisan ini map: zoom: in: Perbesar @@ -2344,6 +2354,7 @@ id: header: Layer Peta notes: Catatan Peta data: Data Peta + gps: Jejak GPS Umum overlays: Mengaktifkan overlay untuk penyelesaian masalah peta title: Lapisan copyright: © Kontributor OpenStreetMap @@ -2382,8 +2393,10 @@ id: edit_help: Memindahkan peta dan memperbesar lokasi yang ingin Anda sunting, kemudian klik di sini. directions: + ascend: Naik engines: graphhopper_bicycle: Sepeda (GraphHopper) + graphhopper_car: Mobil (GraphHopper) graphhopper_foot: Jalan Kaki (GraphHopper) mapquest_bicycle: Sepeda (MapQuest) mapquest_car: Mobil (MapQuest) @@ -2392,6 +2405,7 @@ id: mapzen_bicycle: Sepeda (Mapzen) mapzen_car: Mobil (Mapzen) mapzen_foot: Kaki (Mapzen) + descend: Turun directions: Petunjuk Arah distance: Jarak errors: @@ -2426,6 +2440,11 @@ id: against_oneway_without_exit: Lawan arah pada %{name} end_oneway_without_exit: Akhir dari satu arah pada %{name} roundabout_with_exit: Di bundaran keluar %{exit} menuju %{name} + turn_left_with_exit: Pada bundaran belok kiri ke %{name} + slight_left_with_exit: Pada bundaran belok kiri sedikit ke %{name} + turn_right_with_exit: Pada bundaran belok kanan ke %{name} + slight_right_with_exit: Pada bundaran belok kanan sedikit ke %{name} + continue_with_exit: Pada bundaran lurus saja ke %{name} unnamed: jalan tanpa nama courtesy: Petunjuk arah disediakan oleh %{link} time: Waktu tempuh @@ -2437,8 +2456,12 @@ id: error: 'Kelasahan menghubungi %{server}: %{error}' timeout: Waktu habis menghubungi %{server} context: + directions_from: Petunjuk arah dari sini + directions_to: Petunjuk arah ke sini add_note: Tambahkan sebuah catatan disini show_address: Tampilkan alamat + query_features: Fitur-fitur kueri + centre_map: Pusatkan peta di sini redaction: edit: description: Deskripsi diff --git a/config/locales/is.yml b/config/locales/is.yml index 1cae3f1e8..439093d6b 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -6,6 +6,7 @@ # Author: Snævar # Author: Sveinki # Author: Sveinn í Felli +# Author: Vignir # Author: Ævar Arnfjörð Bjarmason --- is: @@ -77,7 +78,7 @@ is: body: Texti recipient: Móttakandi user: - email: Tölvupóstfang + email: Netfang active: Virkur display_name: Sýnilegt nafn description: Lýsing @@ -166,7 +167,7 @@ is: node: hnútur way: leið relation: vensl - changeset: fannst ekki breytingasett + changeset: breytingasett note: minnispunktur timeout: sorry: Ekki var hægt að ná í gögn fyrir %{type} með kennitöluna %{id}, það tók @@ -178,6 +179,7 @@ is: changeset: breytingasettið note: minnispunktur redacted: + redaction: Endurskoðun %{id} type: node: hnút way: leið @@ -191,8 +193,8 @@ is: tag_details: tags: Merki wiki_link: - key: Wiki-síðan fyrir %{key} merkið - tag: Wiki-síðan fyrir %{key}=%{value} merkið + key: Wiki-síðan fyrir merkið %{key} + tag: Wiki-síðan fyrir merkið %{key}=%{value} wikidata_link: Atriðið %{page} á Wikidata wikipedia_link: „%{page}“ greinin á Wikipedia telephone_link: Hringja í %{phone_number} @@ -225,8 +227,8 @@ is: changeset: changeset_paging_nav: showing_page: Síða %{page} - next: Næsta » - previous: « Fyrra + next: Áfram » + previous: « Til baka changeset: anonymous: Nafnlaus no_edits: (engar breytingar) @@ -241,17 +243,17 @@ is: title: Breytingasett title_user: Breytingar eftir %{user} title_friend: Breytingar eftir vini þína - title_nearby: Breytingasett eftir nálæga notendur + title_nearby: Breytingar eftir nálæga notendur empty: Engin breytingasett fundust. load_more: Hlaða inn fleiri rss: - commented_at_html: Uppfært fyrir %{when} síðan - commented_at_by_html: Uppfært fyrir %{when} síðan af %{user} + commented_at_html: Uppfært fyrir %{when} + commented_at_by_html: Uppfært fyrir %{when} af %{user} full: Öll umræðan diary_entry: new: title: Ný bloggfærsla - publish_button: Gefa út + publish_button: Birta list: title: Blogg notenda title_friends: Blogg vina @@ -362,7 +364,6 @@ is: search: title: latlon: Niðurstöður frá Internal - us_postcode: Niðurstöður frá Geocoder.us uk_postcode: Niðurstöður frá NPEMap / FreeThe Postcode ca_postcode: Niðurstöður frá Geocoder.CA @@ -376,7 +377,7 @@ is: prefix_format: '%{name}:' prefix: aerialway: - cable_car: Kláflyfta + cable_car: Kláfur chair_lift: Stólalyfta drag_lift: Toglyfta gondola: Eggjalyfta @@ -386,7 +387,7 @@ is: gate: Hlið helipad: Þyrlupallur runway: Flugbraut - taxiway: Akstursbraut + taxiway: Akbraut flugvéla terminal: Flugstöð amenity: animal_shelter: Dýraheimili @@ -404,15 +405,15 @@ is: bureau_de_change: Gjaldeyrisskipti bus_station: Strætóstöð cafe: Kaffihús - car_rental: Bílaleigan - car_wash: Bílaþvottastöðin + car_rental: Bílaleiga + car_wash: Bílaþvottastöð casino: Spilavíti charging_station: Hleðslustöð childcare: Barnagæsla cinema: Kvikmyndahús clinic: Heilsugæsla clock: Klukka - college: Framhaldskóli + college: Framhaldsskóli community_centre: Samfélagsmiðstöð courthouse: Dómshús crematorium: Bálstofa @@ -603,7 +604,9 @@ is: club: Klúbbur common: Almenningur dog_park: Hundagarður + fishing: Fiskveiði fitness_centre: Líkamsræktarstöð + fitness_station: Líkamsræktarstöð garden: Garður golf_course: Golfvöllur horse_riding: Hestaferðir @@ -614,7 +617,9 @@ is: park: Almenningsgarður pitch: Íþróttavöllur playground: Leikvöllur + recreation_ground: Leikvöllur sauna: Gufubað + slipway: Slippur sports_centre: Íþróttamiðstöð stadium: Íþróttaleikvangur swimming_pool: Sundlaug @@ -872,8 +877,10 @@ is: edit_with: Breyta með %{editor} tag_line: Frjálsa wiki heimskortið intro_header: Velkomin í OpenStreetMap! + intro_text: OpenStreetMap er heimskort búið til af fólki eins og þér. Það er gefið + út með opnu hugbúnaðarleyfi og það kostar ekkert að nota það. intro_2_create_account: Búa til notandaaðgang - partners_ucl: UCL VR Centre + partners_ucl: UCL partners_ic: Imperial College London partners_bytemark: Bytemark Hosting partners_partners: samstarfsaðilar @@ -1102,6 +1109,7 @@ is: date: Dags reply_button: Svara unread_button: Merkja sem ólesin + delete_button: Eyða back: Til baka to: Til sent_message_summary: @@ -1148,7 +1156,7 @@ is: to: Til where_am_i: Hvar er ég? where_am_i_title: Notar leitarvélina til að lýsa núverandi staðsetningu á kortinu - submit_text: Fara + submit_text: Byrja key: table: entry: @@ -1688,6 +1696,7 @@ is: failed: Gat ekki bætt %{name} á vinalistann þinn. already_a_friend: '%{name} er þegar vinur þinn.' remove_friend: + heading: Hætta að vera vinur %{user}? button: fjarlægja úr vinahópi success: '%{name} er ekki lengur vinur þinn.' not_a_friend: '%{name} er ekki vinur þinn.' @@ -1829,6 +1838,7 @@ is: rss: title: Minnispunktar OpenStreetMap opened: nýr minnispunktur (nálægt %{place}) + commented: ný athugasemd (nálægt %{place}) closed: lokaður minnispunktur (nálægt %{place}) reopened: endurvirkjaður minnispunktur (nálægt %{place}) entry: @@ -1913,6 +1923,7 @@ is: directions: engines: graphhopper_bicycle: Reiðhjól (GraphHopper) + graphhopper_car: Bíll (GraphHopper) graphhopper_foot: Fótgangandi (GraphHopper) mapquest_bicycle: Reiðhjól (MapQuest) mapquest_car: Bíll (MapQuest) @@ -1927,9 +1938,19 @@ is: no_route: Gat ekki fundið leið á milli þessara tveggja staða. no_place: Því miður, gat ekki fundið þennan stað. instructions: - continue_without_exit: Halda áfram á %{name} + continue_without_exit: Haltu áfram á %{name} + endofroad_right_without_exit: Við enda vegarins skaltu beygja til hægri inn + á %{name} + turn_right_without_exit: Beygðu til hægri inn á %{name} + sharp_right_without_exit: Kröpp hægribeygja inn á %{name} + sharp_left_without_exit: Kröpp vinstribeygja inn á %{name} + endofroad_left_without_exit: Við enda vegarins skaltu beygja til vinstri inn + á %{name} follow_without_exit: Fylgja %{name} + start_without_exit: Byrjaðu við endann á %{name} + destination_without_exit: Farðu á leiðarenda unnamed: ónefnd gata + courtesy: Leiðarlýsing í boði %{link} time: Tími query: node: Hnútur @@ -1938,6 +1959,13 @@ is: nothing_found: Engar fitjur fundust error: 'Villa við að tengjast %{server}: %{error}' timeout: Rann út á tíma við að tengjast %{server} + context: + directions_from: Vegvísun héðan + directions_to: Vegvísun hingað + add_note: Bæta við minnispunkti hér + show_address: Sjá heimilisfang + query_features: Rannsaka fitjur + centre_map: Miðjusetja kort hér redaction: edit: description: Lýsing diff --git a/config/locales/it.yml b/config/locales/it.yml index 85d3eb40b..12ba09c64 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -224,10 +224,10 @@ it: load_data: Carica dati loading: Caricamento in corso... tag_details: - tags: Tag + tags: Etichette wiki_link: - key: La pagina wiki per la descrizione del tag %{key} - tag: La pagina wiki per la descrizione del tag %{key}=%{value} + key: La pagina wiki per la descrizione dell'etichetta %{key} + tag: La pagina wiki per la descrizione dell'etichetta %{key}=%{value} wikidata_link: L'elemento %{page} su Wikidata wikipedia_link: La voce di Wikipedia su %{page} telephone_link: Chiama %{phone_number} @@ -235,9 +235,9 @@ it: title: 'Nota: %{id}' new_note: Nuova nota description: Descrizione - open_title: 'Nota irrisolta: %{note_name}' + open_title: 'Nota irrisolta #%{note_name}' closed_title: 'Nota risolta #%{note_name}' - hidden_title: 'Note nascosta #%{note_name}' + hidden_title: 'Nota nascosta #%{note_name}' open_by: Creato da %{user} %{when} fa open_by_anonymous: Creato da anonimo %{when} fa commented_by: Commento da %{user} %{when} fa @@ -273,7 +273,7 @@ it: list: title: Gruppi di modifiche title_user: Gruppi di modifiche di %{user} - title_friend: Insieme di modifiche dei tuoi amici + title_friend: Gruppi di modifiche dei tuoi amici title_nearby: Gruppi di modifiche da parte di utenti nelle vicinanze empty: Nessun gruppo di modifiche trovato. empty_area: Nessun gruppo di modifiche in quest'area. @@ -421,7 +421,6 @@ it: search: title: latlon: Risultati da Internal - us_postcode: Risultati da Geocoder.us uk_postcode: Risultati da NPEMap / FreeThe Postcode ca_postcode: Risultati da Geocoder.CA @@ -986,7 +985,7 @@ it: intro_text: OpenStreetMap è una mappa del mondo, creata da persone come te e libera da utilizzare secondo una licenza aperta. intro_2_create_account: Crea un account utente - partners_html: L'hosting è supportato da %{ucl}, %{ic}, %{bytemark} e da altri + partners_html: L'hosting è supportato da %{ucl}, %{bytemark}, %{ic} e da altri %{partners}. partners_ucl: UCL partners_ic: Imperial College (Londra) @@ -1051,8 +1050,7 @@ it: more_title_html: Per saperne di più more_1_html: Per saperne di più su come utilizzare i nostri dati e come citarne correttamente la fonte, consulta la pagina sulla Licenza - OSMF e le Domande - legali frequenti della community. + OSMF. more_2_html: |- Anche se i dati OpenStreetMap sono aperti, non possiamo fornire accesso alle API della mappa gratuitamente per terze parti. Vedi la nostra Politica di utilizzo delle API, la @@ -1152,11 +1150,11 @@ it: rules: title: Regole! paragraph_1_html: "OpenStreetMap ha poche regole formali, ma ci aspettiamo che - tutti i partecipanti collaborino\ncon, e comunichino con la comunità. Se stai - considerando qualsiasi attività di editing manuale, sei pregato - di leggere e seguire le indicazioni \nLe - importazioni e \nki.openstreetmap.org/wiki/Automated_Edits_code_of_conduct\">Automatizzato - Modifiche." + tutti i partecipanti collaborino e comunichino con la comunità. Se stai considerando + qualsiasi altra attività oltre all'editing manuale, dovresti prima leggere + le linee guida sulle importazioni + e \nmodifiche + automatiche e seguire le loro indicazioni." questions: title: Domande? paragraph_1_html: |- @@ -1165,9 +1163,9 @@ it: start_mapping: Inizia a mappare add_a_note: title: Non hai tempo per editare? Aggiungi una nota! - paragraph_1_html: Se pensi che ci debba essere una piccola correzione, ma non - hai abbastanza tempo da registrarti e imparare a modificare, puoi aggiungere - semplicemente una nota. + paragraph_1_html: Se vuoi fare solo una piccola correzione, ma non hai abbastanza + tempo per registrarti e imparare come modificare, puoi semplicemente aggiungere + una nota. paragraph_2_html: |- Vai alla mappa e clicca sull'icona della nota: . Questo aggiungerà un marker alla mappa, che potrai muovere trascinandolo. Aggiungi il tuo messaggio, quindi fare clic su Salva e altri Mappers daranno un'occhiata. @@ -1245,9 +1243,10 @@ it: community_driven_html: La comunità di OpenStreetMap è diversa, appassionante, e cresce ogni giorno. I nostri contributori includono mapper entusiasti, professionisti GIS, ingegneri che gestiscono i server di OSM, mapping umanitario di aree soggette - a disastri e molto altro. Per ulteriori informazioni sulla comunità, consultare - i diari degli utenti, il blog - della comunità, e il sito OSM Foundation. + a disastri e molto altro. Per ulteriori informazioni sulla comunità, consulta + il blog OpenStreetMap, i diari + degli utenti, il blog della comunità, + e il sito OSM Foundation. open_data_title: Open Data open_data_html: 'OpenStreetMap è open data: sei libero di usarla per qualsiasi scopo a patto di attribuirla a OpenStreetMap e ai suoi contributori. Se alteri @@ -1444,6 +1443,7 @@ it: date: Data reply_button: Rispondi unread_button: Segna come non letto + delete_button: Cancella back: Indietro to: A wrong_user: Hai effettuato l'accesso come '%{user}', ma il messaggio che hai @@ -1497,7 +1497,7 @@ it: get_directions_title: Trova indicazioni tra due punti from: Da to: A - where_am_i: Dove sono? + where_am_i: Dove lo trovo? where_am_i_title: Descrivi la posizione attuale usando il motore di ricerca submit_text: Vai key: @@ -2358,7 +2358,7 @@ it: out: Zoom indietro locate: title: Mostra la mia posizione - popup: Ti trovi a {distanza} {unità} da questo punto + popup: Ti trovi a {distance} {unit} da questo punto base: standard: Standard cycle_map: Mappa ciclabile @@ -2411,6 +2411,7 @@ it: ascend: Salita engines: graphhopper_bicycle: Bicicletta (GraphHopper) + graphhopper_car: Auto (GraphHopper) graphhopper_foot: A piedi (GraphHopper) mapquest_bicycle: Bicicletta (MapQuest) mapquest_car: Auto (MapQuest) diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 6a3119eb3..52341707f 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -19,6 +19,7 @@ # Author: Nyampire # Author: OKANO Takayoshi # Author: Omotecho +# Author: Otokoume # Author: Ruila # Author: Rxy # Author: Schu @@ -394,7 +395,6 @@ ja: search: title: latlon: Internalからの結果 - us_postcode: Geocoder.usからの結果 uk_postcode: NPEMap / FreeThe Postcodeからの結果 ca_postcode: Geocoder.CAからの結果 osm_nominatim: OpenStreetMap @@ -959,7 +959,7 @@ ja: intro_header: OpenStreetMap へようこそ! intro_text: OpenStreetMap は、あなたのような人々が作成した世界地図であり、オープン ライセンスの下で自由に利用できます。 intro_2_create_account: 新しい利用者アカウントを作成 - partners_html: 'ホスティング支援者: %{ucl}、%{ic}、%{bytemark}、その他の%{partners}' + partners_html: 'ホスティング支援者: %{ucl}、%{bytemark}、%{ic}及びその他の%{partners}' partners_ucl: UCL partners_ic: インペリアル カレッジ ロンドン partners_bytemark: バイトマーク ホスティング @@ -1014,8 +1014,7 @@ ja: more_title_html: 詳細を見る more_1_html: |- データの利用やクレジット方法についての詳細はOpenStreetMapライセンスページならびにコミュニティの法に関するよくある質問をお読みください。 + href="http://osmfoundation.org/Licence">OSMF ライセンスページをお読みください。 more_2_html: OpenStreetMap はオープンデータですが、サードパーティーの開発者のための無料の地図 API は提供できません。API 利用規約、タイル利用規約ならびに利用者の日記、コミュニティのブログ、OSM財団のウェブサイトをご覧ください。 + href='https://blog.openstreetmap.org'>OpenStreetMap のブログ、利用者の日記、コミュニティのブログとOSM財団のウェブサイトをご覧ください。 open_data_title: オープン データ open_data_html: OpenStreetMapはオープンデータです。あなたはOpenStreetMapと協力者の著作権を表示すれば、いかなる目的でも無料で利用することができます。もし何らかの方法でデータを変更したり二次データを作成したりした場合も、同じライセンス条件下でのみ結果を配布できます。詳しくは、著作権とライセンスをご覧ください。 @@ -1297,6 +1296,7 @@ ja: date: 日付 reply_button: 返信 unread_button: 未読にする + delete_button: 削除 back: 戻る to: 宛先 wrong_user: あなたは「%{user}」としてログインしていますが、閲覧しようとしたメッセージは、この利用者が送信したものでも、この利用者宛てのものでもありません。メッセージを閲覧するには、正しいユーザーとしてログインしてください。 @@ -1339,7 +1339,7 @@ ja: get_directions_title: 2点を結ぶルートを検索 from: 出発点 to: 目的地 - where_am_i: いまどこ? + where_am_i: これはどこにありますか? where_am_i_title: 検索エンジンを使用して現在の場所を記述 submit_text: 検索 key: diff --git a/config/locales/ka.yml b/config/locales/ka.yml index 34ba51a6a..c9d5e07d5 100644 --- a/config/locales/ka.yml +++ b/config/locales/ka.yml @@ -289,7 +289,6 @@ ka: search: title: latlon: შიდა შედეგები - us_postcode: Geocoder.us–ის შედეგები uk_postcode: NPEMap / FreeThe Postcode–ის შედეგები ca_postcode: Geocoder.CA–ს შედეგები diff --git a/config/locales/kab.yml b/config/locales/kab.yml new file mode 100644 index 000000000..e7580d36f --- /dev/null +++ b/config/locales/kab.yml @@ -0,0 +1,1485 @@ +# Messages for Kabyle (Taqbaylit) +# Exported from translatewiki.net +# Export driver: phpyaml +# Author: Belkacem77 +# Author: Mastanabal +# Author: Mhenni +# Author: Sayem AtVkm +# Author: SlimaneAmiri +--- +kab: + time: + formats: + friendly: '%e %B %Y É£ef %H:%M' + activerecord: + models: + acl: Tabdart n usenqed n inekcam + changeset: Agraw n ibeddilen + changeset_tag: Imyerr n ugraw n ibeddilen + country: Tamurt + diary_comment: Awennit n uÉ£mis + diary_entry: Anekcam n uÉ£mis + friend: Amdakkel + language: Tutlayt + message: Izen + node: Tikerrist + node_tag: Imyerr n tkerrist + notifier: LÉ£u + old_node: Tikerrist taqburt + old_node_tag: Imyerr n tkerrist taqburt + old_relation: AssaÉ£ aqbur + old_relation_member: Amedraw n ussaÉ£ aqbur + old_relation_tag: Tikerrist n ussaÉ£ aqbur + old_way: Abrid aqbur + old_way_node: Tikerrist n ubrid aqbuṛ + old_way_tag: Imyerr n ubrid aqbuṛ + relation: AssaÉ£ + relation_member: Amedraw n ussaÉ£ + relation_tag: Tikerrist n ussaÉ£ + session: TiÉ£imit + trace: Adsil + tracepoint: Taneqqiḍt n udsil + tracetag: Imyerr n udsil + user: Aseqdac + user_preference: Ismenyifen n useqdac + user_token: Tiddest n useqdac + way: Abrid + way_node: Tikerrist n ubrid + way_tag: Imyerr n ubrid + attributes: + diary_comment: + body: Tafekka + diary_entry: + user: Aseqdac + title: Asentel + latitude: Tarrut + longitude: Tazegrart + language: Tutlayt + friend: + user: Aseqdac + friend: Amdakkel + trace: + user: Aseqdac + visible: Uman + name: Isem + size: TeÉ£zi + latitude: Tarrut + longitude: Tazegrart + public: Azayez + description: Aglam + message: + sender: Amazan + title: Asentel + body: Tafekka + recipient: AÉ£erwaḍ + user: + email: Imayl + active: Urmid + display_name: Mefffer isem + description: Aglam + languages: Tutlayin + pass_crypt: Awal uffir + editor: + default: Amezwer (tura %{name}) + potlatch: + name: Potlatch 1 + description: Potlatch 1 (amaẓrag ineṭḍen deg iminig) + id: + name: iD + description: iD (yeddan deg iminig) + potlatch2: + name: Potlatch 2 + description: Potlatch 2 (amaẓrag ineṭḍen deg iminig) + remote: + name: Amaẓrag azÉ£aray + description: Amaẓrag azÉ£aray (JOSM neÉ£ Merkaartor) + browse: + created: Yettwarna + closed: Yemdel + created_html: Yettwarna deg %{time} aya + closed_html: Yettwamdek deg %{time} aya + created_by_html: Yettwarna deg %{time} aya sÉ£ur + %{user} + deleted_by_html: Yettwarna deg %{time} aya sÉ£ur + %{user} + edited_by_html: Yettwabdel deg %{time} aya sÉ£uṛ + %{user} + closed_by_html: Yettwamdel deg %{time} aya sÉ£ur + %{user} + version: Lqem + in_changeset: Agraw n usnifel + anonymous: udrig + no_comment: (ulac awennit) + part_of: D ayla n + download_xml: Sider XML + view_history: Sken amazray + view_details: Wali talqayt + location: 'Adig:' + changeset: + title: 'Agraw n usnifel: %{id}' + belongs_to: Ameskar + node: Tikerras (%{count}) + node_paginated: Tikerras (%{x}-%{y} si %{count}) + way: Iberdan (%{count}) + way_paginated: Iberdan (%{x}-%{y} si %{count}) + relation: AssaÉ£en (%{count}) + relation_paginated: AssaÉ£en (%{x}-%{y} si %{count}) + comment: Iwenniten (%{count}) + hidden_commented_by: Awennit yeffren n %{user} %{when} + aya + commented_by: Awennit n %{user} %{when} aya + changesetxml: XML n ugraw n ibeddilen + osmchangexml: XML osmChange + feed: + title: Agraw n usnifel %{id} + title_comment: Agraw n ubeddel %{id} - %{comment} + join_discussion: Qqen akken ad tedduḍ ar usqerdec + discussion: Asqerdec + node: + title: 'Takerrist: %{name}' + history_title: 'Amazray n tkerrist: %{name}' + way: + title: 'Abrid: %{name}' + history_title: 'Amazray n ubrid: %{name}' + nodes: Tikerras + also_part_of: + one: Aḥric n ubrid %{related_ways} + other: Aḥric n iberdan %{related_ways} + relation: + title: 'AssaÉ£: %{name}' + history_title: 'Amazray n wassaÉ£: %{name}' + members: Imedrawen + relation_member: + entry_role: '%{type} %{name} s %{role}' + type: + node: Tikerrist + way: Abrid + relation: AssaÉ£ + containing_relation: + entry: AssaÉ£ %{relation_name} + entry_role: AssaÉ£ %{relation_name} (am %{relation_role}) + not_found: + sorry: 'Suref-aÉ£, %{type} #%{id} ulac-it.' + type: + node: tikerrist + way: abrid + relation: assaÉ£ + changeset: agraw n usnifel + note: tazmilt + timeout: + sorry: Suref-aÉ£, isefka n wanaw %{type} s usulay %{id} ttwin ddeqs n wakud akken + ad d-uÉ£alen. + type: + node: tikerrist + way: abrid + relation: assaÉ£ + changeset: agraw n usnifel + note: tazmilt + redacted: + redaction: Tuffra %{id} + message_html: Lqem %{version} n %{type} agi ur yezmir ara ad yettwasken acku + yeffer. wali %{redaction_link} i ugar n isallen. + type: + node: tikerrist + way: abrid + relation: assaÉ£ + start_rjs: + feature_warning: Asali n %{num_features} n tÉ£awsiwin yezmer ad yerr iminig-ik + ẓẓay neÉ£ ahat ad t-isewḥel. TebÉ£iḍ ad tsekneḍ isefka-agi? + load_data: Sali-d isefka + loading: Asali... + tag_details: + tags: Imyerren + wiki_link: + key: Aglam n imyerr %{key} É£ef uwiki + tag: Aglam n imyerr %{key}=%{value} É£ef uwiki + wikidata_link: Aferdis %{page} di Wikidata + wikipedia_link: Amagrad %{page}di Wikipedia + telephone_link: Siwel ar %{phone_number} + note: + title: 'Tazmilt: %{id}' + new_note: Tazmilt tamaynut + description: Aglam + open_title: 'Tazmilt ur yefrin ara #%{note_name}' + closed_title: 'Tazmilt ur yefrin ara #%{note_name}' + hidden_title: 'Tazmilt yeffren #%{note_name}' + open_by: Yerna-t %{user} %{when} aya + open_by_anonymous: Yernat useqdac udrig %{when} + aya + commented_by: Awennit sÉ£ur %{user} %{when} aya + commented_by_anonymous: Awennit n useqdac udrig %{when} + aya + closed_by: Yefra-t %{user} %{when} aya + closed_by_anonymous: YEfra-t useqdac udrig %{when} + aya + reopened_by: Irmed-it %{user} %{when} aya + reopened_by_anonymous: Irmed-it useqdac udrig %{when} + aya + hidden_by: Yeffer-it %{user} %{when} aya + query: + title: Tuttriwin É£ef tÉ£awsiwin + introduction: Sit É£ef tkarḍa allen ad tafeḍ tiÉ£awsiwin iqeṛben. + nearby: TiÉ£awsiqin iqeṛben + enclosing: TiÉ£awsiwin timagbarin + changeset: + changeset_paging_nav: + showing_page: Asebter %{page} + next: Ar zdat» + previous: « ar deffir + changeset: + anonymous: Udrig + no_edits: (ulac abeddel) + view_changeset_details: Sken talqayt n ugraw n usnifel + changesets: + id: Asulay + saved_at: Yettwasekles di + user: Aseqdac + comment: Awennit + area: Tamnaḍt + list: + title: Agraw n usnifel + title_user: Igrawen n usnifel sÉ£ur %{user} + title_friend: Igrawen n usnifel n imdukal-ik + title_nearby: Igrawen n usnifel n iseqdacen iqeṛben + empty: Ulac agraw n usnifel yettwafen. + empty_area: Ulac agraw n usnifel yettwafen di temnaḍt-agi. + empty_user: Ulac agraw n usnifel n useqdac-agi. + no_more: Ulac agraw-nniḍen n usnifel yettwafen. + no_more_area: Ulac agraw-nniḍen n usnifel yettwafen di temnaḍt-agi. + no_more_user: Ulac agraw-nniḍen n usnifel n useqdac-agi. + load_more: Sali ugar + timeout: + sorry: Suref-aÉ£, tabdart n igrawen n usnifel i d-sutreḍ tettwai ddeqs n wakud + akkena d d-ali. + rss: + title_all: Asqerdec deg ugraw n usnifel OpenStreetMap + title_particular: Asqerdec deg ugraw n usnifel OpenStreetMap uá¹­á¹­ %{changeset_id} + comment: Awennit amaynut deg ugraw n usnifel uá¹­á¹­ %{changeset_id} par %{author} + commented_at_html: Yettwalqem %{when} aya + commented_at_by_html: Yettwalqem %{when} aya sÉ£ur %{user} + full: Asqerdec ummid + diary_entry: + new: + title: Anekcam amaynut n uÉ£mis + publish_button: SuffeÉ£-d + list: + title: IÉ£misen n useqdac + title_friends: IÉ£misen n imdukal + title_nearby: IÉ£misen n iseqdacen iqeṛben + user_title: AÉ£mis n %{user} + in_language_title: Inekcam n uÉ£mis s %{language} + new: Anekcam amaynut n uÉ£mis + new_title: Aru anekcam amaynut deg uÉ£mis-ik n useqdac + no_entries: Ulac amagrad n uÉ£mis + recent_entries: Imagraden n melmi kan n uÉ£mis + older_entries: Inekcam iqbuṛen + newer_entries: Inekcam n melmi kan + edit: + title: Ẓreg anekcam n uÉ£mis + subject: 'Asentel:' + body: 'Tafekka:' + language: 'Tutlayt:' + location: 'Adig:' + latitude: 'Tarrut:' + longitude: 'Tazegrart:' + use_map_link: seqdec takarḍa + save_button: Sekles + marker_text: Adig n unekcam n uÉ£mis + view: + title: AÉ£mis n %{user} | %{title} + user_title: AÉ£mis n %{user} + leave_a_comment: Eǧǧ-d awennit + login_to_leave_a_comment: '%{login_link} akken ad teǧǧeḍ awennit' + login: Aseqdac + save_button: Sekles + no_such_entry: + title: Ulac ula d yiwen n unekcam n uÉ£mis yettwafen + heading: 'Ula d yiwen n unekcam s usulay: %{id}' + body: Suref-aÉ£, ulac ula d yiwen n unekcam deg uÉ£mis neÉ£ deg uwennit s usulay + %{id}. Senqed tira-ik neÉ£ aseÉ£wen fiÉ£ef i tsiteḍ ma d ameÉ£tu. + diary_entry: + posted_by: Yuzen-it-id %{link_user} af %{created} s %{language_link} + comment_link: Rnu awennit i unekcam-agi + reply_link: Err i unekcam-agi + comment_count: + zero: Ulac awennit + one: '%{count} n uwennit' + other: '%{count} n iwenniten' + edit_link: Ẓreg anekcam-agi + hide_link: Ffer anekcam-agi + confirm: Sentem + diary_comment: + comment_from: Awennit n %{link_user} di %{comment_created_at} + hide_link: Ffer awennit-agi + confirm: Sentem + location: + location: 'Adig:' + view: Sken + edit: Ẓreg + feed: + user: + title: Imagraden n uá¹£mis OpenStreetMap i %{user} + description: Imagraden ineggura n uÉ£mis OpenStreetMap sÉ£uṛ %{user} + language: + title: Imagraden n iÉ£misen OpenStreetMap s %{language_name} + description: Imagraden ineggura n iÉ£misen n iseqdacen OpenStreetMap s %{language_name} + all: + title: Imagraden n iÉ£misen OpenStreetMap + description: Imagraden inegguran n iÉ£misen n iseqdacen OpenStreetMap + comments: + has_commented_on: '%{display_name} yerna awennit ar inekcamen-agi n iÉ£misen' + post: Amagrad + when: Melmi + comment: Awennit + ago: '%{ago} aya' + newer_comments: Iwenniten ineggura + older_comments: Iwenniten iqbuṛen + export: + title: Sifeḍ + start: + area_to_export: Tamnaḍt n usifeḍ + manually_select: Fren s ufus tamnadt-nniḍen + format_to_export: Amasal n usifeḍ + osm_xml_data: Isefka XML OpenStreetMap + map_image: Tugna n tkarḍa (ad tesken akalku n tegnut) + embeddable_html: HTML yettwaslaÉ£en + licence: Turagt + export_details: Isefka n OpenStreetMap ffÉ£en-d ddaw n Turaft + Open Data Commons Open Database (ODbL). + too_large: + advice: 'Ma yella asifed ddaw-a yeÉ£li, seqdec ma ulac aÉ£ilif tiÉ£bula yettwabedren + ddaw-a:' + body: Tamnadt-agi hrawet aá¹­as akken ad tettwasifeḍ ar umasal OpenStreetMap + XML SenÉ£es ma ulac aÉ£ilif temÉ£er neÉ£ fren tamnaḍt meẓẓiyen, neÉ£ seqdec yiwen + seg iÉ£bula-agi i usider n isefka s uqettun. + planet: + title: Amtiweg OSM + description: Ad yenÉ£el si sya ar da lqem n taffa n isefka yemmden n OpenStreetMap + overpass: + title: API Overpass + description: Sider akatar-agi amagbar seg temrayt n taffa n isefka OpenStreetMap + geofabrik: + title: Isidar Geofabrik + description: Ad d-yessuffeÉ£ si sya ar da ileqman n imeẓawen, timura akked + timdinin yettwafernen + metro: + title: AsuffeÉ£ n umiá¹­ru + description: AsuffeÉ£ n temdinin tigejdanin n umadal akked lquṛub-nsent + other: + title: IÉ£bula-nniḍen + description: Ibula-nniḍen yettwabedren deug uwiki OpenStreetMap + options: IÉ£ewwaṛen + format: Amasal + scale: Sellum + max: afellay + image_size: TeÉ£zi n tugna + zoom: SemÉ£eṛ + add_marker: Rnu taṛekkizt É£ef tkarḍa + latitude: 'Tarrut:' + longitude: 'Tazegrart:' + output: TuffÉ£a + paste_html: Senteḍ tangalt HTML deg usmel Web + export_button: Sifeḍ + geocoder: + search: + title: + latlon: Igmaḍ igensanen + uk_postcode: Igmaḍ si NPEMap / FreeThe + Postcode + ca_postcode: Igmaḍ si Geocoder.CA + osm_nominatim: Igmaḍ si OpenStreetMap + Nominatim + geonames: Igmaḍ si GeoNames + osm_nominatim_reverse: Igmaḍ si OpenStreetMap + Nominatim + geonames_reverse: Igmaḍ si GeoNames + search_osm_nominatim: + prefix: + aerialway: + cable_car: Tilifirik + chair_lift: TilisÉ£imt + drag_lift: Tiliski + gondola: TilituzdiÉ£t + station: TaÉ£sert n tilituzdiÉ£t + aeroway: + aerodrome: Anafag + apron: Tamnaḍt n usseÉ£ser + gate: Tabburt + helipad: Anafag n ukuptir + runway: TafuÉ£alt + taxiway: Abrid n tkeṛṛust n unafag + terminal: Anemdu + amenity: + animal_shelter: Aglat n yiÉ£arsiwen + arts_centre: Almus aẓuṛan + atm: Asedgar awurman n yidrimen + bank: Tabanka + bar: Ttberna + bbq: Taseknaft + bench: AÉ£alad + bicycle_parking: AneÉ£sar n iviluten + bicycle_rental: Asekru n iviluten + biergarten: Ttberna di beṛṛa + boat_rental: Asekru n iÉ£erruba + brothel: Axxam n wuqqu + bureau_de_change: Tanarit n ubeddel n yidrimen + bus_station: TaÉ£sert n yisakacen + cafe: Lqehwa + car_rental: Kerru n tkerrust + car_sharing: Beá¹­á¹­u n tkeryas + car_wash: Tarda n tkeryas + casino: Akazinu + charging_station: taÉ£sert n uɛemmeṛ + childcare: Aqareɛ n warrac + cinema: Sinima + clinic: Taklinit + clock: Tamrilt + college: AÉ£erbaz + community_centre: Taxxamt tagtazalt + courthouse: AneÉ£ n teÉ£demt + crematorium: TanerÉ£ut + dentist: Amejjay n tuÉ£mas + doctors: Imejjayen + dormitory: Anaḍḍas + drinking_water: Aman n tissit + driving_school: AÉ£erbaz n uselmed n tenheṛt + embassy: Tamahelt + emergency_phone: TiliÉ£ri n utrab + fast_food: Učči arurad + ferry_terminal: Anemdu n ufirri + fire_hydrant: Amsexsay n tmes + fire_station: Taqcelt n isexsayen + food_court: Tamnaḍt n wučči + fountain: Tala + fuel: AserÉ£u + gambling: Uraren yidrimen + grave_yard: Tajebbant + gym: Fitness / tajimnastikt + health_centre: Almus n tdawsa + hospital: Sbiá¹­ar + hunting_stand: Tanefsart n uselfeÉ£ + ice_cream: Tamagrist + kindergarten: Tibḥirt n warrac + library: Tanedlist + market: Alzuz + marketplace: Ssuq + monastery: Amunastiṛ + motorcycle_parking: AneÉ£sar n imuá¹­uten + nightclub: Tazeqqa n yiḍ + nursery: Tanectalt + nursing_home: Axxam n tastaÉ£t s udawi + office: Tanarit + parking: AneÉ£sar + parking_entrance: Tabburt n uneÉ£sar + pharmacy: Tansafart + place_of_worship: Amḍiq n weɛbad + police: Tamsulta + post_box: Tanaka n tebṛatin + post_office: Tanarit n lpusá¹­a + preschool: AÉ£erbaz uzwir + prison: Lḥebs + pub: Ttberna + public_building: AzadaÉ£ azayez + reception_area: Tamnaḍt n usiweḍ + recycling: Point de wallus n usseqdec + restaurant: Asečču + retirement_home: Axxam n testaÉ£t + sauna: Sauna + school: AÉ£erbaz + shelter: Aglat + shop: Taḥanut + shower: Tasnuceft + social_centre: Almus amettan + social_club: Aqusis amettan + social_facility: Ameẓlu amettan + studio: Astudyu + swimming_pool: Tanerdabt + taxi: Aá¹­aksi + telephone: Tilifun azayez + theatre: Amezgun + toilets: Ibduzen + townhall: Asensu n temdint/taÉ£iwant + university: Tasdawit + vending_machine: Asedgar awurman + veterinary: Tafettakt tabiḍart + village_hall: Tazeqqa taÉ£iwant + waste_disposal: Affas n yiḍuman + youth_centre: Axxam n yilemẓiyen + boundary: + census: Talast taddadant + bridge: + swing: Tillegwit yeddawaren + viaduct: Tiqená¹­aṛt + "yes": Tiqená¹­ert + building: + "yes": Akerrus + craft: + carpenter: Amekras + electrician: Amesliktri + gardener: Abeḥḥar + painter: Abeyyaá¹­ + photographer: Asewlaf + plumber: Amsaldun + shoemaker: Axerraz + tailor: Axeggaḍ + "yes": Taḥanutt n Tinḍi + highway: + bridleway: AÉ£aras n yimnayen + footway: AÉ£aras n uḍar + path: AÉ£aras + pedestrian: AÉ£lad n uḍar + platform: TiÉ£erÉ£ert + primary: Abrid agejdan + primary_link: Abrid agejdan + raceway: Amnenniḍ + rest_area: Amḍiq n ustaεfu + road: Abrid + secondary: Abrid asnawan + secondary_link: Abrid asnawan + service: Abrid n umeẓlu + speed_camera: Aṛadaṛ n tazzla + steps: Sellum + street_lamp: Tasafut n ubrid + track: Abrid + "yes": Abrid + historic: + archaeological_site: Adig Asenzikan + battlefield: Amraḥ n Tamiwta + boundary_stone: Aẓru n talast + building: AzadaÉ£ amazray + castle: TiÉ£remt + church: Taglizt + city_gate: Tabburt n temdint + citywalls: IÉ£raben n temdint + house: Axxam + icon: Tignit + stone: Ablaḍ + landuse: + farm: Tibḥirt + farmland: Akal n tkerrazt + forest: Tiẓgi + leisure: + stadium: Annar + natural: + beach: Taftist + forest: Tiẓgi + hill: Awrir + island: Tigzirt + land: Akal + marsh: Alma + mud: Ixmiṛ + peak: Taqacuct + rock: Aẓru + sand: Ijdi + stone: Ablaḍ + tree: Aseklu + valley: Talat + water: Aman + wood: AmadeÉ£ + office: + accountant: Amessiḍan + administrative: Tadbelt + architect: Amasgad + company: Taṛmist + employment_agency: Tanegga n uxeddim + government: Tadbelt tazayezt + insurance: Tanegga n usenkid + lawyer: Abugaá¹­u + "yes": Tanarit + place: + allotments: Talmat n twacult + block: Iḥder + airport: Anafag + city: TiÉ£remt + country: Tamurt + county: Tamurt + farm: Tibḥirt + hamlet: Aḥriq + house: Axxam + houses: Ixxamen + island: Tigzirt + islet: Tigzirt meẓẓiyen + isolated_dwelling: Axxam awḥid + locality: Amḍiq + municipality: TaÉ£iwant + neighbourhood: Agmam + postcode: Tangalt n lpusá¹­a + region: Tamnaḍt + sea: Ilel + state: AÉ£ir + town: tiÉ£remt + village: Taddart + "yes": Amḍiq + shop: + bicycle: Taḥanutt n iviluten + books: Tahanutt n yidlisen + boutique: Tahanutt n umaynut + butcher: Agezzar + car: Tahanutt n tkeryas + car_parts: Ticeqqufin n ubeddel n tkeryas + "yes": Taḥanut + tourism: + hostel: Azebriz + hotel: Asensu + information: TalÉ£ut + museum: Asalay + tunnel: + "yes": Ifri + waterway: + river: Asif + stream: IÉ£zeṛ + wadi: Asif + waterfall: Acercuṛ n waman + weir: Uggug + "yes": Targa n waman + admin_levels: + level2: Talast n tmurt + level4: Talast n waÉ£irneÉ£ tawilayt + level5: Talast n temnaḍt + level6: Talast n waÉ£ir + level8: Talast n temdint + level9: Talast n taddart + level10: Talast n ugmama + description: + title: + osm_nominatim: Asideg si OpenStreetMap + Nominatim + geonames: Adig si GeoNames + types: + cities: Timdinin + towns: Tuddar + places: Idigen + results: + no_results: Ulac igmaḍ + more_results: Ugar n igmaḍ + layouts: + logo: + alt_text: Alugu n OpenStreetMap + home: Duu ar uxxam-ik + logout: FfeÉ£ + log_in: Qqen + log_in_tooltip: Qqen s umiḍan yellan + sign_up: Jerred + start_mapping: Bdu asgertel + sign_up_tooltip: Rnu amiḍan n teẓrigt + edit: Ẓreg + history: Amazray + export: Sifeḍ + data: Isefka + export_data: Sifeḍ isefka + gps_traces: Lǧerrat GPS + gps_traces_tooltip: Sefrek lǧerrat GPS + user_diaries: IÉ£misen n iseqdacen + user_diaries_tooltip: Sken iÉ£misen n iseqdacen + edit_with: Ẓreg s %{editor} + tag_line: Takarḍa n uwiki ilelli n umaḍal + intro_header: Aná¹£uf ar OpenStreetMap! + intro_text: OpenStreetMap d takarḍa n umadal, rnna-tt yemdanen am kečč d tilellit + i useqdec ddaw n turagt tilellit. + intro_2_create_account: Rnu amiḍan n useqdac + partners_html: TanezduÉ£t tmudd-itt %{ucl}, %{ic}, %{bytemark} d %{partners} nniḍen. + partners_ucl: UCL + partners_partners: imendiden + osm_offline: Taffa n isefka n OpenStreetMap ur teqqin ara yakan tura imi aseǧǧem + ilaqen yettwaselkam akken ad teddu akken iwata. + osm_read_only: Taffa n isefka n OpenStreetMap tella deg uskar n tÉ£uri kan akka + tura, imi aseǧǧem ilaqen yettwaselkam akken ad teddu akken iwata. + donate: Mudd afus i OpenStreetMap s %{link}i usali n uswir n warrum-is. + help: Tallelt + about: Ɣef + copyright: Izerfan n umeskar + community: Tamezdagnut + community_blogs: Iblugen n tmezdagnut + community_blogs_title: Iblugen n iɛeggalen n tmezdagnut OpenStreetMap + foundation: Tasbeddit + foundation_title: Tasbeddit OpenStreetMap + make_a_donation: + title: Mudd afus i OpenStreetMap s tewsa n yidirem + text: Mudd tawsa + learn_more: Issin ugar + more: Ugar + license_page: + foreign: + title: Ɣef tsuqilt-agi + english_link: Aneá¹£li s teglizit + native: + title: Ɣef usebter-agi + native_link: Tasuqilt s teqbaylit + mapping_link: Bdu attekki + legal_babble: + title_html: Izerfan n umeskar d turagt + intro_1_html: |- + OpenStreetMap d tagrumma n isefka yeldin, yellan ddaw n turagt Open Data Commons Open Database License (ODbL). + credit_title_html: Amek ara ternuḍ asmad i OpenStreetMap + attribution_example: + alt: AmedÉ£a É£ef wamek ara tettekkiḍ di OpenStreetMap s usebter web + title: Amedya n uttekki + more_title_html: Akken ad tafeḍ ugar n telÉ£ut + contributors_title_html: Iwiziwen-nneÉ£ + contributors_at_html: 'Utric : tegber isefka É£ef Tamdint + n Viyan (ddaw n turagt CC + BY), tamnaḍt + n Vorarlberg akked temnadt n Tyrol (ddaw n turagt CC + BY AT avec amendements).' + contributors_ca_html: 'Canada : yegber isefka n GeoBase®, + GeoGratis (© Agezdu n tiÉ£bula n ugama n Kanada), CanVec + (© Agezdu n tiqbula n ugama n Kanada) et StatCan (Agezdu n tirakalt, + Tidaddanin n Kanada).' + contributors_nl_html: 'Huland : yegber isefka © AND, 2007 (www.and.com).' + welcome_page: + title: Aná¹£uf! + whats_on_the_map: + title: Ayen yellan di tkarḍa + rules: + title: Ilugan! + questions: + title: Asteqsi? + paragraph_1_html: |- + OpenStreetMap tsumur ddeqs n tiÉ£bula ara t-issineḍ ad tesxedmeḍ deg usenfaṛ, akken ad testeqsiḍ neÉ£ ad t-muddeḍ tiririt, udiÉ£ ad tmeslayeḍ neÉ£ ad teÉ£reḍ tasemlit É£ef isental n tira n tkarḍiwin d iseqdacen nniḍen. + Wali afus dagi. + fixthemap: + how_to_help: + title: Amek ara d-muddeḍ afus + join_the_community: + title: Ddu ar tmezdagnut + other_concerns: + title: Uguren-nniḍen + help_page: + title: Awi tallelt + introduction: OpenStreetMap tsumur ddeqs n tiÉ£bula ara t-issineḍ ad tesxedmeḍ + deg usenfaṛ, akken ad testeqsiḍ neÉ£ ad t-muddeḍ tiririt, udiÉ£ ad tmeslayeḍ neÉ£ + ad teÉ£reḍ tasemlit É£ef isental n tira n tkarḍiwin d iseqdacen nniḍen. + welcome: + url: /welcome + title: AnÉ£uf ar OSM + description: Bdu s uminir-agi arurad yettmeslayen É£ef udasil n OpenStreetMap. + beginners_guide: + url: http://wiki.openstreetmap.org/wiki/Beginners%27_guide + title: Amnir n ulemad + description: Aminir i yinelmaden imaynuten i t-xeddem tmezdagnut. + help: + url: https://help.openstreetmap.org/ + title: help.openstreetmap.org + description: Steqsi neÉ£ nadi tiririyin deg usmel akked isteqsiyen n OSM. + mailing_lists: + title: Tabraá¹­á¹­ n tnezwit + forums: + title: Inmagaren + irc: + title: IRC + switch2osm: + title: switch2osm + wiki: + url: http://wiki.openstreetmap.org/ + title: wiki.openstreetmap.org + about_page: + next: Ar zdat + copyright_html: ©imttekkiyen
    n OpenStreetMap + open_data_title: Isefka ilelliyen + legal_title: Asaḍuf + partners_title: Imendiden + notifier: + diary_comment_notification: + subject: '[OpenStreetMap] %{user} yuzen-d awennit ar umagrad n uÉ£mis' + hi: Azzul %{to_user}, + header: '%{from_user} yuzen-ad awennit ar umagrad n uÉ£mis OpenStreetMap s usentel + %{subject} :' + message_notification: + hi: Azul %{to_user}, + header: '%{from_user} yuzen-ak-d izen si OpenStreetMap s usentel %{subject} :' + footer_html: Tzemreḍ daÉ£en ad teÉ£reḍ izen di %{readurl} sakin ad tizmireḍ ad + terreḍ i %{replyurl} + friend_notification: + hi: Azul %{to_user}, + subject: '[OpenStreetMap] %{user} yerna-k d amdakkel' + had_added_you: '%{user} yerna-k d amdakkel di OpenStreetMap.' + see_their_profile: 'Tzemred ad twaliḍ amaÉ£nu-is dagi : %{userurl}.' + befriend_them: 'Tzemred daÉ£ed ad tt-rnuḍ-t d amdakkel dagi : %{befriendurl}.' + gpx_notification: + greeting: Azul, + your_gpx_file: Ittemcabi ar ufayli-ik GPX + with_description: s uglam + and_the_tags: 'akked wawalen-agi n tsura:' + and_no_tags: s war awalen n tsura + failure: + subject: '[OpenStreetMap] Akter GPX ur yeddi ara' + failed_to_import: 'ur d-yettwakter ara. Hatta tuccḍa:' + more_info_1: Ugar n telÉ£ut É£ef tuccḍiwin n ukter GPX akked wamek ur ḍerrunt + ara + more_info_2: 'zemren ad ttwafen di:' + success: + subject: '[OpenStreetMap] Akter GPX yedda' + loaded_successfully: yuli-d akken iwata s %{trace_points} n %{possible_points} + n tneqqiḍin izemren ad ilint. + signup_confirm: + subject: '[OpenStreetMap] Aná¹£uf ar OpenStreetMap' + greeting: Azul din! + created: Yella win (nessaram d kečč) yernan amiḍan É£ef %{site_url}. + email_confirm: + subject: '[OpenStreetMap] Sentem tansa-ik imayl' + email_confirm_plain: + greeting: Azul, + email_confirm_html: + greeting: Azul, + lost_password: + subject: '[OpenStreetMap] Asuter n tulsa n uwennez n wawal uffir' + lost_password_plain: + greeting: Azul, + click_the_link: Ma d kečč, sit É£ef useÉ£wen akken ad talseḍ awennez n wawal uffir. + lost_password_html: + greeting: Azul, + note_comment_notification: + anonymous: Aseqdac udrig + greeting: Azul, + commented: + subject_own: '[OpenStreetMap] %{commenter} yerna awennit ar yiwet si tezmilin-ik' + subject_other: '[OpenStreetMap] %{commenter} yerna awennit ar yiwet n tezmilt + anida telliḍ' + your_note: '%{commenter} yerna awennit É£ef yiwet si tezmilin-ik n tkarḍa rrif + n %{place}.' + commented_note: '%{commenter} yerna awennit É£ef yiwet n tezmilt n tkarḍa anida + terniḍ awennit. Tazmilt teqṛeb ar %{place}.' + closed: + subject_own: '[OpenStreetMap] %{commenter} yefra yiwet si tezmilin-ik' + subject_other: '[OpenStreetMap] %{commenter} yefra yiwet n tezmilt anida telliḍ' + your_note: '%{commenter} yefra yiwet si tezmilin-ik n tkarḍa rrif n %{place}.' + commented_note: '%{commenter} yefra yiwet n tezmilt n tkarḍa anida terniḍ + awennit. Tazmilt teqṛeb ar %{place}.' + reopened: + subject_own: '[OpenStreetMap] %{commenter} yermed yiwet si tezmilin-ik' + subject_other: '[OpenStreetMap] %{commenter} yermed yiwet n tezmilt anida + telliḍ' + your_note: '%{commenter} yermed yiwet si tezmilin-ik n tkarḍa rrif n %{place}.' + commented_note: '%{commenter} yermed yiwet n tezmilt n tkarḍa anida terniḍ + awennit. Tazmilt teqṛeb ar %{place}.' + details: Ugar n telÉ£ut É£ef yezmilt ad tettwaf di %{url} + changeset_comment_notification: + hi: Azul %{to_user}, + greeting: Azul, + commented: + subject_own: '[OpenStreetMap] %{commenter} yerna awennit ar yiwet si tezmilin-ik + n tagrumma n usnifel' + subject_other: '[OpenStreetMap] %{commenter} yerna awennit ar yiwet n tagrumma + n usnifel anida telliḍ' + your_changeset: '%{commenter} yerna awennit É£ef yiet si tegrummiwin-ik n usenifel + yettwarnan di %{time}' + partial_changeset_with_comment: s uwennit '%{changeset_comment}' + partial_changeset_without_comment: S war awennit + message: + inbox: + title: Tanaka n urmas + my_inbox: Tanaka-iw n urmas + outbox: tanaka n tuzna + messages: Ɣur-k %{new_messages} akked %{old_messages} + from: Seg + subject: Asentel + date: Azemz + message_summary: + unread_button: Creḍ ur yettwaÉ£ra ara + read_button: Creḍ yettwaÉ£ra + reply_button: Err + delete_button: Kkes + new: + title: Azen izen + subject: Asentel + body: Tafekka + send_button: Azen + message_sent: Izen yettwazen + no_such_message: + title: Ulac izen + heading: Ulac izen + body: Suref-aÉ£, ulac izen s usulay-agi. + outbox: + title: Tanaka n tuzna + my_inbox: '%{inbox_link}-iw' + inbox: tanaka n urmas + outbox: tanaka n tuzna + to: I + subject: Asentel + date: Azemz + read: + title: Ɣeṛ izen + from: Seg + subject: Asentel + date: Azemz + reply_button: Err + unread_button: Creḍ yettwaÉ£ra + delete_button: Kkes + back: UÉ£al + to: I + sent_message_summary: + delete_button: Kkes + mark: + as_read: Izen yettwacred yettwaÉ£ra + as_unread: Izen yettwacred ur yettwaÉ£ra ara + delete: + deleted: Izen yettwakkes + site: + index: + permalink: AseÉ£wen yezgan + shortlink: AseÉ£wen awezlan + createnote: Rnu tazmilt + edit: + user_page_link: asebter n useqdac + sidebar: + search_results: Igmad n unadi + close: Mdel + search: + search: Nadi + get_directions: Awi iwellihen + from: Seg + to: I + where_am_i: Anida lliÉ£? + submit_text: Ddu + key: + table: + entry: + school: + - AÉ£erbaz + - Tasdawit + richtext_area: + edit: Ẓreg + markdown_help: + title_html: Yettwasleḍ s Markdown + headings: Izwal + heading: Azwel + subheading: Azwel asnawan + first: Aferids amezwaru + second: Aferdis wis sin + link: AseÉ£wen + text: Aḍris + image: Tugna + alt: Aḍris-nniḍen + url: Tansa URL + trace: + edit: + title: Ẓreg lǧeṛṛa %{name} + filename: 'Isem n ufaylu:' + download: sider + uploaded_at: 'Yuli:' + points: 'Tineqqiḍin:' + map: takarḍa + edit: ẓreg + owner: 'Bab:' + description: 'Aglam:' + tags: 'Ticraḍ:' + trace_form: + description: 'Aglam:' + tags: 'Ticraḍ:' + upload_button: Sali + help: Tallelt + trace_header: + upload_trace: Azen lǧerra + see_all_traces: Wali akk lǧerrat + see_your_traces: Wali lǧerrat-ik + trace_optionals: + tags: Ticraḍ + view: + pending: YETTRAǦU + filename: 'Isem n ufaylu :' + download: sider + uploaded: 'Yuli:' + points: 'Tineqqiḍin:' + map: takarḍa + edit: ẓreg + owner: 'Bab:' + description: 'Aglam:' + tags: 'Ticraḍ:' + none: Ulac + edit_track: Ẓreg lǧerra-agi + delete_track: Kkes lǧerra-agi + trace_not_found: Ulac lǧeṛṛa! + trace_paging_nav: + showing_page: Asebter %{page} + newer: LÉ£errat timaynutin + trace: + pending: YETTRAǦU + count_points: '%{count} n tneqqiḍin' + ago: '%{time_in_words_ago} aya' + more: ugar + trace_details: Sken talqayt n lǧerra + view_map: Sken takarḍa + edit: ẓreg + edit_map: Ẓreg takarḍa + public: AZAYEZ + private: USLIG + by: sÉ£uṛ + in: di + map: takarḍa + list: + public_traces: Lǧerrat GPS tizuyaz + your_traces: Lǧerrat-ik GPS + public_traces_from: Lǧerrat tizuyaz tizuyza n %{user} + description: Snirem lǧ€rrat GPS tineggura i yilin + tagged_with: yettwaṛekkez s %{tags} + empty_html: Ulac acu yella dagi. Sali lǧeṛṛa tamaynut + neÉ£ issin ugar É£ef lǧerra GPR, Wali asebter + awiki. + delete: + scheduled_for_deletion: TafuÉ£alt yettwaheggan i tukksa + make_public: + made_public: Lǧerra GPS yuÉ£alen d tazayezt + offline_warning: + message: Anagraw n tuzna n ifuyla GPX ulac-it tura + offline: + heading: Asekles GPX n war tuqqna + message: Anagraw n usekles d tuzna n ifuyla GPX ulac-it tura. + georss: + title: Lǧerrat GPS n OpenStreetMap + description: + description_with_count: + one: Afaylu GPX s %{count} n tneqqiḍt n %{user} + other: Afaylu GPX s %{count} n tneqqiḍin n %{user} + description_without_count: Afaylu GPX n %{user} + application: + require_cookies: + cookies_needed: Yettban d akken inagan n tuqqna nsan É£ef iminig-ik. Rmed-iten + send ad tkemmleḍ. + setup_user_auth: + blocked_zero_hour: Ɣur-k izen utrib É£ef usmel Web OpenStreetMap. Yessef ad t-É£reḍ-t + send ad tizmireḍ ad teskelseḍ asnifel-ik. + blocked: Anekcum-ik API yewḥel. Qqen ar ugrudem Web i ugar n isallen. + oauth: + oauthorize: + title: Sireg anekcum ar umiḍan-ik + allow_to: 'Sireg asnas amsaÉ£ i:' + allow_read_prefs: É£eṛ ismenyifen-ik n useqdac. + allow_write_prefs: Ẓreg ismenyifen-ik n useqdac. + allow_write_diary: rnu inekcam deg uÉ£mis, iwenniten akked imdukkal. + allow_write_api: snifel takarḍa + allow_read_gpx: É£eṛ lǧerrat-ik GPS usligen. + allow_write_gpx: azen lǧerrat GPS + allow_write_notes: snifel tizmilin. + grant_access: Mudd tasiregt + oauthorize_success: + title: Asuter n tsiregt tettwaqbel + allowed: Yessefk ad tmuddeḍ tasiregt ar umiḍan-ik i usnas %{app_name}. + verification: Asenqed n tengalt d %{code}. + oauthorize_failure: + title: Asuter n tsiregt ur yeddi ara + denied: Tugwiḍ tasiregt n unekcu ar umiḍan-ik i usnas %{app_name}. + invalid: Ajiá¹­un n tsiregt mačči d ameÉ£tu. + revoke: + flash: Teḥwiḍ ajiá¹­un i %{application} + permissions: + missing: Ur teǧǧiḍ ara asnas akken ad yeqqen ar usebdded-agi + oauth_clients: + new: + title: Sekles asnas amaynut + submit: Sekles + edit: + title: Ẓreg asnas-ik + submit: Ẓreg + show: + title: Talqayt OAuth i %{app_name} + key: 'Tasarutt n useqdac:' + secret: 'Tabadnit n useqdac:' + url: 'Tansa n ujiá¹­un n tuttra:' + access_url: 'Tansa n ujiá¹­un n unelcum:' + authorize_url: 'Tansa URL n tsiregt:' + support_notice: Nsefrak izmulen HMAC-SHA1 (yelha) akked RSA-SHA1 + edit: Ẓreg talqayt + delete: Kkes amsaÉ£ + confirm: TebÉ£iḍ? + requests: 'Asuter n tsirag-agi i useqdac:' + allow_read_prefs: É£eṛ ismenyifen n useqdac. + allow_write_prefs: snifel ismenyifen n useqdac. + allow_write_diary: rnu inekcam deg uÉ£mis, iwenniten akked imdukkal. + allow_write_api: snifel takarḍa. + allow_read_gpx: É£eṛ lǧerrat GPS usligen. + allow_write_gpx: azen lǧerrat GPS. + allow_write_notes: snifel tizmilin. + index: + title: Talqayt-iw OAuth + my_tokens: Isnasen-iw yettwaskelsen + application: Isem n usnas + issued_at: YeffeÉ£-d di + revoke: Ḥwi! + my_apps: Isnasen-iw imsaÉ£en + register_new: Sekles asnas-il + form: + name: Isem + required: Ilaq + url: Tansa URL tagejdant n usnas + callback_url: Tansa URL n usmekti + support_url: Tansa URL n tallelt + allow_read_prefs: É£eṛ ismenyifen n useqdac. + allow_write_prefs: snifel ismenyifen n useqdac. + allow_write_api: snifel takarḍa + allow_read_gpx: É£eṛ lǧerrat GPS usligen. + allow_write_gpx: azen lǧerrat GPS. + allow_write_notes: snifel tizmilin. + user: + login: + title: Qqen + heading: Qqen + email or username: 'Tansa imayl neÉ£ isem n useqdac:' + password: 'Awal uffir:' + openid: '%{logo} OpenID:' + remember: Cfu fell-i + lost password link: Tweddreḍ awal-ik uffir? + login_button: Qqen + register now: Jerred tura + new to osm: D amaynut ar OpenStreetMap? + no account: Ur tesɛiḍ ara amiḍan? + openid_logo_alt: Qqen s OpenID + auth_providers: + openid: + title: Qqen s OpenID + alt: Qqen s tensa URL OpenID + google: + title: Qqen s Google + alt: Qqen s Google OpenID + facebook: + title: Qqen s Facebook + alt: Qqen s umidan Facebook + windowslive: + title: Qqen s Windows Live + alt: Qqen s umiḍan Windows Live + github: + title: Qqen s GitHub + alt: Qqen s umiḍan GitHub + wikipedia: + title: Qqen s Wikipedia + alt: qqes s umiḍan Wikipedia + yahoo: + title: Qqen s Yahoo + alt: Qqen s Yahoo OpenID + wordpress: + title: Qqen s Wordpress + alt: Qqen s OpenID + aol: + title: Qqen s AOL + alt: Qqen s AOL OpenID + logout: + title: TuffÉ£a + heading: TuffÉ£a si OpenStreetMap + logout_button: TuffÉ£a + lost_password: + title: Awal uffir iṛuḥ + heading: Tettuḍ awal uffir? + email address: 'Tansa imayl:' + new password button: Ales awennez n wawal uffir + reset_password: + title: Ales awennez n wawal uffir + heading: Ales awennez n wawal uffir i %{user} + password: 'Awal uffir:' + confirm password: Sentem awal uffir + reset: Ales awennez n wawal uffir + flash changed: Awal-ik uffir ibeddel. + flash token bad: Ajiá¹­un-agi ulac-it, ahat tuccḍa di tansa URL? + new: + title: Jerred + email address: 'Tansa imayl:' + confirm email address: 'Sentem tansa n e-mail:' + password: 'Awal uffir:' + confirm password: 'Sentem awal uffir:' + continue: Jerred + terms: + title: Tiwtilin n iwiziw + heading: Tiwtilin n iwiziw + consider_pd_why: d acu-t wa? + agree: QqebleÉ£ + decline: Agwi + legale_select: 'Tamurt n tnezduÉ£t:' + legale_names: + france: Fṛansa + italy: Ṭelyan + no_such_user: + title: Ulac aseqdac + deleted: yettwakkes + view: + my diary: AÉ£mis-iw + new diary entry: anekcam amaynut n uÉ£mis + my edits: Tiẓrigin-iw + my traces: Lǧerrat-iw + my notes: Tizmilin-iw + my messages: Iznan-iw + my profile: AmaÉ£nu-iw + my settings: IÉ£ewwaṛen-iw + my comments: Iwenniten-iw + oauth settings: iÉ£ewwaṛen oauth + blocks on me: Asewḥel i y-iɛnan + blocks by me: Asewḥel sÉ£ur-i + send message: Azen izen + diary: AÉ£mis + edits: Tiẓrigin + traces: Lǧeṛṛat + notes: Tizmilin n tkarḍa + remove as friend: Kkes seg imdukkal + add as friend: Rnu amdakkel + ago: (%{time_in_words_ago} aya) + ct status: 'Tiwtilin n iwiziw:' + ct declined: Yettwagi + ct accepted: Yettwaqbel %{ago} aya + latest edit: 'Asnifel aneggaru %{ago} :' + email address: 'Tansa imayl:' + created from: 'Yettwarna seg:' + status: 'Addad:' + spam score: 'Amatar n uspam:' + description: Aglam + user location: Adig n useqdac + settings_link_text: IÉ£ewwaṛen + your friends: Imdukkal-ik + km away: '%{count} km' + m away: yebɛed s %{count} m + nearby users: Iseqdacen-nniḍen iqeṛben + role: + administrator: Aseqdac-agi d anedbal + grant: + administrator: Mudd izerfan n unedbal + revoke: + administrator: Kkes izerfan n unedbal + block_history: Asewḥel urmid + moderator_history: Asewḥel yettunefken + comments: Iwenniten + create_block: Sewḥel aseqdac-agi + activate_user: Rmed aseqdac-agi + deactivate_user: Sens aseqdacèagi + confirm_user: Sentem aseqdac-agi + hide_user: Ffer aseqdac-agi + unhide_user: Sken aseqdac-agi + delete_user: Kkes aseqdac-agi + confirm: Sentem + friends_changesets: Igrawen n usnifel n yidukkal + friends_diaries: Inekcam n uÉ£mis n yimdukkal + nearby_changesets: Ihrawen n usnifel n iseqdacen iqeṛben + nearby_diaries: Inekcam n uÉ£mis n iseqdacen iqeṛben + popup: + your location: Adig-ik + friend: Amdakkel + account: + title: Ẓreg amiḍan + my settings: IÉ£ewwaṛen-iw + current email address: Tansa imayl n tura + new email address: Tansa imayl tamaynut + email never displayed publicly: (werǧin ad d-iban s wudem azayez) + openid: + link: http://wiki.openstreetmap.org/wiki/OpenID + link text: d acu-t wa? + public editing: + heading: Taẓrigt tazayezt + enabled link: http://wiki.openstreetmap.org/wiki/Anonymous_edits + enabled link text: d acu-t wa? + disabled link text: Acu zemreÉ£ ad beddleÉ£? + public editing note: + heading: Taẓrigt tazayezt + contributor terms: + heading: 'Tiwtilin n iwiziw:' + link text: what is this? + profile description: 'Aglam n umaÉ£nu:' + preferred languages: 'Tutlayin tebÉ£iḍ:' + preferred editor: 'Amaẓrag tebÉ£iḍ:' + image: 'Tugna:' + gravatar: + gravatar: Seqdec Gravatar + link text: d acu-t wa? + new image: Rbu tugna + delete image: Kkes tugna tamirant + replace image: Semselsi tugna tamirant + home location: 'Adig n uxxam:' + no home location: Ur tsekcemeḍ ara adig n uxxam-ik. + latitude: 'Tarrut:' + longitude: 'Tazegrart:' + update home location on click: Snifel adig n uxxam-ik ticki siteÉ£ É£ef tkarḍa? + save changes button: Sekles asnifel + make edits public button: Err akk tiẓrigin-iw s tizuyaz + return to profile: UÉ£al ar umaÉ£nu + flash update success: TalÉ£ut n useqdac tettwasnifel akken iwata + confirm: + heading: Senqed tansa-ik imayl! + introduction_1: Nuzen-ak-d imayl n usentem. + press confirm button: Senned É£ef tqeffalt Sentem ddaw-a akken ad tremdeḍ amiḍan-ik. + button: Sentem + success: Amiḍan yettwasentem, tanemmirt É£ef ujerred! + already active: Amiḍan-agi yettwasentem yakan. + unknown token: Tangalt n usentem tezri neÉ£ ulac-itt. + confirm_resend: + failure: Aseqdac %{name} ulac-it. + confirm_email: + heading: Sentem abeddel n tensa-ik imayl + button: Sentem + success: Sentem abeddel n tensa-ik imayl! + unknown_token: Tangalt n usentem tenfer neÉ£ ulac-itt. + set_home: + flash success: Adig n uxxam yettwasekles akken iwata + make_friend: + heading: Rnu %{user} d amdakkel? + button: Rnu d aseqdac + success: '%{name} d amdakkel-ik tura!' + already_a_friend: Telliḍ yakan d amdakul n %{name}. + remove_friend: + heading: Kkes %{user} seg yimdukkal? + button: Kkes seg imdukkal + success: '%{name} yettwakkes seg yimdukkal.' + not_a_friend: '%{name} ur yelli ara d amdakkel.' + filter: + not_an_administrator: Teriḍ ad tiliḍ d anedbal akken ad teggeḍ tigawt-agi. + list: + title: Iseqdacen + heading: Iseqdacen + showing: + other: Asebter %{page} (%{first_item}one= É£ef %{items}) + summary: '%{name} yettwarna si %{ip_address} di %{date}' + summary_no_ip: '%{name} yettwarna di %{date}' + confirm: Sentem iseqdacen yettwafernen + hide: Ffer iseqdacen yettwafernen + empty: Ulac aseqdac d-yefÉ£en deg unadi + suspended: + title: Amiḍan yettwaseḥbes + heading: Amiḍan yettwaseḥbes + auth_failure: + no_authorization_code: Ulac tangalt n wurag + auth_association: + option_1: Ma yella d amaynut i d-tusiḍ É£er OpenStreetMap, ttxil-ek(m) seÉ£new + amiḍan amaynut s tallalt n tferkit adda-ya. + user_role: + grant: + confirm: Sentem + revoke: + confirm: Sentem + user_block: + partial: + show: Sken + edit: Ẓreg + revoke: Ḥwi! + confirm: TebÉ£iḍ? + display_name: Aseqdac iweḥlen + creator_name: Amernay + reason: TaÉ£zint n usewḥel + status: Addad + revoker_name: Isewḥel-it + showing_page: Asebter %{page} + next: Ar zdat» + previous: « ar deffir + helper: + time_future: Ad ifak di %{time}. + until_login: D urmid arama yeqqen useqdac + time_past: Ifuk %{time} aya. + blocks_on: + title: Asewḥel n %{name} + empty: '%{name} ur yewḥil ara yakan.' + blocks_by: + title: Asewḥel sÉ£uṛ %{name} + heading: Tabdart n usewḥel sÉ£uṛ %{name} + empty: '%{name} ur isewḥel kra ar tura.' + show: + title: '%{block_on} isewḥel-it %{block_by}' + heading: '%{block_on} isewḥel-it %{block_by}' + time_future: Ad ifak di %{time} + time_past: Ifuk %{time} aya + created: Yettwarna + ago: '%{time} aya' + status: Addad + show: Sken + edit: Ẓreg + revoke: Ḥwi! + confirm: TebÉ£iḍ? + reason: 'TaÉ£zint n usewḥel:' + back: Sken akk isewḥal + needs_view: Aseqdac-agi yesra ad yeqqen send ad yettwakkes u sewḥel. + note: + description: + opened_at_html: Yattwarna %{when} aya + opened_at_by_html: Yettwarna %{when} aya sÉ£ur %{user} + commented_at_html: Yettwalqem %{when} aya + commented_at_by_html: Yettwalqem %{when} aya sÉ£ur %{user} + closed_at_html: Yefra %{when} aya + closed_at_by_html: Yefra %{when} aya sÉ£ur %{user} + reopened_at_html: Yettwarmed %{when} aya + reopened_at_by_html: Yettwarmed %{when} aya sÉ£ur %{user} + rss: + title: Tizmilin n OpenStreetMap + opened: tazmilt tamaynut (qrib ar %{place}) + commented: awennit amawut (qrib ar %{place}) + closed: tazmilt temdel (qrib ar %{place}) + reopened: tazmilt termed (qrib ar %{place}) + entry: + comment: Awennit + full: Tazmilt tummiḍt + mine: + heading: Tizmilin n %{user} + id: Asulay + creator: Amernay + description: Aglam + created_at: Yettwarna di + last_changed: Asnifel aneggaru + ago_html: '%{when} aya' + javascripts: + close: Mdel + share: + title: Bḍu + cancel: Sefsex + image: Tugna + link: AseÉ£wen neq HTML + long_link: AseÉ£wen + short_link: AseÉ£wen awezlan + geo_uri: URI arakal + embed: HTML + format: 'Amasal:' + scale: 'Sellum:' + download: Sider + short_url: URL awezlan + include_marker: Seddu anabraz + map: + locate: + title: Sken adig-iw + copyright: © Iwiziwen n OpenStreetMap + donate_link_text: + site: + edit_tooltip: Ẓreg takarḍa + createnote_tooltip: Rnu tazmilt ar tkarḍa + queryfeature_tooltip: isitar É£ef tmahilin + changesets: + show: + comment: Awennit + subscribe: Jerred + unsubscribe: FfeÉ£ seg ujerred + hide_comment: ffer + unhide_comment: sken + notes: + new: + add: Rnu tazmilt + show: + hide: Ffer + resolve: Fru + reactivate: Rmed + comment_and_resolve: Rnu awennit & Fru + comment: Awennit + directions: + engines: + graphhopper_car: S tkerrust(GraphHopper) + graphhopper_foot: Ɣef uḍaṛ (GraphHopper) + mapquest_bicycle: S uvilu(MapQuest) + mapquest_car: S tkerrust (MapQuest) + mapquest_foot: Ɣef uḍaṛ (MapQuest) + osrm_car: S tkeṛṛust (OSRM) + mapzen_bicycle: S uvilu (Mapzen) + mapzen_car: S tkeṛṛust (Mapzen) + mapzen_foot: Ɣef uḍaṛ (Mapzen) + instructions: + continue_without_exit: Kemmel É£ef %{name} + time: Akud + query: + node: Tikerrist + way: Abrid + relation: AssaÉ£ + nothing_found: Ulac taÉ£awsa yettwafen + error: 'Tuccḍa deg unermes n %{server} : %{error}' + timeout: Tanzagt tezri deg unermes n %{server} + context: + add_note: Rnu tazmilt dagi + show_address: Sken tansa + query_features: Suter tiÉ£awsiwin + redaction: + edit: + description: Aglam + new: + description: Aglam + show: + description: 'Aglam:' + user: 'Amernay:' + confirm: TebÉ£iḍ? +... diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 9fe56c3d2..8db8281ed 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -4,6 +4,7 @@ # Author: Alex00728 # Author: Asdfqwer51 # Author: B891202 +# Author: CYAN # Author: Freebiekr # Author: Garam # Author: Hym411 @@ -58,7 +59,7 @@ ko: relation_tag: 관계 태그 session: 세션 trace: 궤적 - tracepoint: 궤적 점 + tracepoint: 궤적 지점 tracetag: 궤적 태그 user: 사용자 user_preference: 사용자 환경 설정 @@ -95,7 +96,7 @@ ko: user: email: 이메일 active: 활성 - display_name: 표시 이름 + display_name: 이름 보이기 description: 설명 languages: 언어 pass_crypt: 비밀번호 @@ -150,7 +151,7 @@ ko: feed: title: 바뀜집합 %{id} title_comment: 바뀜집합 %{id} - %{comment} - join_discussion: 토론에 참여하려면 로그인 + join_discussion: 토론에 참여하려면 로그인하세요 discussion: 토론 node: title: '교점: %{name}' @@ -200,7 +201,7 @@ ko: way: 길 relation: 관계 start_rjs: - feature_warning: 브라우저가 느려지거나 응답하지 않을 수 있게 하는 지물 %{num_features}개를 불러오고 있습니다. + feature_warning: 지물 %{num_features}개를 불러오고 있으며, 브라우저가 느려지거나 응답하지 않을 수 있습니다. 정말 이 데이터를 표시하겠습니까? load_data: 데이터 불러오기 loading: 불러오는 중... @@ -383,7 +384,7 @@ ko: scale: 축척 max: 최대 image_size: 그림 크기 - zoom: 확대 + zoom: 확대/축소 add_marker: 지도에 표시 추가 latitude: '위도:' longitude: '경도:' @@ -394,7 +395,6 @@ ko: search: title: latlon: 내부 ê²°ê³¼ - us_postcode: Geocoder.us에서의 ê²°ê³¼ uk_postcode: NPEMap / FreeThe Postcode에서의 ê²°ê³¼ ca_postcode: Geocoder.CA에서의 ê²°ê³¼ @@ -875,7 +875,7 @@ ko: alpine_hut: 산장 apartment: 아파트먼트 artwork: 예술 작품 - attraction: 견인 + attraction: 관광 명소 bed_and_breakfast: 민박 cabin: 오두막 camp_site: 캠프장 @@ -1008,7 +1008,7 @@ ko: 크리에이티브 커먼즈 저작자표시-동일조건변경허락 2.0 라이선스(CC BY-SA)에 따라 사용할 수 있습니다. credit_title_html: OpenStreetMap 제작진 넣는 방법 - credit_1_html: '“© 오픈스트리트맵 기여자”를 저작자로 사용해야 합니다.' + credit_1_html: '“© OpenStreetMap 기여자”를 저작자로 사용해야 합니다.' credit_2_html: |- 또한 명확하게 데이터는 오픈 데이터베이스 라이선스에 따라 사용할 수 있으며, 지도 제작은 지도 타일을 사용할 때에 CC-BY-SA로 허가합니다. @@ -1074,7 +1074,7 @@ ko: National Geo-Spatial Information에서의 데이터를 포함합니다. State가 저작권을 소유합니다. contributors_gb_html: |- - 연합 왕국: 육지 측량 데이터 + 영국: 육지 측량 데이터 © Crown 저작권 및 데이터베이스 권리 2010-12를 포함합니다. contributors_footer_1_html: |- @@ -1201,7 +1201,7 @@ ko: description: 깊이 있는 OSM 설명문서에 대해서는 위키를 찾아보세요. about_page: next: 다음 - copyright_html: ©ì˜¤í”ˆìŠ¤íŠ¸ë¦¬íŠ¸ë§µ
    기여자 + copyright_html: ©OpenStreetMap
    기여자 used_by: '%{name}의 지도 자료는 수많은 웹사이트와 모바일 앱, 하드웨어 장치에서 사용합니다' lede_text: OpenStreetMap은 도로나 오솔길, 카페, 기차역 등에 대한 전세계에 있는 자료를 유지하고 기여하는 지도 제작자 공동체로부터 제작됩니다. @@ -1218,10 +1218,10 @@ ko: 배포할 수 있습니다. 자세한 내용은 저작권 및 라이선스 문서에서 확인하세요.' legal_title: 법률 legal_html: |- - 이 사이트 및 많은 다른 관련된 부문은 공동체를 대표하여 오픈스트리트맵 재단에서 정식적으로 운영합니다. 오픈스트리트맵 재단이 운영하는 부문의 이용은 + 이 사이트 및 많은 다른 관련된 부문은 공동체를 대표하여 OpenStreetMap 재단에서 정식적으로 운영합니다. OpenStreetMap 재단이 운영하는 부문의 이용은 허용할 수 있는 이용 정책 및 개인정보 정책 조건 하에서 이루어집니다.
    - 만일 이용허락 또는 저작권 및 다른 법률적인 질문이나 사안이 있다면, 오픈스트리트맵 재단에 연락하십시오. + 만일 이용허락 또는 저작권 및 다른 법률적인 질문이나 사안이 있다면, OpenStreetMap 재단에 연락하십시오. partners_title: 파트너 notifier: diary_comment_notification: @@ -1266,11 +1266,11 @@ ko: email_confirm_plain: greeting: 안녕하세요, hopefully_you: 누군가가 아마 자신이 %{server_url} 에 %{new_address} (으)로 이메일 주소를 바꾸고 싶습니다. - click_the_link: 만약 당신이라면 바뀜을 확인하기 위해 아래 링크를 클릭하세요. + click_the_link: 만약 당신이라면 바뀐 내용을 확인하기 위해 아래의 링크를 클릭하세요. email_confirm_html: greeting: 안녕하세요, hopefully_you: 누군가가 아마 자신이 %{server_url} 에 %{new_address} (으)로 이메일 주소를 바꾸고 싶습니다. - click_the_link: 만약 당신이라면 바뀜을 확인하기 위해 아래 링크를 클릭하세요. + click_the_link: 만약 당신이라면 바뀐 내용을 확인하기 위해 아래 링크를 클릭하세요. lost_password: subject: '[OpenStreetMap] 비밀번호 재설정 요청' lost_password_plain: @@ -1376,6 +1376,7 @@ ko: date: 날짜 reply_button: 답글 unread_button: 읽지 않음으로 표시 + delete_button: 삭제 back: 뒤로 to: 받는이 wrong_user: '''%{user}''님으로 로그인하고 있지만 읽기를 요청한 메시지가 해당 사용자에게 보내지지 않았습니다. 읽으려면 @@ -1407,10 +1408,10 @@ ko: Adobe.com에서 플래시 플레이어를 다운로드할 수 있습니다. 몇 가지 다른 설정 또한 OpenStreetMap 편집을 위해 사용할 수 있습니다. - potlatch_unsaved_changes: 바뀜을 저장하지 않았습니다. (Potlatch에 저장하려면 라이브 모드에서 편집하는 경우, - 현재 길이나 점을 선택을 해제하거나 저장 버튼이 있다면 저장을 클릭해야 합니다.) + potlatch_unsaved_changes: 바뀐 내용을 저장하지 않았습니다. (Potlatch에 저장하려면 라이브 모드에서 편집하는 + 경우 현재 길이나 점의 선택을 해제하시고, 저장 버튼이 있다면 저장을 클릭해야 합니다.) potlatch2_not_configured: Potlatch 2가 설정되지 않았습니다 - 자세한 정보는 http://wiki.openstreetmap.org/wiki/The_Rails_Port - potlatch2_unsaved_changes: 바뀜을 저장하지 않았습니다. (Potlatch 2에서 저장하려면 저장을 클릭해야 합니다.) + potlatch2_unsaved_changes: 바뀐 내용을 저장하지 않았습니다. (Potlatch 2에서 저장하려면 저장을 클릭해야 합니다.) id_not_configured: iD가 설정되지 않았습니다 no_iframe_support: 브라우저가 이 기능에 필요한 HTML iframe을 지원하지 않습니다. sidebar: @@ -1422,9 +1423,9 @@ ko: get_directions_title: 두 점 사이의 길 찾기 from: 출발지 to: 도착지 - where_am_i: 내가 어디있나요? + where_am_i: 이것이 어디있나요? where_am_i_title: 검색 엔진을 사용하여 현재 위치를 나타냅니다 - submit_text: 가기 + submit_text: 검색 key: table: entry: @@ -1866,7 +1867,7 @@ ko: ct undecided: 정의되지 않음 ct declined: 거부됨 ct accepted: '%{ago} 전에 승인함' - latest edit: '최근 편집 %{ago}:' + latest edit: '마지막 편집 %{ago}:' email address: '이메일 주소:' created from: '만든 위치:' status: '상태:' @@ -2034,8 +2035,8 @@ ko: unknown_signature_algorithm: 알려지지 않은 인증 알고리즘 invalid_scope: 잘못된 범위 auth_association: - heading: 당신의 아이디는 아직 오픈스트리트맵에 등록되지 않았습니다. - option_1: 만약 당신이 오픈스트리트맵에 처음 이라면, 밑의 양식을 써서 새 계정을 만들어 주세요. + heading: 당신의 ID는 아직 OpenStreetMap 계정에 등록되지 않았습니다. + option_1: 만약 당신이 OpenStreetMap에 처음이시면, 아래 양식을 사용해 새 계정을 만들어 주세요. option_2: 만약 당신이 이미 계정을 가지고 있다면, 당신은 당신의 사용자 이름과 비밀번호를 사용해 로그인할 수 있고 당신의 아이디를 사용자 설정에서 등록할 수 있습니다. user_role: @@ -2232,7 +2233,7 @@ ko: gps: 공개 GPS 궤적 overlays: 지도 문제를 해결하기 위해 오버레이를 활성화 title: 레이어 - copyright: © 오픈스트리트맵 기여자 + copyright: © OpenStreetMap 기여자 donate_link_text: site: edit_tooltip: 지도 편집 diff --git a/config/locales/lb.yml b/config/locales/lb.yml index 1fb534e1a..f26ff0c19 100644 --- a/config/locales/lb.yml +++ b/config/locales/lb.yml @@ -48,6 +48,7 @@ lb: message: sender: Sender title: Sujet + recipient: Empfänger user: email: E-Mail active: Aktiv @@ -62,10 +63,14 @@ lb: id: name: iD browse: + created: Ugeluecht closed: Zou + created_html: Ugeluecht viru(n) %{time} closed_html: Zougemaach viru(n) %{time} + created_by_html: Ugeluecht viru(n) %{time} vum %{user} deleted_by_html: Geläscht viru(n) %{time} vum %{user} edited_by_html: Geännert viru(n) %{time} vum %{user} + closed_by_html: Zougemaach viru(n) %{time} vum %{user} version: Versioun in_changeset: Set vun Ännerungen anonymous: anonym @@ -87,6 +92,7 @@ lb: comment: Bemierkungen (%{count}) hidden_commented_by: Verstoppt Bemierkung vum %{user} viru(n) %{when} + commented_by: Bemierkung vum %{user} viru(n) %{when} changesetxml: XML mam Set vun Ännerungen osmchangexml: osmChange XML feed: @@ -196,6 +202,7 @@ lb: publish_button: Verëffentlechen list: title: Blogge vun de Benotzer + user_title: Blog vum %{user} edit: subject: 'Sujet:' language: 'Sprooch:' @@ -210,6 +217,7 @@ lb: login: Aloggen save_button: Späicheren diary_entry: + posted_by: Vum %{link_user} matgedeelt de(n) %{created} op %{language_link} comment_count: one: '%{count} Bemierkung' zero: Keng Bemierkungen @@ -232,6 +240,7 @@ lb: export: title: Exportéieren start: + area_to_export: Beräich fir den Export manually_select: Sicht manuell eng aner Géigend eraus format_to_export: Format fir z'exportéieren osm_xml_data: OpenStreetMap-XML-Daten @@ -249,12 +258,14 @@ lb: max: max image_size: Gréisst vum Bild zoom: Zoom + latitude: 'Geographesch Breet:' + longitude: 'Geographesch Längt:' + output: Resultat export_button: Exportéieren geocoder: search: title: latlon: Resultater vun Internal - us_postcode: Resultater vu Geocoder.us uk_postcode: Resultater vun NPEMap / FreeThe Postcode ca_postcode: Resultater vu Geocoder.ca @@ -262,12 +273,16 @@ lb: geonames_reverse: Resultater vun GeoNames search_osm_nominatim: prefix: + aerialway: + cable_car: Kabelwon aeroway: aerodrome: Fluchhafen gate: Paart + helipad: Helikopterlandeplaz runway: Start- a Landepist terminal: Terminal amenity: + arts_centre: Konschtzentrum atm: Bancomat bank: Bank bar: Bar @@ -286,9 +301,11 @@ lb: cinema: Kino clinic: Klinik clock: Auer + courthouse: Geriicht crematorium: Crematoire dentist: Zänndokter doctors: Dokteren + dormitory: Studentewunnengen drinking_water: Drénkwaasser driving_school: Fahrschoul embassy: Ambassade @@ -306,6 +323,7 @@ lb: market: Maart marketplace: Maartplaz monastery: Klouschter + nursery: Crèche office: Büro parking: Parking pharmacy: Apdikt @@ -315,6 +333,7 @@ lb: preschool: Spillschoul prison: Prisong pub: Bistro + public_building: Ëffentlecht Gebai reception_area: Rezeptiounsberäich recycling: Recycling-Center restaurant: Restaurant @@ -338,14 +357,19 @@ lb: boundary: national_park: Nationalpark bridge: + aqueduct: Aquädukt suspension: Hänkbréck + swing: Dréibréck viaduct: Viadukt "yes": Bréck building: "yes": Gebai craft: + brewery: Brauerei + carpenter: Zammermann electrician: Elektriker gardener: Gäertner + painter: Usträicher photographer: Fotograf shoemaker: Schouster tailor: Schneider @@ -355,6 +379,7 @@ lb: highway: bridleway: Wee fir Päerd bus_guideway: Busspur + bus_stop: Busarrêt construction: Autobunn (am Bau) elevator: Lift footway: Fousswee @@ -386,6 +411,7 @@ lb: citywalls: Stadmaueren house: Haus memorial: Monument + mine: Minn monument: Monument roman_road: Réimerwee ruins: Ruinen @@ -393,6 +419,8 @@ lb: tomb: Graf tower: Tuerm wreck: Wrack + junction: + "yes": Kräizung landuse: cemetery: Kierfecht farm: Bauerenhaff @@ -403,6 +431,7 @@ lb: grass: Wiss industrial: Industriezone military: Militairegebitt + mine: Minn orchard: Bongert quarry: Steekaul railway: Eisebunn @@ -494,7 +523,9 @@ lb: construction: Eisebunn (am Bau) disused: Fréier Eisebunn historic_station: Historesch Eisebunnsstatioun + junction: Eisebunnskräizung miniature: Miniatur-Eisebunn + platform: Zuchquai proposed: Proposéiert Eisebunnslinn station: Gare (Eisebunn) subway: Metro @@ -557,6 +588,7 @@ lb: "yes": Tunnel waterway: canal: Kanal + dam: Staudamm river: Floss wadi: Wadi waterfall: Waasserfall @@ -636,6 +668,7 @@ lb: title: Wëllkomm bäi OSM beginners_guide: url: http://wiki.openstreetmap.org/wiki/Beginners%27_guide + title: Guide fir nei Benotzer help: url: https://help.openstreetmap.org/ title: help.openstreetmap.org @@ -690,6 +723,8 @@ lb: subject: '[OpenStreetMap] Ufro fir d''Passwuert zréckzesetzen' lost_password_plain: greeting: Salut, + click_the_link: Wann Dir dat sidd da klickt w.e.g. op de Link hei drënner fir + Äert Passwuert zréckzesetzen. lost_password_html: greeting: Salut, click_the_link: Wann Dir dat sidd da klickt w.e.g. op de Link hei drënner fir @@ -701,6 +736,8 @@ lb: changeset_comment_notification: hi: Salut %{to_user}, greeting: Salut, + commented: + partial_changeset_without_comment: ouni Kommentar message: inbox: messages: Dir hutt %{new_messages} a(n) %{old_messages} @@ -734,17 +771,22 @@ lb: date: Datum reply_button: Äntwerten unread_button: Als net geliest markéieren + delete_button: Läschen back: Zréck sent_message_summary: delete_button: Läschen mark: as_read: Message als geliest markéiert + as_unread: Message als net geliest markéiert delete: deleted: Message geläscht site: index: + js_1: Dir hutt entweder e Browser dee JavaScript net ënnerstëtzt oder Dir hutt + JavaScript desaktivéiert. createnote: Eng Notiz derbäisetzen edit: + not_public: Dir hutt net agestallt datt Är Ännerungen ëffentlech sinn. user_page_link: Benotzersäit anon_edits_link_text: Fannt eraus firwat dat de Fall ass. sidebar: @@ -752,7 +794,7 @@ lb: close: Zoumaachen search: search: Sichen - where_am_i: Wou sinn ech? + where_am_i: Wou ass dat? submit_text: Lass key: table: @@ -882,6 +924,7 @@ lb: allow_write_api: Kaart änneren index: title: Meng OAuth Detailer + revoke: Ophiewen! form: name: Numm required: Obligatoresch diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 29ff2a56a..54e773e15 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -394,7 +394,6 @@ lt: search: title: latlon: Vidiniai rezultatai - us_postcode: Geocoder.us rezultatai uk_postcode: NPEMap / FreeThe Postcode rezultatai ca_postcode: Geocoder.CA rezultatai diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 8d8f8979e..8cfd51f91 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -2,6 +2,7 @@ # Exported from translatewiki.net # Export driver: phpyaml # Author: Admresdeserv. +# Author: Baisulis # Author: Bbot22 # Author: Cuu508 # Author: Edgars2007 @@ -132,6 +133,9 @@ lv: relation: Relācijas (%{count}) relation_paginated: Relācijas (%{x}-%{y} no %{count}) comment: Komentāri (%{count}) + hidden_commented_by: Slēptais komentārs no %{user} %{when} + ago + commented_by: Komentārs no %{user} %{when} atpakaļ changesetxml: Izmaiņu kopas XML osmchangexml: osmChange XML feed: @@ -387,7 +391,6 @@ lv: search: title: latlon: Rezultāti no Iekšējās meklēšanas - us_postcode: Rezultāti no Geocoder.us uk_postcode: Rezultāti no NPEMap / FreeThe Postcode ca_postcode: Rezultāti no Geocoder.CA @@ -952,7 +955,7 @@ lv: intro_text: OpenStreetMap ir pasaules karte, kuru veido cilvēki kā tu, un tā ir bezmaksas lietoÅ¡anai zem atvērtas licences. intro_2_create_account: Izveidot lietotāja kontu - partners_html: Servera vietu atblasta %{ucl}, %{ic} un %{bytemark}, un citi %{partners}. + partners_html: Servera vietu atbalsta %{ucl}, %{ic} un %{bytemark}, un citi %{partners}. partners_ucl: UCL partners_ic: Londonas Imperiālā Koledža partners_bytemark: Bytemark Hosting @@ -1018,7 +1021,7 @@ lv: title: Atsauces piemērs more_title_html: Uzzināt vairāk more_1_html: |- - Lasi vairāk par mÅ«su datiem, un kā uz mums atsaukties juridiskajā FAQ. more_2_html: |- @@ -1239,6 +1242,7 @@ lv: %{subject}:' footer_html: Tu arÄ« vari izlasÄ«t ziņojumu iekÅ¡ %{readurl} un atbildēt iekÅ¡ %{replyurl} friend_notification: + hi: Sveiks, %{to_user} subject: '[OpenStreetMap] %{user} pievienoja JÅ«s kā draugu' had_added_you: '%{user} pievienoja jÅ«s kā draugu OpenStreetMap.' see_their_profile: JÅ«s variet redzēt viņu profilu %{userurl}. @@ -1325,6 +1329,7 @@ lv: kur esi komentējis. PiezÄ«me ir netālu no %{place}.' details: Vairāk informācijas par piezÄ«mēm var atrast %{url}. changeset_comment_notification: + hi: Sveiks, %{to_user}, greeting: Sveicināti, commented: subject_own: '[OpenStreetMap] %{commenter} ir komentējis kādu no tavām izmaiņām' @@ -1337,6 +1342,8 @@ lv: partial_changeset_with_comment: ar komentāru '%{changeset_comment}' partial_changeset_without_comment: bez komentāra details: Vairāk informācijas par izmaiņām varat atrast %{url}. + unsubscribe: Lai atrakstÄ«tos no labojumu atjauninājumiem, apmeklē %{url} un + spied "AtrakstÄ«ties". message: inbox: title: iesÅ«tne @@ -1397,6 +1404,7 @@ lv: date: Datums reply_button: Atbilde unread_button: AtzÄ«mēt kā nelasÄ«tu + delete_button: Dzēst back: Atpakaļ to: Kam wrong_user: JÅ«s esat autorizējies kā `%{user}', bet ziņojums, kuru vēlaties @@ -1450,7 +1458,7 @@ lv: get_directions_title: IegÅ«t norādÄ«jumus starp diviem punktiem from: "No" to: Uz - where_am_i: Kur es esmu? + where_am_i: Kur tas ir? where_am_i_title: Aprakstiet paÅ¡reizējo atraÅ¡anās vietu izmantojot meklētāju submit_text: OK key: @@ -1662,6 +1670,8 @@ lv: require_moderator: not_a_moderator: Tev nepiecieÅ¡ams bÅ«t moderatoram, lai izpildÄ«tu Å¡o darbÄ«bu. setup_user_auth: + blocked_zero_hour: Jums ir pienākusi svarÄ«ga ziņa tÄ«mekļa vietnē OpenStreetMap. + Jums ir jāizlasa ziņa pirms jÅ«s saglabāsiet savas izmaiņas. blocked: Tev ir liegta piekļuve API. LÅ«dzu autorizējies mājaslapas interfeisā, lai uzzinātu vairāk. need_to_see_terms: Tava piekļuve API un laiku pārtraukta. LÅ«dzu autorizējies diff --git a/config/locales/mk.yml b/config/locales/mk.yml index a737bd57a..d00352f8a 100644 --- a/config/locales/mk.yml +++ b/config/locales/mk.yml @@ -383,7 +383,6 @@ mk: search: title: latlon: Внатрешни исходни ставки - us_postcode: Исход од Geocoder.us uk_postcode: Исход од NPEMap / FreeThe Postcode ca_postcode: Исход од Geocoder.CA @@ -1407,6 +1406,7 @@ mk: date: Датум reply_button: Одговори unread_button: Означи како непрочитано + delete_button: Избриши back: Назад to: За wrong_user: Најавени сте како „%{user}“, но пораката што побаравте да ја прочитате @@ -1462,7 +1462,7 @@ mk: from: Од to: До where_am_i: Каде сум? - where_am_i_title: Опишете ја моменталната местоположба со помош на пребарувачот + where_am_i_title: Опишете ја тековната местоположба со помош на пребарувачот submit_text: Дај key: table: diff --git a/config/locales/mr.yml b/config/locales/mr.yml index b64ef9c49..67009b6fe 100644 --- a/config/locales/mr.yml +++ b/config/locales/mr.yml @@ -360,7 +360,6 @@ mr: search: title: latlon: निकाल अंतर्गत - us_postcode: निकाल जिओकोडर.यूएस uk_postcode: निकालNPEMap / FreeThe Postcode ca_postcode: निकाल जिओकोडर.सीए osm_nominatim: निकाल ओपनस्ट्रीटमॅप diff --git a/config/locales/ms.yml b/config/locales/ms.yml index ecb0c7bcc..4ba64c820 100644 --- a/config/locales/ms.yml +++ b/config/locales/ms.yml @@ -2,6 +2,7 @@ # Exported from translatewiki.net # Export driver: phpyaml # Author: Anakmalaysia +# Author: Jeluang Terluang # Author: Karmadunya9- # Author: Macofe # Author: Nemo bis @@ -371,7 +372,6 @@ ms: search: title: latlon: Hasil carian dalaman - us_postcode: Hasil carian Geocoder.us uk_postcode: Hasil carian NPEMap / FreeThe Postcode ca_postcode: Hasil carian Geocoder.CA @@ -925,7 +925,7 @@ ms: edit_with: Sunting dengan %{editor} tag_line: Peta Dunia Wiki Bebas intro_header: Selamat datang ke OpenStreetMap! - intro_text: OpenStreetMap adalah peta dunia yang diwujudkan oleh insan seperti + intro_text: OpenStreetMap ialah peta dunia yang diwujudkan oleh insan seperti anda, dan bebas digunakan dengan berlandaskan lesen terbuka. intro_2_create_account: Buka akaun pengguna partners_html: Pengehosan disokong oleh %{ucl}, %{ic} dan %{bytemark}, serta %{partners} @@ -1040,8 +1040,8 @@ ms: atau menerima sebarang tanggungan.' infringement_title_html: Pencabulan hak cipta infringement_1_html: Penyumbang OSM diingatkan supaya tidak sesekali menambah - data dari mana-mana sumber berhak cipta (cth. Google Maps atau peta cetakan) - tanpa izin bersurat dari pemegang hak cipta. + data daripada mana-mana sumber berhak cipta (cth. Peta Google atau peta cetakan) + tanpa izin bersurat daripada pemegang hak cipta. infringement_2_html: "Sekiranya anda percaya bahawa bahan berhak cipta telah dtambahkan secara tidak berpatutan ke dalam pangkalan OpenStreetMap atau tapak ini, sila rujuk prosedur @@ -1067,13 +1067,13 @@ ms: title: Peristilahan Asas Pemetaan paragraph_1_html: OpenStreetMap mempunyai peristilahan tersendiri. Yang berikut ialah kata-kata kunci yang berguna. - editor_html: Editor adalah perisian atau laman web yang boleh + editor_html: Editor ialah perisian atau laman web yang boleh digunakan untuk menyunting peta. - node_html: Nod adalah titik pada peta, seperti sebuah kedai + node_html: Nod ialah titik pada peta, seperti sebuah kedai makan atau sebatang pokok. - way_html: Jalan adalah garis atau kawasan seperti jalan raya, + way_html: Jalan ialah garis atau kawasan seperti jalan raya, sungai, tasik atau bangunan. - tag_html: Teg adalah keterangan ringkas mengenai nod atau jalan, + tag_html: Teg ialah keterangan ringkas mengenai nod atau jalan, seperti nama restoran atau had laju jalan raya. rules: title: Peraturan! @@ -1098,7 +1098,7 @@ ms: join_the_community: title: Sertai komuniti explanation_html: Jika anda mendapati kemusykilan dengan data peta kami, misalnya - jalan raya atau alamat anda tertinggal, cara penyelesaian yang terbaik adalah + jalan raya atau alamat anda tertinggal, cara penyelesaian yang terbaik ialah menyertai komuniti OpenStreetMap dan menambah atau membetulkan data sendiri. add_a_note: instructions_html: |- @@ -1156,9 +1156,12 @@ ms: blog komuniti, dan laman web the OSM Foundation. open_data_title: Data Terbuka - open_data_html: |- - OpenStreetMap adalah data terbuka: anda bebas menggunakannya untuk sebarang tujuan asalkan anda memberikan penghargaan kepada OpenStreetMap dan para penyumbangnya. Jika anda mengubah suai atau menokok tambah datanya - dalam cara-cara tertentu, anda boleh mengedarkan hasilnya di bawah lesen yang sama sahaja. Rujuk halaman Hak Cipta dan Lesen untuk keterangan lanjut. + open_data_html: 'OpenStreetMap ialah data terbuka: anda bebas menggunakannya + untuk sebarang tujuan asalkan anda memberikan penghargaan kepada OpenStreetMap + dan para penyumbangnya. Jika anda mengubah suai atau menokok tambah datanya + dalam cara-cara tertentu, anda boleh mengedarkan hasilnya di bawah lesen yang + sama sahaja. Rujuk halaman Hak Cipta dan Lesen + untuk keterangan lanjut.' partners_title: Rakan Kongsi notifier: diary_comment_notification: diff --git a/config/locales/nb.yml b/config/locales/nb.yml index 2428b5bf8..bfcdda7ac 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -394,7 +394,6 @@ nb: search: title: latlon: Resultat fra Internt - us_postcode: Resultat fra Geocoder.us uk_postcode: Resultat fra NPEMap / FreeThe Postcode ca_postcode: Resultat fra Geocoder.CA @@ -964,7 +963,7 @@ nb: og gratis Ã¥ bruke under en Ã¥pen lisens. intro_2_create_account: Opprett en brukerkonto partners_html: Hosting er støttet av %{ucl}, %{ic}, %{bytemark} og andre %{partners}. - partners_ucl: UCL VR-senteret + partners_ucl: UCL partners_ic: Imperial College London partners_bytemark: Bytemark Hosting partners_partners: partnere @@ -1403,6 +1402,7 @@ nb: date: Dato reply_button: Svar unread_button: Marker som ulest + delete_button: Slett back: Tilbake to: Til wrong_user: Du er logget inn som «%{user}», men meldingen du ønsker Ã¥ lese ble @@ -2345,6 +2345,7 @@ nb: ascend: Tiltagende engines: graphhopper_bicycle: Sykkel (GraphHopper) + graphhopper_car: Bil (GraphHopper) graphhopper_foot: Til fots (GraphHopper) mapquest_bicycle: Sykkel (MapQuest) mapquest_car: Bil (MapQuest) diff --git a/config/locales/ne.yml b/config/locales/ne.yml index 16ba19515..210c65be5 100644 --- a/config/locales/ne.yml +++ b/config/locales/ne.yml @@ -264,7 +264,11 @@ ne: sorry: माफ गर्नुहोला, तपाईंले खोज्नुभएको परिवर्तनहरूको सूची प्राप्त गर्न निकै समय लाग्यो । rss: + title_all: OpenStreetMap परिवर्वतन सूची छलफल + title_particular: 'OpenStreetMap परिवर्तन सूची #%{changeset_id} छलफल' + comment: ' %{author}द्वारा #%{changeset_id}मा नयाँ टिप्पणी' commented_at_html: ' %{when} पहिले अद्यावधि गरिएको' + commented_at_by_html: ' %{user} द्वारा %{when} पहिले अद्यावधिक गरिएको' full: पूरा वार्तालाप diary_entry: new: @@ -364,8 +368,8 @@ ne: title: ओएस्एम ग्रह description: नियमित रूपमा अपडेट गरिएका ओपनस्ट्रीटम्याप तथ्याङ्कका प्रतिहरू overpass: - title: ओभरपास एपिअाई - description: ओपनस्ट्रीटम्याप तथ्याङ्कको अर्को स्रोतबाट यो सिमारेखा प्राप्त + title: ओभरपास एपिअाइ + description: OpenStreetMap तथ्याङ्कको अर्को स्रोतबाट यो सिमारेखा प्राप्त गर्नुहोस् geofabrik: title: Geofabrik डाउनलोडहरू @@ -393,7 +397,6 @@ ne: search: title: latlon: आन्तरिक बाट नतिजाहरू - us_postcode: Geocoder.usबाट नतिजाहरू uk_postcode: NPEMap / FreeThe Postcodeबाट नतिजाहरू ca_postcode: Geocoder.CAintern - us_postcode: Resultaten van Geocoder.us uk_postcode: Resultaten van NPEMap / FreeThe Postcode ca_postcode: Resultaten van Geocoder.CA @@ -1064,8 +1064,7 @@ nl: more_title_html: Meer informatie more_1_html: Lees meer over het gebruik van onze gegevens, en hoe u OpenStreetMap moet vermelden, op de licentiepagina - van de OSMF en de gemeenschapspagina vaak - gestelde juridische vragen (Engelstalig). + van de OSMF more_2_html: |- Hoewel OpenStreetMap open data is, kunnen we geen gratis kaart-API voor derde partijen aanbieden. @@ -1290,6 +1289,7 @@ nl: footer_html: U kunt het bericht ook lezen op %{readurl} en u kunt antwoorden op %{replyurl} friend_notification: + hi: Hoi %{to_user}, subject: '[OpenStreetMap] %{user} heeft u als vriend toegevoegd' had_added_you: '%{user} heeft u toegevoegd als vriend op OpenStreetMap.' see_their_profile: U kunt zijn/haar profiel bekijken op %{userurl}. @@ -1377,6 +1377,7 @@ nl: opnieuw geactiveerd. De opmerking is gemaakt bij %{place}.' details: Meer details over de opmerking zijn te vinden op %{url}. changeset_comment_notification: + hi: Hoi %{to_user}, greeting: Hallo, commented: subject_own: '[OpenStreetMap] %{commenter} heeft gereageerd op een van uw @@ -1390,6 +1391,8 @@ nl: partial_changeset_with_comment: met reactie "%{changeset_comment}" partial_changeset_without_comment: zonder reactie details: Meer details over de wijzigingenset kunt u vinden op %{url}. + unsubscribe: Om je af te melden van de updates van deze wijzigig, ga naar %{url} + en klik op "Afmelden". message: inbox: title: Postvak IN @@ -1451,6 +1454,7 @@ nl: date: Datum reply_button: Antwoorden unread_button: Markeren als ongelezen + delete_button: Verwijderen back: Terug to: Aan wrong_user: |- @@ -1504,7 +1508,7 @@ nl: get_directions_title: Routebeschrijving tussen twee punten from: Van to: Naar - where_am_i: Waar ben ik? + where_am_i: Waar is dit? where_am_i_title: De huidige locatie via de zoekmachine beschrijven submit_text: OK key: @@ -1516,7 +1520,7 @@ nl: primary: Primaire weg secondary: Secundaire weg unclassified: Ongeclassificeerde weg - track: Spoor + track: Veld- of bosweg bridleway: Ruiterpad cycleway: Fietspad cycleway_national: Nationale fietsroute @@ -1718,6 +1722,8 @@ nl: require_moderator: not_a_moderator: U moet moderator zijn om die handeling uit te kunnen voeren. setup_user_auth: + blocked_zero_hour: U heeft een urgente melding op de OpenStreetMap web site. + U moet het bericht lezen voordat u in staat bent uw wijzigingen op te slaan. blocked: Uw toegang tot de API is geblokkeerd. Meld u opnieuw aan in de webinterface om meer te weten te komen. need_to_see_terms: Uw toegang tot de API is tijdelijk opgeschort. Meld u aan @@ -1748,6 +1754,8 @@ nl: invalid: Het autorisatietoken is niet geldig. revoke: flash: U hebt het token voor %{application} ingetrokken + permissions: + missing: U heeft niet toegestaan dat de applicatie toegang heeft tot dit kenmerk. oauth_clients: new: title: Nieuwe toepassing registreren @@ -2261,6 +2269,8 @@ nl: helper: time_future: Vervalt over %{time}. until_login: Actief totdat de gebruiker zich aanmeldt. + time_future_and_until_login: Eindigt in %{time} en nadat de gebruiker ingelogd + is. time_past: '%{time} geleden vervallen.' blocks_on: title: Blokkades voor %{name} @@ -2461,6 +2471,13 @@ nl: nothing_found: Geen eigenschappen gevonden error: 'Fout bij het verbinding maken met %{server}: %{error}' timeout: Timeout bij het verbinding maken met %{server} + context: + directions_from: Aanwijzingen vanaf hier + directions_to: Aanwijzingen naar hier + add_note: Voeg hier een commentaar toe + show_address: Toon adres + query_features: Opvragen van kenmerken + centre_map: Centreer de kaart hier redaction: edit: description: Beschrijving diff --git a/config/locales/nn.yml b/config/locales/nn.yml index a74c290e2..4a7cc09d8 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -1,6 +1,7 @@ # Messages for Norwegian Nynorsk (norsk nynorsk) # Exported from translatewiki.net # Export driver: phpyaml +# Author: Bjorni # Author: Dittaeva # Author: Eirik # Author: Gnonthgol @@ -60,7 +61,7 @@ nn: body: Brødtekst diary_entry: user: Brukar - title: Tittel + title: 'Emne:' latitude: Breiddegrad longitude: Lengdegrad language: SprÃ¥k @@ -78,7 +79,7 @@ nn: description: Skildring message: sender: Sendar - title: Tittel + title: Emne body: Brødtekst recipient: Mottakar user: @@ -95,6 +96,9 @@ nn: potlatch: name: Potlatch 1 description: Potlatch 1 (rediger i nettlesaren) + id: + name: ID + description: iD (redigering i nettlesaren) potlatch2: name: Potlatch 2 description: Potlatch 2 (rediger i nettleseran) @@ -102,13 +106,33 @@ nn: name: Lokalt installert program description: Lokalt installert program (JOSM eller Merkaartor) browse: + created: Oppretta + closed: Attlaten + created_html: Oppretta for %{time} sidan + created_by_html: Oppretta for %{time} sidan av %{user} + deleted_by_html: Sletta for %{time} sidan av %{user} + edited_by_html: Redigert for %{time} sidan av %{user} + version: 'Versjon:' + anonymous: anonym + no_comment: (ingen kommentar) + part_of: Del av + download_xml: Last ned XML + view_history: Vis historikk + view_details: Vis detaljar changeset: - title: Endringssett + title: Endringssett %{id} + belongs_to: Skapar + way: Strekningar (%{count}) + way_paginated: Strekningar (%{x}-%{y} av %{count}) + comment: Kommentarar (%{count}) changesetxml: XML for endringssett osmchangexml: osmChange XML feed: title: Endringssett %{id} title_comment: 'Endringssett: %{id} - %{comment}' + discussion: Ordskifte + relation: + members: Medlemmar relation_member: entry: '%{type} %{name}' entry_role: '%{type} %{name} som %{role}' @@ -120,12 +144,13 @@ nn: entry: Relasjon %{relation_name} entry_role: Relasjon %{relation_name} (som %{relation_role}) not_found: - sorry: Klarte ikkje finne %{type}-ein med ID %{id}. + sorry: Beklagar, klarte ikkje Ã¥ finne %{type}-en med ID %{id}. type: node: node way: veg relation: relasjon changeset: endringssett + note: merknad timeout: sorry: Beklagar, data for %{type} med id %{id} tok for lang tid Ã¥ hente. type: @@ -133,6 +158,7 @@ nn: way: veg relation: relasjon changeset: endringssett + note: merknad redacted: redaction: Maskering %{id} message_html: Versjon %{version} av denne %{type} kan ikkje visast fordi den @@ -145,15 +171,21 @@ nn: load_data: Last inn data loading: Lastar... tag_details: - tags: 'Merkelapper:' + tags: Merkelappar wiki_link: key: Wiki-beskrivelsessiden for %{key}-elementet tag: Wiki-beskrivelsessiden for %{key}=%{value}-elementet wikipedia_link: Artikkelen %{page} pÃ¥ Wikipedia + telephone_link: Ring %{phone_number} note: - description: 'Skildring:' - open_title: 'Uoppklara notis: %{note_name}' - closed_title: 'Oppklara notis: %{note_name}' + title: 'Merknad: %{id}' + new_note: Ny merknad + description: Skildring + open_title: 'Uavklart merknad #%{note_name}' + closed_title: 'Avklart merknad: #%{note_name}' + query: + title: Førespurnadsfunksjonar + nearby: Nærliggjande funksjonar changeset: changeset_paging_nav: showing_page: Side %{page} @@ -174,11 +206,17 @@ nn: title_user: Endringssett av %{user} title_friend: Endringssett av venene dine title_nearby: Endringssett av naboar + load_more: Last inn meir timeout: sorry: Lista over endringssett tok for lang tid Ã¥ hente. + rss: + commented_at_html: Oppdatert for %{when} sidan + commented_at_by_html: Oppdatert for %{when} sidan av %{user} + full: Fullstendig ordskifte diary_entry: new: title: Ny dagbokoppføring + publish_button: Publiser list: title: Brukarane sine dagbøker title_friends: Dagbøkene til venene dine @@ -252,6 +290,7 @@ nn: newer_comments: Nyare kommentarar older_comments: Eldre kommentarar export: + title: Eksporter start: area_to_export: OmrÃ¥de som skal eksporterast manually_select: Vel eit anna omrÃ¥de manuelt @@ -265,6 +304,10 @@ nn: too_large: body: Dette omrÃ¥det er for stort for Ã¥ eksporterast som OpenStreetMap XML-data. Zoom inn eller vel eit mindre omrÃ¥de. + planet: + title: Planet OSM + other: + title: Andre kjelder options: Val format: Format scale: Skala @@ -281,7 +324,6 @@ nn: search: title: latlon: Resultat frÃ¥ Internt - us_postcode: Resultat frÃ¥ Geocoder.us uk_postcode: Resultat frÃ¥ NPEMap / FreeThe Postcode ca_postcode: Resultat frÃ¥ Geocoder.CA @@ -291,6 +333,12 @@ nn: search_osm_nominatim: prefix_format: '%{name}' prefix: + aerialway: + cable_car: Kabelbane + chair_lift: Stolheis + drag_lift: Skitrekk + gondola: Gondolheis + station: Fjellheisstasjon aeroway: aerodrome: Flyplass apron: Flyrampe @@ -309,6 +357,7 @@ nn: bicycle_parking: Sykkelparkering bicycle_rental: Sykkelutleige biergarten: Ølhage + boat_rental: BÃ¥tutleige brothel: Bordell bureau_de_change: Vekslingskontor bus_station: Busstasjon @@ -320,6 +369,7 @@ nn: charging_station: Ladestation cinema: Kino clinic: Klinikk + clock: Klokke college: Høgskule community_centre: Samfunnshus courthouse: Rettsbygning @@ -338,6 +388,7 @@ nn: food_court: Serveringsstadar fountain: Fontene fuel: Drivstoff + gambling: Gambling grave_yard: Gravlund gym: Treningssenter health_centre: Helsesenter @@ -348,11 +399,14 @@ nn: library: Bibliotek market: Marknad marketplace: Marknadsplass + monastery: Kloster + motorcycle_parking: Motorsykkelparkering nightclub: Nattklubb nursery: Førskule nursing_home: Pleieheim office: Kontor parking: Parkeringsplass + parking_entrance: Innkøyring til parkeringsgarasje pharmacy: Apotek place_of_worship: Religiøst hus police: Politi @@ -399,12 +453,30 @@ nn: "yes": Bru building: "yes": Bygning + craft: + brewery: Bryggeri + carpenter: Tømrar + electrician: Elektrikar + gardener: Gartnar + painter: MÃ¥lar + photographer: Fotograf + plumber: Røyrleggjar + shoemaker: Skomakar + tailor: Skreddar + "yes": Handverkbutikk + emergency: + ambulance_station: Ambulansestasjon + defibrillator: Hjartestartar + landing_site: Nødlandingsplass + phone: Nødtelefon highway: + abandoned: Forlaten motorveg bridleway: Rideveg bus_guideway: Leidde bussfelt bus_stop: Busstopp construction: Motorveg under konstruksjon cycleway: Sykkelsti + elevator: Heis emergency_access_point: Nødtilgangspunkt footway: Gangsti ford: Vadestad @@ -418,6 +490,7 @@ nn: platform: Perrong primary: Primær veg primary_link: Primær veg + proposed: FøreslÃ¥tt veg raceway: Racerbane residential: Bustadveg rest_area: Rasteplass @@ -428,33 +501,45 @@ nn: services: Motorveitjenester speed_camera: Fotoboks steps: Trapper + street_lamp: Gatelykt tertiary: Tertiær veg tertiary_link: Kommunal veg track: Sti + traffic_signals: Trafikklys trail: Sti trunk: Hovedveg trunk_link: Hovedveg unclassified: Uklassifisert veg unsurfaced: Veg utan dekke + "yes": Veg historic: archaeological_site: Arkeologisk plass battlefield: Slagmark boundary_stone: Grensestein - building: Bygning + building: Historisk bygning + bunker: Bunker castle: Slott church: Kyrkje + city_gate: Byport + citywalls: Bymurar fort: Fort + heritage: Verdsarvsstad house: Hus icon: Ikon manor: Herregard memorial: Minne mine: Gruve monument: Monument + roman_road: Romersk veg ruins: Ruinar + stone: Stein + tomb: Grav tower: TÃ¥rn wayside_cross: Vegkant kross wayside_shrine: Vegkant alter wreck: Vrak + junction: + "yes": Kryss landuse: allotments: Kolonihagar basin: ElveomrÃ¥de @@ -489,11 +574,15 @@ nn: leisure: beach_resort: Strandsted bird_hide: FugletÃ¥rn + club: Klubb common: Allmenning + dog_park: Hundepark fishing: FiskeomrÃ¥de + fitness_centre: Treningssenter fitness_station: Trenings studio garden: Hage golf_course: Golfbane + horse_riding: Riding ice_rink: Skøytebane marina: BÃ¥thavn miniature_golf: Minigolf @@ -502,6 +591,7 @@ nn: pitch: Sportsarena playground: Leikeplass recreation_ground: Idrettsplass + resort: Feriestad sauna: Badstu slipway: Slipp sports_centre: Sportssenter @@ -509,6 +599,13 @@ nn: swimming_pool: Symjebaseng track: Laupebane water_park: Vannpark + "yes": Fritid + man_made: + lighthouse: Fyr + pipeline: Røyrleidning + tower: TÃ¥rn + works: Fabrikk + "yes": Menneskeskapt military: airfield: Militær flyplass barracks: Kaserner @@ -540,6 +637,7 @@ nn: reef: Rev ridge: Rygg rock: Stein + sand: Sand scree: Ur scrub: Kratt spring: Kjelde @@ -553,6 +651,7 @@ nn: wood: Skog office: accountant: Revisor + administrative: Administrasjon architect: Arkitekt company: Bedrift employment_agency: Bemanningsbedrift @@ -565,6 +664,7 @@ nn: travel_agent: ReisebyrÃ¥ "yes": Kontor place: + block: Blokk airport: Flyplass city: By country: Land @@ -579,6 +679,7 @@ nn: locality: Plass moor: Myr municipality: Kommune + neighbourhood: Nabolag postcode: Postnummer region: OmrÃ¥de sea: Hav @@ -588,6 +689,7 @@ nn: town: Tettstad unincorporated_area: Kommunefritt omrÃ¥de village: Landsby + "yes": Stad railway: abandoned: Forlatt jernbane construction: Jernbane under konstruksjon @@ -604,6 +706,7 @@ nn: narrow_gauge: Smalsporjernbane platform: Jernbaneperrong preserved: Verna jernbane + proposed: FøreslÃ¥tt jernbane spur: Jernbaneforgrening station: Jernbanestasjon subway: T-banestasjon @@ -671,17 +774,21 @@ nn: pet: Dyrebutikk photo: Fotobutikk salon: Salong + second_hand: Bruktbutikk shoes: Skobutikk shopping_centre: Kjøpesenter sports: Sportsbutikk stationery: Papirbutikk supermarket: Supermarked + tailor: Skreddar toys: Lekebutikk travel_agency: ReisebyrÃ¥ video: Videobutikk wine: Utanfor lisens + "yes": Butikk tourism: alpine_hut: Fjellhytte + apartment: Leilegheit artwork: Kunstverk attraction: Attraksjon bed_and_breakfast: Bed and breakfast @@ -689,6 +796,7 @@ nn: camp_site: Teltplass caravan_site: Campingplass chalet: Fjellhytte + gallery: Galleri guest_house: Gjestehus hostel: Vandrerhjem hotel: Hotell @@ -719,6 +827,7 @@ nn: wadi: Elveleie waterfall: Foss weir: Overløpskant + "yes": Vassveg description: title: osm_nominatim: Posisjon frÃ¥ OpenStreetMap @@ -738,20 +847,24 @@ nn: logo: alt_text: OpenStreetMap-logo home: heim - logout: logg ut - log_in: logg inn + logout: Logg ut + log_in: Logg inn log_in_tooltip: Logg inn med ein eksisterande konto - sign_up: registrer + sign_up: Registrer deg + start_mapping: Start kartlegging sign_up_tooltip: Opprett ein konto for redigering edit: Rediger history: Historikk export: Eksporter + data: Data + export_data: Eksportar data gps_traces: GPS-spor gps_traces_tooltip: Handsam GPS-spor user_diaries: Brukardagbok user_diaries_tooltip: Vis brukaren si dagbok edit_with: Rediger med %{editor} tag_line: Fritt Wiki-verdenskart + intro_header: Velkomen til OpenStreetMap! intro_2_create_account: Opprett ein brukarkonto partners_html: Drifta er støtta av %{ucl}, %{ic}, %{bytemark} og andre %{partners}. partners_ucl: UCL VR-senteret @@ -765,7 +878,8 @@ nn: donate: Støytt OpenStreetMap ved %{link} til Hardware Upgrade Fund (eit fond for maskinvareoppgraderinger). help: Hjelp - copyright: Opphavsrett & lisens + about: Om + copyright: Opphavsrett community: Samfunnet community_blogs: Bloggar community_blogs_title: Bloggar frÃ¥ medlemmane i OpenStreetMap-felleskapet @@ -774,6 +888,8 @@ nn: make_a_donation: title: Støtt OpenStreetMap med ei pengegÃ¥ve text: Gje pengegÃ¥ve + learn_more: Les meir + more: Meir license_page: foreign: title: Om denne omsetjinga @@ -877,9 +993,47 @@ nn: takedown \nprosedyre eller direkte til vÃ¥rt online skjema." + welcome_page: + title: Velkomen! + rules: + title: Reglar! + questions: + title: SpørsmÃ¥l? + start_mapping: Start kartlegging + fixthemap: + title: Rapporter eit problem/Korriger kartet + how_to_help: + title: Korleis hjelpe til + join_the_community: + title: Ver med i fellesskapen help_page: + title: FÃ¥ hjelp + welcome: + url: /velkommen + title: Velkomen til OSM beginners_guide: url: http://wiki.openstreetmap.org/wiki/Nn:Beginners%27_guide + help: + title: help.openstreetmap.org + mailing_lists: + title: E-postlister + forums: + title: Forum + irc: + title: IRC + switch2osm: + title: switch2osm + wiki: + url: http://wiki.openstreetmap.org/ + title: wiki.openstreetmap.org + about_page: + next: Neste + copyright_html: ©OpenStreetMap
    bidragsytarar + local_knowledge_title: Lokalkunnskap + community_driven_title: Fellesskapsdrive + open_data_title: Opne Data + legal_title: Juridisk + partners_title: Partnarar notifier: diary_comment_notification: subject: '[OpenStreetMap] %{user} kommenterte på ein oppføring i dagboka di' @@ -894,6 +1048,7 @@ nn: header: '%{from_user} har sendt deg ei melding gjennom OpenStreetMap med emnet %{subject}:' friend_notification: + hi: Hei %{to_user}, subject: '[OpenStreetMap] %{user} la deg til som ein ven' had_added_you: '%{user} har lagt deg til som ven på OpenStreetMap.' see_their_profile: Du kan sjå profilen deira på %{userurl}. @@ -951,6 +1106,12 @@ nn: anonymous: Ein anonym brukar greeting: Hei, details: Meir detaljar om notisen kan du finne på %{url}. + changeset_comment_notification: + hi: Hei %{to_user}, + greeting: Hei, + commented: + partial_changeset_with_comment: med kommentaren '%{changeset_comment}' + partial_changeset_without_comment: utan kommentar message: inbox: title: Innboks @@ -1012,6 +1173,8 @@ nn: date: Dato reply_button: Svar unread_button: Marker som ulese + delete_button: Slett + back: Tilbake to: Til wrong_user: Du er logga inn som «%{user}», men meldinga du ynskjer å lese vart ikkje send til den brukaren. Logg inn som korrekt brukar for å lese. @@ -1058,6 +1221,8 @@ nn: close: Lukk search: search: Søk + from: Frå + to: Til where_am_i: Kor er eg? where_am_i_title: Bruk søkjemotoren til å skildre gjeldande lokasjon. submit_text: Gå @@ -1065,6 +1230,7 @@ nn: table: entry: motorway: Motorveg + main_road: Hovudveg trunk: Hovedveg primary: Primærveg secondary: Sekundærveg @@ -1072,6 +1238,9 @@ nn: track: Spor bridleway: Rideveg cycleway: Sykkelveg + cycleway_national: Nasjonal sykkelsti + cycleway_regional: Regional sykkelsti + cycleway_local: Lokal sykkelsti footway: Gangveg rail: Jernbane subway: Undergrunnsbane @@ -1124,6 +1293,9 @@ nn: private: Privat tilgjenge destination: Destinasjonstilgang construction: Vegar under konstruksjon + bicycle_shop: Sykkelbutikk + bicycle_parking: Sykkelparkering + toilets: Toalett richtext_area: edit: Endre preview: Førehandsvising @@ -1231,7 +1403,7 @@ nn: in: i map: kart list: - public_traces: Offentleg GPS-spor + public_traces: Offentlege GPS-spor your_traces: Dine GPS-spor public_traces_from: Offentlege GPS-spor frå %{user} description: Vis siste opplasta GPS loggar @@ -1249,6 +1421,8 @@ nn: heading: GPX-lagring er utilgjengelig message: Systemet for opplasting og lagring av GPX-filer er ikkje tilgjengeleg for augneblunken. + description: + description_without_count: GPX-fil frå %{user} application: require_cookies: cookies_needed: Du ser ut til å ha deaktivert informasjonskapsler. Aktivar informasjonskapsler @@ -1274,6 +1448,7 @@ nn: allow_read_gpx: lese dine private GPS-spor. allow_write_gpx: laste opp GPS-spor. allow_write_notes: endre notisar. + grant_access: Gje tilgang revoke: flash: Du sletta nøkkelen for %{application} oauth_clients: @@ -1362,6 +1537,34 @@ nn: du ynskjer å diskutere dette. auth failure: Beklagar, kunne ikkje logge inn med den informasjonen openid_logo_alt: Logg inn med ein OpenID + auth_providers: + openid: + title: Logg inn med OpenID + alt: Logg inn med ein OpenID-URL + google: + title: Logg inn med Google + alt: Logg inn med ein Google OpenID + facebook: + title: Logg inn med Facebook + alt: Logg inn med ein Facebook-konto + windowslive: + title: Logg inn med Windows Live + alt: Logg inn med ein Windows Live-konto + github: + title: Log inn med GitHub + alt: Logg inn med ein GitHub-konto + wikipedia: + title: Logg inn med Wikipedia + alt: Logg inn med ein Wikipedia-konto + yahoo: + title: Logg inn med Yahoo + alt: Logg inn med ein Yahoo OpenID + wordpress: + title: Logg inn med Wordpress + alt: Logg inn med ein Wordpress OpenID + aol: + title: Logg inn med AOL + alt: Logg inn med ein AOL OpenID logout: title: Logg ut heading: Logg ut frå OpenStreetMap @@ -1385,11 +1588,13 @@ nn: flash changed: Passordet ditt er endra. flash token bad: Kunne ikkje finne den nøkkelen. Sjekke URLen kanskje? new: - title: Opprett konto + title: Registrer deg no_auto_account_create: Beklagelegvis kan me for augneblunken ikkje opprette ein konto for deg automatisk. contact_webmaster: Kontakt webmaster for å opprette ein konto. Me vil prøve å handsame førespurnaden så fort som mogleg. + about: + header: Fri og redigerbar license_agreement: Når du stadfestar kontoen din må du godkjenne bidragsytervilkåra. email address: 'E-postadresse:' confirm email address: 'Stadfest e-postadresse:' @@ -1401,7 +1606,7 @@ nn: dette seinare i innstellingane. password: 'Passord:' confirm password: 'Stadfest passord:' - continue: Hald fram + continue: Registrer deg terms accepted: Takk for at du godtok dei nye bidragsytervilkårene! terms declined: Me beklagar at du har vedteke å ikkje akseptere dei nye bidragsytervilkårene. For meir informasjon, sjå denne wiki-sida . @@ -1433,24 +1638,27 @@ nn: heading: Brukaren %{user} finst ikkje body: Det er ingen brukar med namnet %{user}. Sjekk om du har skrive namnet feil eller om lenkja du klikket er feil. + deleted: sletta view: - my diary: mi dagbok + my diary: Mi dagbok new diary entry: ny dagbokoppføring - my edits: redigeringane mine - my traces: spora mine - my notes: mine kartnotisar - my settings: innstellingane mine - my comments: mine kommentarar - oauth settings: oauth-innstellingar - blocks on me: blokkeringane mine + my edits: Mine endringar + my traces: Mine spor + my notes: Mine merknadar + my messages: Mine meldingar + my profile: Min profil + my settings: Mine innstillingar + my comments: Mine kommentarar + oauth settings: oauth-innstillingar + blocks on me: Mine blokeringar blocks by me: blokkeringar utført av meg - send message: send melding - diary: dagbok - edits: redigeringar - traces: spor - notes: kartnotisar - remove as friend: fjern ven - add as friend: legg til ven + send message: Send melding + diary: Dagbok + edits: Endringar + traces: Spor + notes: Kartmerknadar + remove as friend: Fjern ven + add as friend: Legg til ven mapper since: 'Brukar sidan:' ago: (%{time_in_words_ago} sidan) ct status: 'Bidragsytarvilkår:' @@ -1465,7 +1673,7 @@ nn: description: Skildring user location: Posisjonen til brukaren if set location: Set heimeposisjonen på di %{settings_link}-sida for å sjå naboar. - settings_link_text: innstellingar + settings_link_text: innstillingar your friends: Venene dine no friends: Du har ikkje lagt til nokon venner enno. km away: '%{count}km unna' @@ -1482,16 +1690,16 @@ nn: revoke: administrator: Fjern administrator-tilgjenge moderator: fjern moderator-tilgjenge - block_history: mottekne blokkeringar - moderator_history: tildelte blokkeringar - comments: kommentarar - create_block: blokkar denne brukaren - activate_user: aktiver denne brukaren - deactivate_user: deaktiver denne brukaren - confirm_user: stadfest denne brukaren - hide_user: skjul denne brukaren - unhide_user: stopp å skjule denne brukaren - delete_user: slett denne brukaren + block_history: Aktive blokeringar + moderator_history: Tildelte blokkeringar + comments: Kommentarar + create_block: Blokér denne brukaren + activate_user: Aktivér denne brukaren + deactivate_user: Deaktivér denne brukaren + confirm_user: Stadfest denne brukaren + hide_user: Gøym denne brukaren + unhide_user: Gøym ikkje lenger denne brukaren + delete_user: Slett denne brukaren confirm: Stadfest friends_changesets: endringssett av vener friends_diaries: dagbokoppføringar av vener @@ -1538,8 +1746,8 @@ nn: offentleg eigedom (Public Domain). link: http://www.osmfoundation.org/wiki/License/Contributor_Terms link text: kva er dette? - profile description: 'Profilbeskrivelse:' - preferred languages: 'Foretrukne språk:' + profile description: 'Profilskildring:' + preferred languages: 'Føretrekte språk:' preferred editor: Foretrukket redigeringsverktøy image: 'Bilete:' gravatar: @@ -1555,7 +1763,7 @@ nn: no home location: Du har ikkje skrive inn din heimelokasjon. latitude: 'Breiddegrad:' longitude: 'Lengdegrad:' - update home location on click: Oppdater hjemmelokasjon når eg klikkar på kartet? + update home location on click: Oppdatere heimeplassering når eg klikkar på kartet? save changes button: Lagre endringar make edits public button: Gjer alle redigeringane mine offentleg return to profile: Returner til profil @@ -1563,7 +1771,8 @@ nn: din for å stadfeste din epostadresse. flash update success: Brukerinformasjon oppdatert. confirm: - heading: Stadfest ein brukerkonto + heading: Sjekk e-posten din! + introduction_1: Vi har sendt deg ei e-poststadfesting. press confirm button: Klikk bekreftknappen nedanfor for å aktivare kontoen din. button: Stadfest success: Kontoen din er stadfesta - takk for at du registrerte deg. @@ -1621,6 +1830,8 @@ nn:

    Denne avgjerda vil gjennomgåast av ein administrator snart, eller du kan kontakte %{webmaster} viss du ynskjer å diskutere dette. + auth_failure: + invalid_scope: Ugyldig avgrensning user_role: filter: not_an_administrator: Berre administratorar kan forandre rollar, og du er ikkje @@ -1691,7 +1902,7 @@ nn: success: Blokkering oppdatert. index: title: Brukerblokkeringer - heading: Liste over brukerblokkeringer + heading: Liste over brukarblokkeringar empty: Ingen blokkeringar har vorte utførde enno. revoke: title: Tilbakekaller blokkering på %{block_on} @@ -1735,6 +1946,8 @@ nn: heading: '%{block_on} blokkert av %{block_by}' time_future: Sluttar om %{time} time_past: Slutta %{time} sidan + created: Oppretta + ago: '%{time} sidan' status: Status show: Vis edit: Rediger @@ -1744,21 +1957,102 @@ nn: back: Vis alle blokkeringar revoker: 'Tilbakekaller:' needs_view: Brukaren må logge inn før denne blokkeringa vert fjerna. + note: + description: + opened_at_html: Oppretta for %{when} sidan + opened_at_by_html: Oppretta for %{when} sidan av %{user} + commented_at_html: Oppdatert for %{when} sidan + commented_at_by_html: Oppdatert for %{when} sidan av %{user} + closed_at_html: Løyst for %{when} sidan + closed_at_by_html: Løyst for %{when} sidan av %{user} + entry: + comment: Kommentar + full: Fullstendig merknad + mine: + id: ID + creator: Skapar + description: Skildring + created_at: Oppretta den + last_changed: Sist endra + ago_html: '%{when} sidan' javascripts: + close: Lat att + share: + title: Del + cancel: Avbryt + image: Bilde + link: Lenkje eller HTML + long_link: Lenkje + short_link: Kortlenkje + geo_uri: Geo-URI + embed: HTML + format: 'Format:' + scale: 'Skala:' + download: Last ned + short_url: Kort-URL + include_marker: Inkluder markør + view_larger_map: Vis større kart + key: + title: Kartsymbol + tooltip: Kartsymbol map: + zoom: + in: Vis større + out: Vis mindre base: standard: Standard cycle_map: Sykkelkart transport_map: Transport-kart + hot: Humanitært + layers: + header: Kartlag + notes: Kartmerknadar + data: Kartdata + title: Lag site: edit_tooltip: Rediger kartet edit_disabled_tooltip: Zoom inn for å redigere kartet + changesets: + show: + comment: Kommentar + subscribe: Abonnér + unsubscribe: Avslutt abonnement + hide_comment: gøym + notes: + new: + add: Legg til merknad + show: + hide: Gøym + resolve: Løys + comment: Kommenter directions: engines: graphhopper_bicycle: Sykkel (GraphHopper) + graphhopper_car: Bil (GraphHopper) graphhopper_foot: Til fots (GraphHopper) mapquest_bicycle: Sykkel (MapQuest) + mapquest_car: Bil (MapQuest) mapquest_foot: Til fots (MapQuest) + osrm_car: Bil (OSRM) + mapzen_bicycle: Sykkel (Mapzen) + mapzen_car: Bil (Mapzen) + mapzen_foot: Til fots (Mapzen) + descend: Fallande + distance: Avstand + instructions: + sharp_left_without_exit: Skarp venstresving inn på %{name} + turn_left_without_exit: Ta til venstre inn på %{name} + offramp_left_without_exit: Ta rampen til venstre til %{name} + via_point_without_exit: (via punkt) + follow_without_exit: Følg %{name} + roundabout_without_exit: Ved rundkøyringa, ta til %{name} + unnamed: namnlaus veg + time: Tid + query: + node: Node + way: Veg + context: + show_address: Vis adresse redaction: edit: description: Skildring diff --git a/config/locales/oc.yml b/config/locales/oc.yml index bc0c4e9bc..692d072be 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -3,6 +3,7 @@ # Export driver: phpyaml # Author: Cedric31 # Author: Macofe +# Author: OpenStreetMap-oc --- oc: time: @@ -381,7 +382,6 @@ oc: search: title: latlon: Resultats intèrnes - us_postcode: Resultats dempuèi Geocoder.us uk_postcode: Resultats dempuèi NPEMap / FreeThe Postcode ca_postcode: Resultats dempuèi Geocoder.CA @@ -753,7 +753,7 @@ oc: sea: Mar state: Estat / província subdivision: Subdivision - suburb: Barri + suburb: Quartier town: Vila unincorporated_area: Luòc pas organizat village: Vilatge @@ -948,7 +948,7 @@ oc: intro_2_create_account: Creatz un compte d'utilizaire partners_html: L'albergament es pres en carga per %{ucl}, %{ic} e %{bytemark}, e d'autres %{partners}. - partners_ucl: lo VR Centre de l'UCL + partners_ucl: UCL partners_ic: lo Collègi Imperial de Londres partners_bytemark: Albergament Bytemark partners_partners: partenaris @@ -1117,6 +1117,7 @@ oc: footer_html: Tanben podètz legir lo messatge a %{readurl} e i podètz respondre a %{replyurl} friend_notification: + hi: Bonjorn %{to_user}, subject: '[OpenStreetMap] %{user} vos a apondut coma amic' had_added_you: '%{user} vos a apondut coma amic dins OpenStreetMap.' see_their_profile: 'Podètz veire son perfil aicí : %{userurl}.' @@ -1261,6 +1262,7 @@ oc: date: Data reply_button: Respondre unread_button: Marcar coma pas legit + delete_button: Suprimir back: Retorn to: A wrong_user: Sètz identificat(-ada) coma « %{user} » mas lo messatge qu'ensajatz @@ -2077,8 +2079,10 @@ oc: comment_and_resolve: Comentar e resòlvre comment: Comentari directions: + ascend: Creissent engines: graphhopper_bicycle: A bicicleta (GraphHopper) + graphhopper_car: En veitura (GraphHopper) graphhopper_foot: A pè (GraphHopper) mapquest_bicycle: A bicicleta (MapQuest) mapquest_car: En veitura (MapQuest) @@ -2087,6 +2091,7 @@ oc: mapzen_bicycle: A bicicleta (Mapzen) mapzen_car: En veitura (Mapzen) mapzen_foot: A pè (Mapzen) + descend: Descreissent directions: Itineraris distance: Distància errors: diff --git a/config/locales/pl.yml b/config/locales/pl.yml index e8d56049c..9c9dee5cd 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -427,7 +427,6 @@ pl: search: title: latlon: Wyniki z Internal - us_postcode: Wyniki z Geocoder.us uk_postcode: Wyniki z NPEMap / FreeThe Postcode ca_postcode: Wyniki z Geocoder.CA @@ -593,7 +592,7 @@ pl: ford: Bród living_street: Strefa zamieszkania (znak D-40) milestone: Słupek pikietażowy - motorway: autostrada + motorway: Autostrada motorway_junction: Węzeł autostradowy motorway_link: Autostrada - dojazd path: Ścieżka @@ -983,7 +982,7 @@ pl: sign_up_tooltip: Załóż konto, aby edytować edit: Edycja history: Zmiany - export: Eksportowanie + export: Eksport data: Dane export_data: Eksportuj dane gps_traces: Ślady GPS @@ -997,7 +996,7 @@ pl: i z możliwością użycia pod otwartą licencją. intro_2_create_account: Utwórz konto partners_html: Hosting obsługuje %{ucl}, %{ic}, %{bytemark}, a także inni %{partners}. - partners_ucl: centrum UCL VR + partners_ucl: University College London partners_ic: Imperial College London partners_bytemark: Hosting Bytemark partners_partners: partnerzy @@ -1063,9 +1062,8 @@ pl: title: Przykład uznania autorstwa more_title_html: Dowiedz się więcej more_1_html: |- - Dowiedz się więcej o korzystaniu z naszych danych i o tym, jak określić nas jako źródło z którego pochodzą dane na stronie OSMF License i stronie odpowiedzi na pytania prawne. + Dowiedz się więcej o korzystaniu z naszych danych i o tym, jak określić nas jako źródło, z którego pochodzą dane na stronie OSMF License. more_2_html: Chociaż dane OpenStreetMap są otwarte, nie jesteśmy w stanie zapewnić nieograniczonego dostępu do naszego API wszystkim chętnym. Zapoznaj się z naszą Polityką @@ -1341,7 +1339,7 @@ pl: subject_other: '[OpenStreetMap] %{commenter} rozwiązał interesującą Cię uwagę' your_note: '%{commenter} rozwiązał jedną z Twoich uwag na mapie w lokalizacji: %{place}.' - commented_note: 'Użytkonik %{commenter} rozwiązał skomentowaną uwagę. Znajduje + commented_note: 'Użytkownik %{commenter} rozwiązał skomentowaną uwagę. Znajduje się ona w położeniu: %{place}.' reopened: subject_own: '[OpenStreetMap] %{commenter} ponownie aktywował jedną z Twoich @@ -1436,6 +1434,7 @@ pl: date: Nadano reply_button: Odpowiedz unread_button: Oznacz jako nieprzeczytaną + delete_button: Usuń back: Cofnij to: Do wrong_user: Jesteś zalogowany jako „%{user}”, ale wiadomość, którą chcesz przeczytać, @@ -2405,6 +2404,7 @@ pl: ascend: W górę engines: graphhopper_bicycle: Rower (GraphHopper) + graphhopper_car: Samochód (GraphHopper) graphhopper_foot: Pieszo (GraphHopper) mapquest_bicycle: Rower (MapQuest) mapquest_car: Samochód (MapQuest) diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 48683c238..f413704a0 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -36,6 +36,7 @@ # Author: Vitalb # Author: Walesson # Author: Wille +# Author: Willemarcel # Author: 555 --- pt-BR: @@ -51,7 +52,7 @@ pt-BR: changeset_tag: Etiqueta do conjunto de alterações country: País diary_comment: Comentário do diário - diary_entry: Entrada do diário + diary_entry: Publicação do diário friend: Amigo language: Idioma message: Mensagem @@ -291,22 +292,22 @@ pt-BR: full: Discussão completa diary_entry: new: - title: Nova Entrada de Diário + title: Nova Publicação no Diário publish_button: Publicar list: title: Diários dos Usuários title_friends: Diários dos amigos title_nearby: Diários dos usuários próximos user_title: Diário de %{user} - in_language_title: Entradas de Diário em %{language} - new: Nova Entrada no Diário - new_title: Escrever nova entrada em seu diário - no_entries: Sem entradas no diário - recent_entries: Entradas recentes do diário - older_entries: Entradas mais antigas - newer_entries: Entradas mais novas + in_language_title: Publicações de Diário em %{language} + new: Nova Publicação no Diário + new_title: Escrever nova publicação em seu diário + no_entries: Sem publicações no diário + recent_entries: Publicações recentes no diário + older_entries: Publicações mais antigas + newer_entries: Publicações mais novas edit: - title: Editar entrada do diário + title: Editar publicação no diário subject: 'Assunto:' body: 'Texto:' language: 'Idioma:' @@ -315,7 +316,7 @@ pt-BR: longitude: 'Longitude:' use_map_link: usar mapa save_button: Salvar - marker_text: Localização da entrada no diário + marker_text: Localização da publicação no diário view: title: Diário de %{user} | %{title} user_title: Diário de %{user} @@ -324,20 +325,20 @@ pt-BR: login: Entrar save_button: Salvar no_such_entry: - title: Entrada de diário inexistente - heading: 'Não há entrada no diário com o id: %{id}' - body: Não há entrada no diário ou comentário com o id %{id}. Confira a digitação, + title: Publicação de diário inexistente + heading: 'Não há postagens no diário com o id: %{id}' + body: Não há postagens no diário ou comentário com o id %{id}. Confira a digitação, ou talvez o link clicado esteja errado. diary_entry: posted_by: Publicado por %{link_user} em %{created} em %{language_link} - comment_link: Comentar nesta entrada - reply_link: Responder esta entrada + comment_link: Comentar nesta publicação + reply_link: Responder esta publicação comment_count: one: '%{count} comentário' zero: Nenhum comentário other: '%{count} comentários' - edit_link: Editar esta entrada - hide_link: Ocultar essa entrada + edit_link: Editar esta postagem + hide_link: Ocultar essa postagem confirm: Confirmar diary_comment: comment_from: Comentário de %{link_user} em %{comment_created_at} @@ -349,16 +350,17 @@ pt-BR: edit: Editar feed: user: - title: Entradas do diário do OpenStreetMap de %{user} - description: Entradas recentes no diário do OpenStreetMap de %{user} + title: Publicações do diário do OpenStreetMap de %{user} + description: Publicações recentes no diário do OpenStreetMap de %{user} language: - title: Entradas no diário do OpenStreetMap em %{language_name} - description: Entradas de diário recentes de usuários do OpenStreetMap em %{language_name} + title: Publicações no diário do OpenStreetMap em %{language_name} + description: Publicações de diário recentes de usuários do OpenStreetMap em + %{language_name} all: - title: Entradas no diário do OpenStreetMap - description: Entradas no diário recentes de usuários do OpenStreetMap + title: Publicações no diário do OpenStreetMap + description: Publicações no diário recentes de usuários do OpenStreetMap comments: - has_commented_on: '%{display_name} comentou nestas entradas de diário' + has_commented_on: '%{display_name} comentou nestas postagens de diário' post: Publicar when: Quando comment: Comentário @@ -417,7 +419,6 @@ pt-BR: search: title: latlon: Resultados Internos - us_postcode: Resultados do Geocoder.us uk_postcode: Resultados do NPEMap / FreeThe Postcode ca_postcode: Resultados do Geocoder.CA @@ -469,7 +470,7 @@ pt-BR: cinema: Cinema clinic: Clínica médica clock: Relógio - college: Faculdade + college: Escola Técnica community_centre: Centro/Clube Comunitário courthouse: Fórum Jurídico crematorium: Crematório @@ -977,7 +978,7 @@ pt-BR: data: Dados export_data: Exportar Dados gps_traces: Trilhas GPS - gps_traces_tooltip: Gerenciar trilhas GPS + gps_traces_tooltip: Gerenciar trilhas de GPS user_diaries: Diários de Usuário user_diaries_tooltip: Ver os diários dos usuários edit_with: Edite com %{editor} @@ -986,9 +987,9 @@ pt-BR: intro_text: O OpenStreetMap é um mapa do mundo, criado por pessoas como você e de uso livre sob uma licença aberta. intro_2_create_account: Criar uma conta de usuário - partners_html: A hospedagem é apoiada por %{ucl}, %{ic}, %{bytemark}, e outros + partners_html: A hospedagem é apoiada por %{ucl}, %{bytemark}, %{ic}, e outros %{partners}. - partners_ucl: UCL VR Centre + partners_ucl: UCL partners_ic: Imperial College de Londres partners_bytemark: Hospedagem Bytemark partners_partners: parceiros @@ -1058,9 +1059,8 @@ pt-BR: title: Exemplo de atribuição more_title_html: Descobrir mais more_1_html: |- - Leia mais sobre o uso de nossos dados, e sobre como nos dar crédito, em Legal - FAQ. + Leia mais sobre o uso de nossos dados e sobre como nos creditar, no Página de licença do OSMF. more_2_html: |- Embora o OpenStreetMap seja aberto, não podemos fornecer API de mapa gratuito para terceiros. @@ -1268,8 +1268,8 @@ pt-BR: diary_comment_notification: subject: '[OpenStreetMap] %{user} comentou em uma entrada do diário' hi: Olá %{to_user}, - header: '%{from_user} comentou na entrada do diário do OpenStreetMap com o assunto - %{subject}:' + header: '%{from_user} comentou na publicação do diário do OpenStreetMap com + o assunto %{subject}:' footer: Você pode ler o comentário em %{readurl}, pode comentá-lo em %{commenturl} ou respondê-lo em %{replyurl} message_notification: @@ -1446,6 +1446,7 @@ pt-BR: date: Data reply_button: Responder unread_button: Marcar como não lida + delete_button: Deletar back: Voltar to: Para wrong_user: Você está conectado como `%{user}' mas a mensagem que você quer @@ -1733,7 +1734,7 @@ pt-BR: allow_write_diary: criar entradas de diário, comentários e adicionar amigos. allow_write_api: modificar o mapa. allow_read_gpx: ler suas trilhas de GPS privadas - allow_write_gpx: atualizar trilhas de GPS. + allow_write_gpx: enviar trilhas de GPS. allow_write_notes: alterar notas. grant_access: Dar acesso oauthorize_success: @@ -1799,7 +1800,7 @@ pt-BR: allow_write_prefs: modificar as preferências de usuário dele. allow_write_diary: criar entradas de diário, comentários e adicionar amigos. allow_write_api: modificar o mapa. - allow_read_gpx: ler trilhas de GPS privadas dele. + allow_read_gpx: ler trilhas de GPS privadas deles. allow_write_gpx: enviar trilhas de GPS allow_write_notes: alterar notas. not_found: @@ -1952,7 +1953,7 @@ pt-BR: deleted: excluído view: my diary: Meu Diário - new diary entry: nova entrada de diário + new diary entry: nova publicação no diário my edits: Minhas Edições my traces: Minhas trilhas my notes: Minhas Notas de Mapa @@ -2013,9 +2014,9 @@ pt-BR: delete_user: Excluir este Usuário confirm: Confirmar friends_changesets: conjuntos de alterações dos amigos - friends_diaries: entradas de diário dos amigos + friends_diaries: publicações no diário dos amigos nearby_changesets: conjuntos de alterações de usuários próximos - nearby_diaries: entradas de diário dos usuários próximos + nearby_diaries: publicações no diário dos usuários próximos popup: your location: Sua localização nearby mapper: Mapeador próximo @@ -2366,7 +2367,7 @@ pt-BR: header: Camadas do Mapa notes: Notas de Mapa data: Dados do Mapa - gps: Rastreios públicos de GPS + gps: Trlhas de GPS públicas overlays: Ativar sobreposições para solucionar problemas do mapa title: Camadas copyright: © contribuidores do OpenStreetMap @@ -2382,7 +2383,7 @@ pt-BR: queryfeature_disabled_tooltip: Aproxime para consultar elementos changesets: show: - comment: Comentário + comment: Comentar subscribe: Inscrever unsubscribe: Cancelar inscrição hide_comment: esconder @@ -2408,6 +2409,7 @@ pt-BR: ascend: Ascender engines: graphhopper_bicycle: Bicicleta (GraphHopper) + graphhopper_car: Carro (GraphHopper) graphhopper_foot: Pedestre (GraphHopper) mapquest_bicycle: Bicicleta (MapQuest) mapquest_car: Carro (MapQuest) diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 8aaf8bc13..e81c4ae1d 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -404,7 +404,6 @@ pt-PT: search: title: latlon: Resultados Internos - us_postcode: Resultados de Geocoder.us uk_postcode: Resultados de NPEMap / FreeThe Postcode ca_postcode: Resultados de Geocoder.CA @@ -971,7 +970,7 @@ pt-PT: intro_2_create_account: Crie uma conta de utilizador partners_html: O alojamento é suportado por %{ucl}, %{ic}, %{bytemark} e outros %{partners}. - partners_ucl: UCL VR Centre + partners_ucl: UCL partners_ic: Imperial College London partners_bytemark: Bytemark Hosting partners_partners: parceiros @@ -1047,9 +1046,9 @@ pt-PT: href="http://wiki.openstreetmap.org/wiki/Legal_FAQ">Perguntas frequentes - Legais (em inglês). more_2_html: Apesar do OpenStreetMap ser uma plataforma de dados abertos, não podemos fornecer a terceiros uma API de mapas, livre de encargos. Veja a Política de Utilização - da API, Política - de Utilização de Telas e Política + href="https://operations.osmfoundation.org/policies/api/">Política de Utilização + da API, Política + de Utilização de Telas e Política de Utilização do Nominatim. contributors_title_html: Os nossos contribuidores contributors_intro_html: 'Os contribuidores do OpenStreetMap são milhares. Também @@ -1260,6 +1259,7 @@ pt-PT: assunto %{subject}:' footer_html: Também pode ler a mensagem em %{readurl} e pode responder em %{replyurl} friend_notification: + hi: Olá %{to_user}, subject: '[OpenStreetMap] %{user} adicionou-o como amigo' had_added_you: '%{user} adicionou-o como amigo no OpenStreetMap.' see_their_profile: Pode ver o perfil do editor em %{userurl}. @@ -1348,6 +1348,7 @@ pt-PT: O erro encontra-se perto de %{place}.' details: Ver mais detalhes sobre o erro reportado em %{url}. changeset_comment_notification: + hi: Olá %{to_user}, greeting: Olá, commented: subject_own: '[OpenStreetMap] %{commenter} comentou uma das suas edições' @@ -1360,6 +1361,8 @@ pt-PT: partial_changeset_with_comment: com o comentário '%{changeset_comment}' partial_changeset_without_comment: sem comentários details: Pode encontrar mais informações sobre a edição em %{url}. + unsubscribe: Para deixar de seguir as atualizações deste conjunto de alterações, + aceda a %{url} e clique em "Anular subscrição". message: inbox: title: Caixa de Entrada @@ -1422,6 +1425,7 @@ pt-PT: date: Data reply_button: Responder unread_button: Marcar como não lida + delete_button: Eliminar back: Voltar to: Para wrong_user: Está autenticado com a conta `%{user}', mas a mensagem que pediu @@ -1490,6 +1494,9 @@ pt-PT: track: Carreiro florestal ou agrícola bridleway: Via para cavaleiros cycleway: Ciclovia + cycleway_national: Ciclovia nacional + cycleway_regional: Ciclovia regional + cycleway_local: Ciclovia local footway: Via pedonal rail: Ferrovia subway: Metropolitano @@ -1542,6 +1549,9 @@ pt-PT: private: Acesso restrito (propriedade privada) destination: Acesso a clientes / fornecedores construction: Estradas em construção + bicycle_shop: Loja de Bicicletas + bicycle_parking: Estacionamento de bicicletas + toilets: Casas de banho richtext_area: edit: Editar preview: Mostrar previsão @@ -1684,6 +1694,8 @@ pt-PT: require_moderator: not_a_moderator: Tem de ser um moderador para poder fazer essa ação. setup_user_auth: + blocked_zero_hour: Tem uma mensagem urgente no site do OpenStreetMap. Tem de + ler a mensagem antes de poder gravar as suas edições. blocked: O seu acesso à API foi bloqueado. Por favor aceda à página web do OpenStreetMap e entre na sua conta para saber mais. need_to_see_terms: O seu acesso à API está temporariamente suspenso. Por favor @@ -1714,6 +1726,8 @@ pt-PT: invalid: O token de autorização não é válido. revoke: flash: Revogou o Token para %{application} + permissions: + missing: Não deu permissão programa para aceder a esta instalação oauth_clients: new: title: Registar um novo programa @@ -1818,6 +1832,9 @@ pt-PT: github: title: Iniciar sessão com GitHub alt: Iniciar sessão com uma conta GitHub + wikipedia: + title: Iniciar sessão através da Wikipédia + alt: Iniciar a sessão com uma conta da Wikipédia yahoo: title: Iniciar sessão com Yahoo alt: Iniciar sessão com OpenID Yahoo @@ -1910,6 +1927,7 @@ pt-PT: heading: O utilizador %{user} não existe body: Não existe nenhum utilizador com o nome %{user}. Verifique se o endereço está correto ou talvez a hiperligação que clicou esteja errada. + deleted: eliminado view: my diary: Meu diário new diary entry: adicionar entrada no meu diário @@ -2024,6 +2042,8 @@ pt-PT: gravatar: gravatar: Usar imagem do site Gravatar link text: o que é isto? + disabled: O Gravatar foi desativado. + enabled: A visualização do seu avatar de Gravatar foi ativada. new image: Adicionar imagem keep image: Manter a imagem atual delete image: Remover a imagem atual @@ -2229,6 +2249,8 @@ pt-PT: helper: time_future: Termina em %{time}. until_login: Ativo até o utilizador entrar na conta. + time_future_and_until_login: Termina em %{time} e após o utilizador entrar na + conta. time_past: Terminou há %{time} atrás. blocks_on: title: Bloqueios em %{name} @@ -2307,6 +2329,7 @@ pt-PT: center_marker: Centrar o mapa no marcador paste_html: Colar HTML para incorporar na página web view_larger_map: Ver mapa maior + only_standard_layer: Apenas a Camada Padrão pode ser exportada como imagem embed: report_problem: Reportar problema key: @@ -2329,6 +2352,7 @@ pt-PT: header: Camadas do Mapa notes: Erros reportados no mapa data: Dados técnicos do mapa + gps: Trilhos GPS Públicos overlays: Ativar sobreposições para solucionar problemas do mapa title: Camadas copyright: © Colaboradores do OpenStreetMap @@ -2370,8 +2394,10 @@ pt-PT: edit_help: Mova o mapa e amplie a localização que pretende editar e depois clique aqui. directions: + ascend: Ascenção engines: graphhopper_bicycle: Bicicleta (GraphHopper) + graphhopper_car: Carro (GraphHopper) graphhopper_foot: A pé (GraphHopper) mapquest_bicycle: Bicicleta (MapQuest) mapquest_car: Carro (MapQuest) @@ -2380,6 +2406,7 @@ pt-PT: mapzen_bicycle: Bicicleta (Mapzen) mapzen_car: Carro (Mapzen) mapzen_foot: A pé (Mapzen) + descend: Descida directions: Direções distance: Distância errors: @@ -2387,12 +2414,38 @@ pt-PT: no_place: Desculpe - não foi possível encontrar esse local. instructions: continue_without_exit: Continuar em %{name} + slight_right_without_exit: Virar ligeiramente à direita para %{name} + offramp_right_without_exit: Seguir a via de acesso à direita para %{name} + onramp_right_without_exit: Virar à direita na via de acesso para %{name} + endofroad_right_without_exit: No fim da estrada, virar à direita para %{name} + merge_right_without_exit: Encostar à via da direita para %{name} + fork_right_without_exit: Na bifurcação virar à direita para %{name} + turn_right_without_exit: Virar à direita para %{name} + sharp_right_without_exit: Curva acentuada à direita para %{name} + uturn_without_exit: Inversão de marcha em %{name} + sharp_left_without_exit: Curva acentuada à esquerda para %{name} + turn_left_without_exit: Virar à esquerda para %{name} + offramp_left_without_exit: Seguir a via de acesso à esquerda para %{name} + onramp_left_without_exit: Virar à esquerda na via de acesso para %{name} + endofroad_left_without_exit: No fim da estrada virar à esquerda para %{name} + merge_left_without_exit: Encostar à via da esquerda para %{name} + fork_left_without_exit: Na bifurcação virar à esquerda para %{name} + slight_left_without_exit: Virar ligeiramente à esquerda para %{name} + via_point_without_exit: (ponto de passagem) follow_without_exit: Seguir %{name} roundabout_without_exit: Na rotunda seguir %{name} leave_roundabout_without_exit: Saia da rotunda - %{name} stay_roundabout_without_exit: Mantenha-se na rotunda - %{name} + start_without_exit: Começar no final de %{name} destination_without_exit: Chegada ao destino + against_oneway_without_exit: Ir em contra-mão em %{name} + end_oneway_without_exit: Fim do sentido único em %{name} roundabout_with_exit: Na rotunda seguir a saída %{exit} para %{name} + turn_left_with_exit: Na rotunda, virar à esquerda para %{name} + slight_left_with_exit: Na rotunda, virar ligeiramente à esquerda para %{name} + turn_right_with_exit: Na rotunda, virar à direita para %{name} + slight_right_with_exit: Na rotunda, virar ligeiramente à direita para %{name} + continue_with_exit: Na rotunda, continuar em frente para %{name} unnamed: sem nome courtesy: Direções fornecidas por %{link} time: Tempo @@ -2403,6 +2456,13 @@ pt-PT: nothing_found: Nenhum elemento encontrado error: 'Erro ao comunicar com %{server}: %{error}' timeout: Tempo limite excedido ao ligar a %{server} + context: + directions_from: Direções a partir daqui + directions_to: Direções para aqui + add_note: Reportar um erro aqui + show_address: Mostrar endereço + query_features: Consular elementos + centre_map: Centrar mapa aqui redaction: edit: description: Descrição diff --git a/config/locales/ro.yml b/config/locales/ro.yml index 59b0271e4..b0ccdde0f 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -367,13 +367,15 @@ ro: search: title: latlon: Rezultate interne - us_postcode: Rezultate de la Geocoder.us uk_postcode: Rezultate de la NPEMap / FreeThe Postcode ca_postcode: Rezultate de la Geocoder.CA osm_nominatim: Rezultate de la OpenStreetMap Nominatim geonames: Rezultate de la GeoNames + osm_nominatim_reverse: Rezultate de la OpenStreetMap + Nominatim + geonames_reverse: Rezultate de la GeoNames search_osm_nominatim: prefix_format: '%{name}' prefix: @@ -721,6 +723,8 @@ ro: food: Alimentară furniture: Mobilier gallery: Galerie + gift: Magazin de cadouri + greengrocer: Piață de zarzavat grocery: Magazin alimentar hairdresser: Coafor hifi: Hi-Fi @@ -730,6 +734,7 @@ ro: laundry: Spălătorie mall: Mall market: Piață + mobile_phone: Magazin de telefoane newsagent: Chioșc de ziare optician: Optician organic: Magazin de alimente organice @@ -772,6 +777,10 @@ ro: waterfall: Cascadă weir: Stăvilar description: + title: + osm_nominatim: Rezultate de la OpenStreetMap + Nominatim + geonames: Rezultate de la GeoNames types: cities: Orașe towns: Orășele @@ -835,7 +844,7 @@ ro: title: Întrebări? start_mapping: Începeți să cartografiați add_a_note: - title:

    Nu aveți timp pentru editare? Adaugați o notiță

    + title:

    Nu aveți timp pentru editare? Adaugați o notă!

    fixthemap: how_to_help: title:

    Cum poți ajuta

    @@ -855,6 +864,8 @@ ro: next: Înainte partners_title: Parteneri notifier: + diary_comment_notification: + hi: Salut %{to_user}, message_notification: hi: Salut, %{to_user}, friend_notification: @@ -922,6 +933,7 @@ ro: edit: user_page_link: pagină de utilizator sidebar: + search_results: Rezultatele căutării close: Închide search: search: Căutare @@ -980,6 +992,8 @@ ro: login: email or username: 'Adresa de e-mail sau numele de utilizator:' password: 'Parolă:' + logout: + heading: Deconectare din OpenStreetMap reset_password: password: 'Parola:' confirm password: 'Confirmați parola:' @@ -1026,6 +1040,9 @@ ro: title: Arată locația mea site: edit_disabled_tooltip: Măriți pentru a edita harta + createnote_tooltip: Adaugă o notă pe hartă context: + directions_from: Direcția de aici + add_note: Adaugă aici o observație show_address: Arată adresa ... diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 7db50d123..82de61841 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -27,6 +27,7 @@ # Author: Facenapalm # Author: FreeExec # Author: G0rn +# Author: Helpau # Author: Ignatus # Author: Iluvatar # Author: Irus @@ -52,6 +53,7 @@ # Author: TarzanASG # Author: Tourorist # Author: WindEwriX +# Author: Wirbel78 # Author: XAN # Author: Yuri Nazarov # Author: Yuryleb @@ -96,7 +98,7 @@ ru: tracetag: Тег маршрута user: Пользователь user_preference: Настройки пользователя - user_token: Маркер пользователя + user_token: Токен пользователя way: Линия way_node: Точка линии way_tag: Тег линии @@ -222,8 +224,8 @@ ru: changeset: пакет правок note: примечание timeout: - sorry: Извините, данные для %{type} с %{id} требуют слишком много времени для - извлечения. + sorry: Извините, данные для %{type} с id %{id} требуют слишком много времени + для извлечения. type: node: точки way: линии @@ -443,7 +445,6 @@ ru: search: title: latlon: Внутренние результаты - us_postcode: Результаты от Geocoder.us uk_postcode: Результаты от NPEMap / FreeThe Postcode ca_postcode: Результаты от Geocoder.CA @@ -924,7 +925,7 @@ ru: alpine_hut: Альпийский домик apartment: Квартира artwork: Произведение искусства - attraction: Аттракцион + attraction: Достопримечательность bed_and_breakfast: Полупансион cabin: Хижина camp_site: Лагерь @@ -1465,6 +1466,7 @@ ru: date: Дата reply_button: Ответить unread_button: Пометить как непрочитанное + delete_button: Удалить back: Назад to: 'Кому:' wrong_user: Вы вошли как пользователь `%{user}', но ответ на ваш вопрос был @@ -1517,7 +1519,7 @@ ru: get_directions_title: Поиск маршрута между двумя точками from: Старт to: Финиш - where_am_i: Где я? + where_am_i: Где это? where_am_i_title: Опишите ваше местоположение, воспользовавшись инструментом поиска submit_text: Найти @@ -2443,6 +2445,7 @@ ru: ascend: По возврастанию engines: graphhopper_bicycle: На велосипеде (GraphHopper) + graphhopper_car: На машине (GraphHopper) graphhopper_foot: Пешком (GraphHopper) mapquest_bicycle: На велосипеде (MapQuest) mapquest_car: На машине (MapQuest) diff --git a/config/locales/scn.yml b/config/locales/scn.yml index 695d3d29f..60573e3fc 100644 --- a/config/locales/scn.yml +++ b/config/locales/scn.yml @@ -382,7 +382,6 @@ scn: search: title: latlon: Risurtati di Nternu - us_postcode: Risurtati di Geocoder.us uk_postcode: Risurtati di NPEMap / FreeThe Postcode ca_postcode: Risurtati di Geocoder.CA diff --git a/config/locales/sco.yml b/config/locales/sco.yml index d5f25c36f..3fe4afd0e 100644 --- a/config/locales/sco.yml +++ b/config/locales/sco.yml @@ -364,7 +364,6 @@ sco: search: title: latlon: Results frae Internal - us_postcode: Results frae Geocoder.us uk_postcode: Results frae NPEMap / FreeThe Postcode ca_postcode: Results frae Geocoder.CA diff --git a/config/locales/sk.yml b/config/locales/sk.yml index d011e15d6..6c519622b 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -372,7 +372,6 @@ sk: search: title: latlon: Výsledky z internej databázy - us_postcode: Výsledky z Geocoder.us uk_postcode: Výsledky z NPEMap / FreeThe Postcode ca_postcode: Výsledky z Geocoder.CA diff --git a/config/locales/sl.yml b/config/locales/sl.yml index d10bef047..54764414d 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -4,6 +4,7 @@ # Author: Damjang # Author: Dbc334 # Author: Eleassar +# Author: HairyFotr # Author: Lesko987 # Author: Macofe # Author: Mateju @@ -388,7 +389,6 @@ sl: search: title: latlon: Interni zadetki - us_postcode: Zadetki iz Geocoder.us uk_postcode: Zadetki iz NPEMap / FreeThe Postcode ca_postcode: Zadetki iz Geocoder.CA @@ -407,7 +407,7 @@ sl: gondola: Kabinska žičnica station: ŽičniÅ¡ka postaja aeroway: - aerodrome: Aerodrom + aerodrome: Letališče apron: LetaliÅ¡ka ploščad gate: Vrata helipad: Heliodrom @@ -557,7 +557,7 @@ sl: motorway_junction: Avtocestno križišče motorway_link: Avtocestni priključek path: Pot - pedestrian: Ulica namenjena peÅ¡cem + pedestrian: Ulica, namenjena peÅ¡cem platform: Platforma primary: Glavna cesta primary_link: Priključek na glavno cesto @@ -621,7 +621,7 @@ sl: construction: Gradbišče farm: Kmetija farmland: Kmetijsko zemljišče - farmyard: Vrt + farmyard: Kmetija forest: Gozd garages: Garaže grass: Trata @@ -952,8 +952,8 @@ sl: intro_text: OpenStreetMap je zemljevid sveta, ki ga ustvarjajo ljudje kot ste vi, brezplačen za uporabo z odprto licenco. intro_2_create_account: Ustvarite uporabniÅ¡ki račun - partners_html: Gostovanje podpira %{ucl}, %{ic} in %{bytemark}, ter ostali %{partners}. - partners_ucl: Center UCL VR + partners_html: Gostovanje podpira %{ucl}, %{bytemark} in %{ic}, ter ostali %{partners}. + partners_ucl: UCL partners_ic: Imperial College v Londonu partners_bytemark: Bytemark Hosting partners_partners: partnerji @@ -998,6 +998,9 @@ sl: Slovenija: Vsebuje javne podatke Geodetske uprave Republike Slovenije in Ministrstva za kmetijstvo, gozdarstvo in prehrano. + contributors_footer_1_html: |- + Za več podrobnosti o teh in drugih virih, ki so bili uporabljeni kot pripomočki pri izboljÅ¡evanju OpenStreetMap, si prosimo oglejte stran sodelujočih na wikiju OpenStreetMap. infringement_title_html: KrÅ¡itev avtorskih pravic welcome_page: title: DobrodoÅ¡li! @@ -1066,7 +1069,16 @@ sl: url: https://help.openstreetmap.org/ description: Zastavite vpraÅ¡anje ali poiščete odgovore v OSM zbirki vpraÅ¡anj in odgovorov. + mailing_lists: + title: PoÅ¡tni seznami + forums: + title: Forumi + irc: + title: IRC + description: Interaktivni klepet v mnogo različnih jezikih in o mnogo temah. wiki: + url: http://wiki.openstreetmap.org/ + title: wiki.openstreetmap.org description: Prebrskajte wiki za poglobljeno OSM dokumentacijo. about_page: next: Naslednji @@ -1075,10 +1087,10 @@ sl: partners_title: Partnerji notifier: diary_comment_notification: - subject: '[OpenStreetMap] %{user} je komentiral vaÅ¡ vnos v dnevnik' + subject: '[OpenStreetMap] %{user} je komentiral vnos v dnevnik' hi: Pozdravljen, %{to_user}! - header: '%{from_user} je komentiral vaÅ¡ nedavni vnos v OpenStreetMap dnevnik - z naslovom %{subject}:' + header: '%{from_user} je komentiral vnos v dnevnik OpenStreetMap z naslovom + %{subject}:' footer: Komentar lahko preberete tudi na %{readurl}, komentirate lahko na %{commenturl} ali odgovorite na %{replyurl} message_notification: @@ -1256,6 +1268,7 @@ sl: date: Datum reply_button: Odgovori unread_button: Označi kot neprebrano + delete_button: IzbriÅ¡i back: Nazaj to: Za wrong_user: Prijavljeni ste kot '%{user}', ampak sporočilo, ko ga \elite prebrati @@ -1307,7 +1320,7 @@ sl: get_directions_title: Navodila za pot med dvema točkama from: Od to: Do - where_am_i: Kje sem? + where_am_i: Kje je to? where_am_i_title: OpiÅ¡ite trenutno lokacijo z uporabo iskalnika submit_text: Išči key: @@ -1451,7 +1464,7 @@ sl: view: title: Prikaz sledi %{name} heading: Prikaz sledi %{name} - pending: ČAKAJOČA + pending: V ČAKALNI VRSTI filename: 'Datoteka:' download: prenos uploaded: 'Poslano:' @@ -1472,7 +1485,7 @@ sl: older: StarejÅ¡e sledi newer: NovejÅ¡e sledi trace: - pending: ČAKAJOČA + pending: V ČAKALNI VRSTI count_points: '%{count} točk' ago: '%{time_in_words_ago} nazaj' more: več @@ -1540,8 +1553,10 @@ sl: allow_read_gpx: branje zasebnih sledi GPS. allow_write_gpx: nalaganje sledi GPS. allow_write_notes: spreminjanje opomb. + grant_access: Odobri dostop oauthorize_success: title: Zahteva za overovitev uspeÅ¡na + allowed: Aplikaciji %{app_name} ste odobrili zahtevek za dostop do vaÅ¡ega računa. verification: Koda za preverjanje je %{code}. oauthorize_failure: title: Zahteva za overovitev ni uspela @@ -1848,6 +1863,7 @@ sl: gravatar: gravatar: Uporabi Gravatar link text: Kaj je to? + disabled: Gravatar je onemogočen. new image: Dodaj sliko keep image: Obdrži trenutno sliko delete image: Odstrani trenutno sliko diff --git a/config/locales/sq.yml b/config/locales/sq.yml index d1f70234a..53d3639c0 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -399,7 +399,6 @@ sq: search: title: latlon: Rezultatet e brendshme nga - us_postcode: Rezultatet nga Geocoder.us uk_postcode: Rezultatet nga NPEMap / FreeThe Postcode ca_postcode: Rezultatet nga Geocoder.ca diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index c2267a4e6..192b53287 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -270,7 +270,6 @@ sr-Latn: search: title: latlon: Rezultati iz Internala - us_postcode: Rezultati iz Geokodera uk_postcode: Rezultati iz NPEMap-a ca_postcode: Rezultati iz Geokodera osm_nominatim: Rezultati iz Nominatima diff --git a/config/locales/sr.yml b/config/locales/sr.yml index d5fcfa084..ba3d58d7f 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -8,6 +8,7 @@ # Author: Nemo bis # Author: Nikola Smolenski # Author: Obsuser +# Author: Prevodim # Author: Rancher # Author: Sawa # Author: Srdjan m @@ -386,7 +387,6 @@ sr: search: title: latlon: Унутрашњи резултати - us_postcode: Резултати са сајта Geocoder.us uk_postcode: Резултати са сајта NPEMap/FreeThe Postcode ca_postcode: Резултати са сајта Geocoder.ca @@ -1031,10 +1031,10 @@ sr: href="http://wiki.openstreetmap.org/wiki/Legal_FAQ">честим правним питањима. more_2_html: |- Иако OpenStreetMap ради с отвореним подацима, не можемо - понудити бесплатан АПИ за мапе независним програмерима. - Погледајте правила о употреби АПИ-ја, - правила о употреби поља - и Номинатим. + трећим странама понудити бесплатан API за мапе. + Погледајте правила о употреби API-ја, + правила о употреби поља + и Номинатим. contributors_title_html: Наши сарадници contributors_intro_html: |- У нашем пројекту учествује на хиљаде појединаца. Користимо и @@ -1052,6 +1052,11 @@ sr: ресурсе Канаде), Канвек (© Одељење за природне ресурсе Канаде) и Статкан (Географски одсек, Завод за статистику Канаде). + contributors_fi_html: |- + Финска: Садржи податке са + Топографске базе података Националног геодетског завода Финске + те друге сетове података, под + NLSFI лиценцом. contributors_fr_html: |- Француска: садржи податке који потичу од Генералне дирекције за опорезивање. @@ -1061,6 +1066,11 @@ sr: contributors_nz_html: |- Нови Зеланд: садржи податке који потичу од Land Information New Zealand. Крунска ауторска права задржана. + contributors_si_html: |- + Словенија: Садржи податке са + Ауторитета за истраживање и мапирање те од + Министарства за пољопривреду, шумарство и прехрамбену индустрију + (јавне информације Словеније). contributors_za_html: |- Јужноафричка Република: садржи податке из Главне управе: @@ -1081,6 +1091,17 @@ sr: infringement_1_html: ОСМ сарадници се подсећају да никад не додају податке из извора заштићених ауторским правима (нпр. Гугл карте или штампане карте) без изричите дозволе власника ауторских права. + infringement_2_html: |- + Ако верујете да је материјал заштићен ауторским правима био неприкладно + додат у базу података OpenStreetMap или овај сајт, молимо да пратите + нашу процедуру за + скидање или да се директно обратите на + нашој онлајн страници за пријаве. + trademarks_title_html: Робне марке + trademarks_1_html: OpenStreetMap, лого лупе и State of the Map регистроване + су робне марке Фондације OpenStreetMap. Ако имате питања о томе како да користите + марке, пошаљите своја питања Радној + групи за лиценце. welcome_page: title: Добро дошли! introduction_html: Добродошли на ОпенСтритМап, бесплатну изменљиву карту света. @@ -1105,6 +1126,14 @@ sr: језера или грађевине. tag_html: Ознака је јединица којом се описује тачка или линија, нпр. име ресторана или ограничење брзине на одређеном путу. + rules: + title: Правила! + paragraph_1_html: "OpenStreetMap има мало формалних правила, али очекујемо од + свих учесника да сарађују\nи комуницирају са заједницом. Ако разматрате било + какве\nактивности поред ручног уређивања, прочитајте и пратите смернице о + \nувозу + и \nаутоматизованим + изменама." questions: title: Питања? paragraph_1_html: |- @@ -1142,12 +1171,32 @@ sr: и одговарају на питања, и заједнички расправљају и документују картографске теме. welcome: + url: /welcome title: Добродошли на ОСМ description: Почни са овим брзим водичем који покрива основе ОпенСтритМапа + beginners_guide: + url: http://wiki.openstreetmap.org/wiki/Sr:Beginners%27_guide + title: Водич за почетничке + description: Водич за почетнике help: + url: https://help.openstreetmap.org/ + title: help.openstreetmap.org description: Постави питање или нађи одговор на ОСМ страници за питања и одговоре. + mailing_lists: + title: Дописне листе + description: Поставите питање или дискутујте о питањима од значаја која се тичу + широког спектра тематских или регионалних мејлинг листа. forums: title: Форуми + description: Питања и расправе за оне који преферирају интерфејс у стилу билтен + табле. + irc: + title: IRC + description: Интерактивни разговор на многим језицима и на многе теме. + switch2osm: + title: switch2osm + description: Помоћ за компаније и организације које прелазе на мапе засноване + на OpenStreetMap-у и другим алаткама. wiki: url: http://wiki.openstreetmap.org/wiki/Sr:Main_Page title: wiki.openstreetmap.org/wiki/Sr:Main_Page @@ -1165,13 +1214,34 @@ sr: снимке из ваздуха, GPS уређаје и обичне теренске мапе у циљу провере исправности и ажурности OSM-а. community_driven_title: Заједница је покретач + community_driven_html: "Заједница OpenStreetMap-а је разнолика, страствена и расте + сваког дана. \nНаши сарадници су ентузијстични мапери, професионалци за GIS, + инжењери\nкоји покрећу OSM сервере, хуманитарци који мапирају подручја погођена + катастрофама,\nи још многи други.\nДа бисте сазнали више о заједници, погледајте + корисничке дневнике,\nблогове + заједнице и\nвеб-сајт Фондације + OSM." open_data_title: Отцорени подаци + open_data_html: |- + OpenStreetMap је опен дата: слободно можете да га користите за било коју сврху + све док одате заслуге за OpenStreetMap и оне који на њему доприносе. Ако измените или + правите податке на одређене начине, можете да дистрибуишете резултата само + под истом лиценцом. Погледајте страницу о ауторским правима + и лиценцама за детаље. + legal_title: Правни аспекти + legal_html: "Овим сајтом и многим другим повезаним алаткама формално управља\nФондација OpenStreetMap (OSMF) \nу име + заједнице. Употреба свих алатки којима управља OSMF је предмет \nнаше \nполитике + прихватљиве употребе и наше политике + приватности\n
    \nМолимо да контактирате + OSMF \nако имате правна питања или проблеме око лиценцирања, ауторских права + и сл." partners_title: Партнери notifier: diary_comment_notification: - subject: '%{user} је прокоментарисао ваш дневнички запис' + subject: '%{user} је прокоментарисао дневнички запис' hi: Поздрав, %{to_user}, - header: '%{from_user} је прокоментарисао ваш скорашњи дневнички запис под насловом + header: '%{from_user} је прокоментарисао OpenStreetMap дневнички запис под насловом %{subject}:' footer: Можете прочитати коментаре на %{readurl}, прокоментарисати на %{commenturl} или одговорити на %{replyurl} @@ -1179,7 +1249,10 @@ sr: subject_header: '[Опенстритмап] – %{subject}' hi: Поздрав, %{to_user}, header: '%{from_user} вам посла поруку преко Опенстритмапа под насловом %{subject}:' + footer_html: Такође можете да прочитате поруку на %{readurl} и можете да одговорите + на %{replyurl} friend_notification: + hi: Поздрав, %{to_user}, subject: '[OpenStreetMap] %{user} вас је додао као пријатеља' had_added_you: '%{user} вас је додао као пријатеља на Опенстритмапу.' see_their_profile: Можете видети његов/њен профил на %{userurl}. @@ -1204,6 +1277,11 @@ sr: subject: '[OpenStreetMap] Добро дошли на ОпенСтритМап' greeting: Здраво! created: Неко (надамо се ти) је управо отворио налог на %{site_url}. + confirm: 'Пре него што ишта урадимо, морамо да потврдимо да је овај захтев дошао + од вас, тако да ако заиста јесте молимо да кликнете на везу испод да бисте + потврдили свој налог:' + welcome: Након што потврдите свој налог, пружићемо Вам неке додатне информације + о томе како почети. email_confirm: subject: '[OpenStreetMap] Потврдите Вашу имејл адресу' email_confirm_plain: @@ -1220,6 +1298,8 @@ sr: subject: '[OpenStreetMap] Захтев за поништавање лозинке' lost_password_plain: greeting: Поздрав, + hopefully_you: Неко (вероватно ви) затражио је поништавање лозинке за имејл + адресу овог openstreetmap.org налога. click_the_link: Ако си то ти, кликни на везу испод да поништиш лозинку. lost_password_html: greeting: Поздрав, @@ -1228,10 +1308,48 @@ sr: note_comment_notification: anonymous: Анонимни корисник greeting: Поздрав, + commented: + subject_own: '[OpenStreetMap] %{commenter} је коментарисао на једној од Ваших + белешки' + subject_other: '[OpenStreetMap] %{commenter} је коментарисао на белешци за + коју сте заинтересовани' + your_note: '%{commenter} је оставио коментар на једну од Ваших белешка на + мапама у близини места %{place}.' + commented_note: '%{commenter} је оставио коментар на белешки мапе коју сте + Ви коментарисали. Белешка је у близини места %{place}.' + closed: + subject_own: '[OpenStreetMap] %{commenter} је решио једну од Ваших белешки' + subject_other: '[OpenStreetMap] %{commenter} је решио белешу за коју сте заинтересовани' + your_note: '%{commenter} је решио једну од Ваших белешки на мапи у близини + места %{place}.' + commented_note: '%{commenter} је решио белешку мапе коју сте коментарисали. + Белешка је у близини места %{place}.' + reopened: + subject_own: '[OpenStreetMap] %{commenter} је реактивирао једну од Ваших белешки' + subject_other: '[OpenStreetMap] %{commenter} је реактивирао белешку за коју + сте заинтересовани' + your_note: '%{commenter} је реактивирао једну од Ваших белешки мапе у близини + места %{place}.' + commented_note: '%{commenter} је реактивирао белешку мапе коју сте коментарисали. + Белешка је у близини места %{place}.' + details: Више информација о белешци може да се пронађе на %{url}. changeset_comment_notification: + hi: Поздрав, %{to_user}, greeting: Поздрав, commented: + subject_own: '[OpenStreetMap] %{commenter} је коментарисао о једном од Ваших + чејнџсетова' + subject_other: '[OpenStreetMap] %{commenter} је коментарисао о чејнџсету за + који сте заинтересовани' + your_changeset: '%{commenter} је оставио коментар на једном од Ваших чејнџсетова + направљеном %{time}' + commented_changeset: '%{commenter} је оставио коментар на чејнџсету мапе који + надгледате и који је направио %{changeset_author} у %{time}' + partial_changeset_with_comment: са коментаром ’%{changeset_comment}’ partial_changeset_without_comment: без коментара + details: Више информација о чејнџсетовима може да се пронађе на %{url}. + unsubscribe: Да бисте престали пратити апдејте овог чејнџсета, посетите %{url} + и кликните на „Престани пратити”. message: inbox: title: Примљене @@ -1240,10 +1358,10 @@ sr: messages: Имате %{new_messages} и %{old_messages} new_messages: one: '%{count} нова порука' - other: '%{count} нове поруке' + other: '%{count} нових порука' old_messages: one: '%{count} стара порука' - other: '%{count} старе поруке' + other: '%{count} старих порука' from: Од subject: Наслов date: Датум @@ -1293,6 +1411,7 @@ sr: date: Датум reply_button: Одговори unread_button: Означи као непрочитано + delete_button: Обриши back: Назад to: За wrong_user: Пријављени сте као %{user}, али порука коју сте желели да прочитате @@ -1333,6 +1452,7 @@ sr: potlatch2_not_configured: Потлач 2 није подешен. Погледајте http://wiki.openstreetmap.org/wiki/The_Rails_Port potlatch2_unsaved_changes: Нисте сачували измене. Да бисте то урадили, кликните на дугме за чување. + id_not_configured: iD није конфигурисан no_iframe_support: Ваш прегледач не подржава HTML iframes, а они су потребни за ову могућност. sidebar: @@ -1340,6 +1460,10 @@ sr: close: Затвори search: search: Претрага + get_directions: Тражите упутства + get_directions_title: Пронађите навигацију између две тачке + from: Од + to: До where_am_i: Где сам? where_am_i_title: Установите тренутну локацију помоћу претраживача submit_text: Иди @@ -1355,6 +1479,9 @@ sr: track: Макадам bridleway: Коњичка стаза cycleway: Бициклистичка стаза + cycleway_national: Национална бициклистичка стаза + cycleway_regional: Регионална бициклистичка стаза + cycleway_local: Локална бициклистичка стаза footway: Пешачка стаза rail: Железничка пруга subway: Подземна железница @@ -1407,6 +1534,9 @@ sr: private: Приватни посед destination: Приступ одредишту construction: Путеви у изградњи + bicycle_shop: Продавница бицикала + bicycle_parking: Паркинг за бицикле + toilets: Тоалети richtext_area: edit: Уреди preview: Преглед @@ -1519,6 +1649,7 @@ sr: public_traces: Јавни ГПС трагови your_traces: Ваши ГПС трагови public_traces_from: Јавни GPS трагови корисника %{user} + description: Претражите недавне аплоуде GPS путева tagged_with: ' означени са %{tags}' empty_html: Овде још увек нема ништа. Отпремите нови траг или сазнајте више о GPS траговима на вики @@ -1532,6 +1663,13 @@ sr: offline: heading: GPX остава је ван мреже message: GPX остава и отпремање тренутно нису доступни. + georss: + title: OpenStreetMap GPS трасе + description: + description_with_count: + one: GPX датотека са %{count} тачком од %{user} + other: GPX датотека са %{count} тачака од %{user} + description_without_count: GPX датотека од %{user} application: require_cookies: cookies_needed: Изгледа да сте онемогућили колачиће. Омогућите их пре него што @@ -1539,12 +1677,15 @@ sr: require_moderator: not_a_moderator: Да бисте извели ову радњу, треба да будете модератор. setup_user_auth: + blocked_zero_hour: Имате хитну поруку на веб-сајту OpenStreetMap. Морате прочитати + поруку пре него што могнете спремати своје измене. blocked: Ваш приступ АПИ-ју је блокиран. Пријавите се да сазнате више. need_to_see_terms: Ваш приступ АПИ-ју је привремено укинут. Пријавите се да бисте погледали услове уређивања. Не морате да их прихватите, већ само да их видите. oauth: oauthorize: + title: Ауторизујте приступ свом налогу request_access: Програм %{app_name} захтева приступ вашем налогу, %{user}. Одлучите се да ли желите да му га омогућите. Можете изабрати било који програм. allow_to: 'Дозволи програму да:' @@ -1554,8 +1695,20 @@ sr: allow_write_api: мења мапу. allow_read_gpx: чита ваше приватне GPS трагове. allow_write_gpx: отпрема GPS трагове. + allow_write_notes: измени белешке. + grant_access: Додели приступ + oauthorize_success: + title: Омогућен захтев за ауторизацију + allowed: Омогућили сте да апликација %{app_name} приступи Вашем налогу. + verification: Верификациони код је %{code}. + oauthorize_failure: + title: Неуспешан захтев за ауторизацију + denied: Онемогућили сте да апликација %{app_name} приступи Вашем налогу. + invalid: Токен за ауторизацију није валидан. revoke: flash: Опозвали сте новчић за %{application} + permissions: + missing: Нисте дозволили приступ апликације овом одељењу oauth_clients: new: title: Упиши нови програм @@ -1628,6 +1781,7 @@ sr: login_button: Пријави ме register now: Отворите налог with username: 'Већ имате налог? Пријавите се с корисничким именом и лозинком:' + with external: 'Алтернативно, користите трећу страну да се пријавите:' new to osm: Нови сте на сајту? to make changes: Да бисте правили измене, морате имати налог. create account minute: Отворите налог. Потребно је само неколико тренутака. @@ -1643,8 +1797,31 @@ sr: auth_providers: openid: title: Пријавити се са OpenID + alt: Пријава преко OpenID URL-а + google: + title: Пријава преко Гугла + alt: Пријава преко Google OpenID-а facebook: title: Пријавити се са Facebook-ом + alt: Пријава преко Facebook налога + windowslive: + title: Пријава преко Windows Live-а + alt: Пријава преко Windows Live налога + github: + title: Пријава коришћењем GitHub-а + alt: Пријава коришћењем GitHub налога + wikipedia: + title: Пријава преко Википедије + alt: Пријава коришћењем Википедија налога + yahoo: + title: Пријава преко Јахуа + alt: Пријава преко Yahoo OpenID-а + wordpress: + title: Пријава коришћењем Wordpress-а + alt: Пријава преко Wordpress OpenID-а + aol: + title: Пријава преко AOL-а + alt: Пријава преко AOL OpenID-а logout: title: Одјава heading: Одјава @@ -1672,18 +1849,28 @@ sr: налог. contact_webmaster: Контактирајте администратора за отварање новог налога. Обрадићемо захтев што је пре могуће. + about: + header: Слободно и изменљиво + html: |- +

    За разлику од осталих мапа, OpenStreetMap у потпуности стварају људи као Ви, + и бесплатан је за свакога да поправља, ажурира, преузима и користи.

    +

    Пријавите се да бисте почели да доприносите. Послаћемо Вам имејл за потврду Вашег налога.

    license_agreement: Након што потврдите налог, мораћете да прихватите услове уређивања. email address: 'Имејл адреса:' confirm email address: 'Потврдите имејл адресу:' - not displayed publicly: Не приказује се јавно (погледајте политику - приватности) + not displayed publicly: Ваша адреса се не приказује јавно, погледајте политику + приватности за више информација display name: 'Име приказа:' display name description: Јавно приказано корисничко име. Касније га можете променити у поставкама. + external auth: 'Аутентификација треће стране:' password: 'Лозинка:' confirm password: 'Потврдите лозинку:' + use external auth: Алтернативно, користите трећу страну за пријаву + auth no password: Са аутентификацијом треће стране, лозинка није потребна — + али неки додатни алати или сервер можда је ипак буду захтевали. continue: Отвори налог terms accepted: Хвала вам што прихватате нове услове уређивања. terms declined: Жао нам је што сте одлучили да не прихватите нове услове уређивања. @@ -1715,6 +1902,7 @@ sr: heading: Корисник %{user} не постоји body: Не постоји корисник с именом %{user}. Проверите исправност уписа или везе коју сте кликнули. + deleted: обрисано view: my diary: Мој дневник new diary entry: нови дневнички запис @@ -1828,6 +2016,8 @@ sr: gravatar: gravatar: Користи Граватар link text: шта је ово? + disabled: Граватар је онемогућен. + enabled: Приказ Вашег Граватара је омогућен. new image: Додај слику keep image: Задржи тренутну слику delete image: Уклони тренутну слику @@ -1911,6 +2101,21 @@ sr: Ову одлуку ће убрзо размотрити администратор. Такође, можете контактирати %{webmaster}а ако желите да се жалите.

    + auth_failure: + connection_failed: Повезивање до аутентификационог провајдера неуспешно + invalid_credentials: Невалидни аутентификациони акредитиви + no_authorization_code: Нема кода ауторизације + unknown_signature_algorithm: Непознат потписни алгоритам + invalid_scope: Невалидан опсед + auth_association: + heading: Ваш ID још увек није повезан са налогом OpenStreetMap. + option_1: |- + Ако сте нови у OpenStreetMap, молимо да направите нови налог + коришћењем доњег обрасца. + option_2: |- + Ако већ имате налог, можете да се пријавите на свој налог + коришћењем свог корисничког имена и лозинке, а потом да га повежете + са својим ID-ом у корисничким подешавањима. user_role: filter: not_an_administrator: Само администратори могу да управљају улогама корисника, @@ -2007,6 +2212,7 @@ sr: helper: time_future: Завршава се у %{time}. until_login: Активно све док се корисник не пријави. + time_future_and_until_login: Завршава у %{time} и након што се корисник пријави. time_past: Завршено пре %{time}. blocks_on: title: Блокаде за %{name} @@ -2021,6 +2227,8 @@ sr: heading: '%{block_on} је блокиран/а од %{block_by}' time_future: Завршава се у %{time} time_past: Завршено пре %{time} + created: Направљено + ago: пре %{time} status: Стање show: Прикажи edit: Уреди @@ -2071,6 +2279,7 @@ sr: link: Веза или HTML long_link: Веза short_link: Кратка веза + geo_uri: Geo URI embed: HTML custom_dimensions: Постави посебне димензије format: 'Формат:' @@ -2082,10 +2291,13 @@ sr: center_marker: Центрирај карту на ознаку paste_html: Налепи HTML да га уградиш у веб страницу view_larger_map: Погледај већу карту + only_standard_layer: Само стандардни лејер може да се извезе као слика + embed: + report_problem: Пријави проблем key: title: Легенда tooltip: Легенда карте - tooltip_disabled: Легенда је доступна само за стандардни слој + tooltip_disabled: Легенда није доступна само за овај лејер map: zoom: in: Увећај @@ -2102,6 +2314,7 @@ sr: header: Слојеви карте notes: Белешке на карти data: Подаци карте + gps: Јавне GPS трасе overlays: Омогући преклапање за тражење грешака на карти title: Слојеви copyright: © ОпенСтритМап сарадници @@ -2139,8 +2352,10 @@ sr: comment: Коментариши edit_help: Помери карту и увећај на место које хоћеш да уредиш, затим кликни овде. directions: + ascend: Растуће engines: graphhopper_bicycle: Бициклом (GraphHopper) + graphhopper_car: Ауто (GraphHopper) graphhopper_foot: Пешке (GraphHopper) mapquest_bicycle: Бициклом (MapQuest) mapquest_car: Аутомобилом (MapQuest) @@ -2149,6 +2364,7 @@ sr: mapzen_bicycle: Бициклом (Mapzen) mapzen_car: Аутомобилом (Mapzen) mapzen_foot: Пешке (Mapzen) + descend: Опадајуће directions: Путања distance: Удаљеност errors: @@ -2157,11 +2373,21 @@ sr: instructions: continue_without_exit: Наставите на %{name} slight_right_without_exit: Мало удесно у %{name} + offramp_right_without_exit: Идите на рампу десно, на %{name} + onramp_right_without_exit: Скрените десно на рампи, на %{name} + endofroad_right_without_exit: На крају цесте скрените десно, на %{name} + merge_right_without_exit: Укључите се десно, на %{name} + fork_right_without_exit: На рачвању скрените десно, на %{name} turn_right_without_exit: Скрените десно у %{name} sharp_right_without_exit: Нагло удесно у %{name} uturn_without_exit: Полукружно окретање дуж %{name} sharp_left_without_exit: Нагло улево у %{name} turn_left_without_exit: Скрените лево у %{name} + offramp_left_without_exit: Идите на рампу лево, на %{name} + onramp_left_without_exit: Скрените лево на рампи, на %{name} + endofroad_left_without_exit: На крају цесте скрените лево, на %{name} + merge_left_without_exit: Укључите се лево, на %{name} + fork_left_without_exit: На рачвању скрените лево, на %{name} slight_left_without_exit: Мало улево у %{name} via_point_without_exit: (преко тачке) follow_without_exit: Пратите %{name} @@ -2173,6 +2399,11 @@ sr: against_oneway_without_exit: Идите једносмерном на %{name} end_oneway_without_exit: Крај једносмерне на %{name} roundabout_with_exit: На кружном току изаберите излаз %{exit} на %{name} + turn_left_with_exit: На кружном току скрените лево у %{name} + slight_left_with_exit: На кружном току скрените благо лево у %{name} + turn_right_with_exit: На кружном току скрените десно у %{name} + slight_right_with_exit: На кружном току скрените благо десно у %{name} + continue_with_exit: На кружном току наставите право у %{name} unnamed: без имена courtesy: Путању је омогућио %{link} time: Време @@ -2183,6 +2414,13 @@ sr: nothing_found: Нема објеката у близини error: 'Грешка при повезивању са %{server}: %{error}%{error}' timeout: Истекло је време за повезивање са %{server} + context: + directions_from: Упути одавде + directions_to: Упути довде + add_note: Додај белешку овде + show_address: Прикажи адресу + query_features: Одлике упита + centre_map: Центрирај мапу овде redaction: edit: description: Опис diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 2619f3510..53b632b40 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -6,6 +6,7 @@ # Author: Adrianod # Author: Ainali # Author: Balp +# Author: Bengtsson96 # Author: Cohan # Author: Cybjit # Author: Dan Koehl @@ -56,7 +57,7 @@ sv: language: SprÃ¥k message: Meddelande node: Nod - node_tag: Nodtagg + node_tag: Nodetikett notifier: Meddelande old_node: Gammal nod old_node_tag: Gammal nodtagg @@ -65,7 +66,7 @@ sv: old_relation_tag: Gammal relationstagg old_way: Gammal sträcka old_way_node: Gammal sträcknod - old_way_tag: Gammal sträcktagg + old_way_tag: Gammal sträcketikett relation: Relation relation_member: Relationsmedlem relation_tag: Relationstagg @@ -74,11 +75,11 @@ sv: tracepoint: SpÃ¥rpunkt tracetag: SpÃ¥retikett user: Användare - user_preference: Användarinställningar + user_preference: Användarinställning user_token: Användarnyckel way: Sträcka way_node: Sträcknod - way_tag: Vägtagg + way_tag: Sträcketikett attributes: diary_comment: body: Brödtext @@ -131,12 +132,14 @@ sv: browse: created: Skapad closed: Stängd - created_html: Skapade %{time} sedan - closed_html: Stängde för %{time} sedan - created_by_html: Skapade %{time} sedan av %{user} - deleted_by_html: Raderade %{time} sedan av %{user} - edited_by_html: Redigerade %{time} sedan av %{user} - closed_by_html: Stängde för %{time} sedan av %{user} + created_html: Skapades för %{time} sedan + closed_html: Stängdes för %{time} sedan + created_by_html: Skapades för %{time} sedan av %{user} + deleted_by_html: Raderades för %{time} sedan av + %{user} + edited_by_html: Redigerades för %{time} sedan av + %{user} + closed_by_html: Stängdes för %{time} sedan av %{user} version: Version in_changeset: Ändringsset anonymous: anonym @@ -218,9 +221,9 @@ sv: webbläsare lÃ¥ngsam eller fÃ¥ den att sluta svara. Är säker pÃ¥ att du vill visa denna data? load_data: Ladda data - loading: Läser in... + loading: Läser in … tag_details: - tags: Taggar + tags: Etiketter wiki_link: key: Wiki-beskrivningssidan för %{key}-taggen tag: Wiki-beskrivningssidan för %{key}=%{value}-taggen @@ -237,17 +240,19 @@ sv: open_by: Skapad av %{user} %{when} sedan open_by_anonymous: Skapad av anonym %{when} sedan commented_by: Kommentar frÃ¥n %{user} %{when} sedan - commented_by_anonymous: Kommentar frÃ¥n anonym %{when} - sedan - closed_by: Löst av %{user} %{when} sedan - closed_by_anonymous: Löst av anonym %{when} sedan - reopened_by: Återaktiverad av %{user} %{when} sedan - reopened_by_anonymous: Återaktiverad av anonym %{when} + commented_by_anonymous: Kommentar frÃ¥n en anonym användare för + %{when} sedan + closed_by: Löst av %{user} för %{when} sedan + closed_by_anonymous: Löst av en anonym användare för + %{when} sedan + reopened_by: Återaktiverades av %{user} för %{when} sedan - hidden_by: Gömd av %{user} %{when} sedan + reopened_by_anonymous: Återaktiverades av en anonym användare för + %{when} sedan + hidden_by: Doldes av %{user} för %{when} sedan query: title: Undersök kartobjekt - introduction: Klicka pÃ¥ kartan för att hitta närliggande funktioner. + introduction: Klicka pÃ¥ kartan för att hitta funktioner i närheten. nearby: Finns i närheten enclosing: Omgivande kartobjekt changeset: @@ -414,7 +419,6 @@ sv: search: title: latlon: Resultat frÃ¥n OpenStreetMap - us_postcode: Resultat frÃ¥n Geocoder.us uk_postcode: Resultat frÃ¥n NPEMap / Free The Postcode ca_postcode: Resultat frÃ¥n Geocoder.CA @@ -573,7 +577,7 @@ sv: bridleway: Ridstig bus_guideway: SpÃ¥rbussväg bus_stop: BusshÃ¥llplats - construction: Motorväg under konstruktion + construction: Väg under byggnad cycleway: CykelspÃ¥r elevator: Hiss emergency_access_point: Utryckningsplats @@ -983,7 +987,7 @@ sv: intro_text: OpenStreetMap är en karta över världen, skapad av människor som du och fri att använda under en öppen licens. intro_2_create_account: Skapa ett användarkonto - partners_html: Hosting via %{ucl}, %{ic} och %{bytemark}, med flera %{partners}. + partners_html: Drivs via %{ucl}, %{ic}, %{bytemark}, %{ic} och andra %{partners}. partners_ucl: University College London partners_ic: Imperial College London partners_bytemark: Bytemark Hosting @@ -1057,10 +1061,8 @@ sv: title: Exempel pÃ¥ källhänvisning. more_title_html: Mer information more_1_html: |- - Läs mer om användning av vÃ¥r data, och hur du anger oss som källa, pÃ¥ OSMF licenssida och gemenskapens juridiska - FAQ. + Läs mer om användning av vÃ¥r data och hur du anger oss som källa pÃ¥ OSMF:s licenssida. more_2_html: |- Även om OpenStreetMap är öppen data, kan vi inte tillhandahÃ¥lla nÃ¥got gratis kart-API för tredjeparter. Se vÃ¥r användningspolicy för API, @@ -1251,7 +1253,7 @@ sv: community_driven_html: |- OpenStreetMaps gemenskap är blandad, passionerad och växer varje dag. Bland vÃ¥ra bidragsgivare finns kartentusiaster, GIS-proffs, ingenjörer som hÃ¥ller igÃ¥ng OSM:s servrar, frivilliga som kartlägger katastrofomrÃ¥den, och mÃ¥nga andra. - För mer information om gemenskapen, se användardagböcker, gemenskapens bloggar, och OSM-stiftelsens webbplats. + För mer information om gemenskapen, se OpenStreetMap-bloggen, användardagböcker, gemenskapens bloggar, och OSM-stiftelsens webbplats. open_data_title: Öppna data open_data_html: 'OpenStreetMap är öppna data: du kan fritt använda den för valfritt syfte sÃ¥ länge du anger OpenStreetMap och dess bidragsgivare som @@ -1444,6 +1446,7 @@ sv: date: Datum reply_button: Svara unread_button: Markera som oläst + delete_button: Radera back: Tillbaka to: Till wrong_user: Du är inloggad som '%{user}', men meddelandet du har bett om att @@ -1497,7 +1500,7 @@ sv: get_directions_title: Hitta vägen mellan tvÃ¥ punkter from: FrÃ¥n to: Till - where_am_i: Var är jag? + where_am_i: Var är detta? where_am_i_title: Beskriv den aktuella platsen med hjälp av sökmotorn submit_text: GÃ¥ key: diff --git a/config/locales/te.yml b/config/locales/te.yml index bfad7e408..abbe0f978 100644 --- a/config/locales/te.yml +++ b/config/locales/te.yml @@ -227,7 +227,6 @@ te: search: title: latlon: అంతర్గత ఫలితాలు - us_postcode: Geocoder.us నుండి ఫలితాలు ca_postcode: Geocoder.CA నుండి ఫలితాలు geonames: GeoNames నుండి ఫలితాలు search_osm_nominatim: diff --git a/config/locales/th.yml b/config/locales/th.yml new file mode 100644 index 000000000..1a47c367e --- /dev/null +++ b/config/locales/th.yml @@ -0,0 +1,1660 @@ +# Messages for Thai (ไทย) +# Exported from translatewiki.net +# Export driver: phpyaml +# Author: Ariesanywhere +# Author: Pon44695 +# Author: Ruila +# Author: TMo3289 +--- +th: + time: + formats: + friendly: '%e %B %Y เมื่อเวลา %H:%M น.' + activerecord: + 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: ป้ายกำกับเส้นทาง + 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: อีเมล์ + active: เปิดใช้ + display_name: ชื่อที่ใช้แสดง + description: คำอธิบาย + languages: ภาษา + pass_crypt: รหัสผ่าน + editor: + default: ค่าปกติ (ขณะนี้ %{name}) + potlatch: + name: พอตแลตช์ 1 + description: พอตแลตช์ 1 (ตัวแก้ไขในเบราว์เซอร์) + id: + name: iD + description: iD (ตัวแก้ไขในเบราว์เซอร์) + potlatch2: + name: พอตแลตช์ 2 + description: พอตแลตช์ 2 (ตัวแก้ไขในเบราว์เซอร์) + remote: + name: การควบคุมระยะไกล + description: ตัวควบคุมระยะไกล (JOSM หรือ Merkaartor) + browse: + created: สร้างเมื่อ + closed: ปิดเมื่อ + created_html: สร้างเมื่อ %{time} ก่อน + closed_html: ปิดเมื่อ %{time} ก่อน + created_by_html: สร้างเมื่อ %{time} ก่อน โดย %{user} + deleted_by_html: ลบเมื่อ %{time} ก่อน โดย %{user} + edited_by_html: แก้ไขเมื่อ %{time} ก่อน โดย %{user} + closed_by_html: ปิดเมื่อ %{time} ก่อน โดย %{user} + version: รุ่นที่ + in_changeset: ชุดการเปลี่ยนแปลง + anonymous: ไม่ระบุตัวตน + no_comment: (ไม่มีความคิดเห็น) + part_of: เป็นส่วนหนึ่งของ + download_xml: ดาวน์โหลด XML + view_history: ดูประวัติ + view_details: ดูรายละเอียด + location: 'ที่ตั้ง:' + changeset: + title: 'ชุดการเปลี่ยนแปลง: %{id}' + belongs_to: ผู้สร้างสรรค์ + node: หมุด (%{count}) + node_paginated: หมุดที่ (%{x}-%{y} จากทั้งหมด %{count}) + way: เส้นทาง (%{count}) + way_paginated: เส้นทางที่ (%{x}-%{y} จาก %{count}) + relation: ความสัมพันธ์ (%{count}) + relation_paginated: ความสัมพันธ์ (%{x}-%{y} จาก %{count}) + comment: ความคิดเห็น (%{count}) + hidden_commented_by: ความคิดเห็นซ่อนจาก %{user} เมื่อ %{when} + ก่อน + commented_by: ความคิดเห็นจาก %{user} เมื่อ %{when} + ก่อน + changesetxml: ชุดการเปลี่ยนแปลง XML + feed: + title: ชุดการเปลี่ยนแปลง %{id} + title_comment: ชุดการเปลี่ยนแปลง %{id} - %{comment} + join_discussion: เข้าสู่ระบบเพื่อเข้าร่วมการอภิปราย + discussion: การอภิปราย + node: + title: 'หมุด: %{name}' + history_title: 'ประวัติหมุด: %{name}' + way: + title: 'เส้นทาง: %{name}' + history_title: 'ประวัติเส้นทาง: %{name}' + nodes: หมุด + relation: + title: 'ความสัมพันธ์: %{name}' + history_title: 'ประวัติความสัมพันธ์: %{name}' + members: สมาชิก + relation_member: + entry_role: '%{type} %{name} ในฐานะ %{role}' + type: + node: หมุด + way: เส้นทาง + relation: ความสัมพันธ์ + containing_relation: + entry: ความสัมพันธ์ %{relation_name} + entry_role: ความสัมพันธ์ %{relation_name} (ในฐานะ %{relation_role}) + not_found: + sorry: 'ขออภัย ไม่พบ %{type} #%{id}' + type: + node: หมุด + way: เส้นทาง + relation: ความสัมพันธ์ + changeset: ชุดการเปลี่ยนแปลง + note: หมายเหตุ + timeout: + sorry: ขออภัย ข้อมูลสำหรับชนิด %{type} ที่กำกับด้วยรหัส %{id} ใช้เวลานานเกินสมควรในการเรียกดู + type: + node: หมุด + way: เส้นทาง + relation: ความสัมพันธ์ + changeset: ชุดการเปลี่ยนแปลง + note: หมายเหตุ + redacted: + redaction: การตรวจทาน %{id} + message_html: รุ่นที่ %{version} ชนิด %{type} ไม่สามารถแสดงว่าถูกตรวจทานมาแล้ว + โปรดไปที่ %{redaction_link} เพื่อดูรายละเอียด + type: + node: หมุด + way: เส้นทาง + relation: ความสัมพันธ์ + start_rjs: + feature_warning: กำลังโหลดส่วนประกอบจำนวน %{num_features} ส่วน การนี้ทำให้เบราว์เซอร์ของท่านทำงานช้าหรือไม่ตอบสนอง + ท่านแน่ใจหรือไม่ที่จะแสดงข้อมูลนี้? + load_data: กำลังโหลดข้อมูล + loading: กำลังโหลด... + tag_details: + tags: ป้ายกำกับ + wiki_link: + key: หน้าคำอธิบายวิกิาสำหรับป้ายระบุ %{key} + tag: หน้าคำอธิบายวิกิาสำหรับป้ายระบุ %{key}=%{value} + wikidata_link: รายการ %{page} ที่วิกิข้อมูล + wikipedia_link: บทความ %{page} ที่วิกิพีเดีย + telephone_link: โทรศัพท์ไปเลขหมาย %{phone_number} + note: + title: 'หมายเหตุ: %{id}' + new_note: หมายเหตุใหม่ + description: คำอธิบาย + open_title: 'บันทึกยังไม่ตอบสนอง #%{note_name}' + closed_title: บันทึกตอบสนองแล้ว %{note_name} + hidden_title: 'บันทึกที่ถูกซ่อน #%{note_name}' + open_by: จัดทำโดย %{user} เมื่อ %{when} ก่อน + open_by_anonymous: จัดทำโดยผู้ไม่ประสงค์ออกนามเมื่อ %{when} + ก่อน + commented_by: ความเห็นจาก %{user} เมื่อ %{when} + ก่อน + commented_by_anonymous: ความเห็นจากผู้ไม่ประสงค์ออกนามเมื่อ %{when} + ก่อน + closed_by: แก้ไขโดย %{user} เมื่อ %{when} ก่อน + closed_by_anonymous: แก้ไขโดยผู้ไม่ประสงค์ออกนามเมื่อ %{when} + ก่อน + reopened_by: เปิดใช้ซ้ำโดย %{user} เมื่อ %{when} + ก่อน + reopened_by_anonymous: เปิดใช้ซ้ำโดยผู้ไม่ประสงค์ออกนาม เมื่อ %{when} + ก่อน + hidden_by: ซ่อนโดย %{user} เมื่อ %{when} ก่อน + query: + title: คุณสมบัติการสอบถาม + introduction: คลิกที่แผนที่เพื่อค้นหาคุณสมบัติต่าง ๆ ที่อยู่ใกล้เคียง + nearby: คุณสมบัติที่อยู่ใกล้เคียง + enclosing: คุณสมบัติที่ปิดล้อม + changeset: + changeset_paging_nav: + showing_page: หน้า %{page} + next: ถัดไป » + previous: « ก่อนหน้า + changeset: + anonymous: ผู้ไม่ประสงค์ออกนาม + no_edits: (ไม่มีรายการแก้ไข) + view_changeset_details: ดูรายละเอียดชุดการเปลี่ยนแปลง + changesets: + id: รหัส + saved_at: บันทึกที่ + user: ผู้ใช้ + comment: ความเห็น + area: พื้นที่ + list: + title: ชุดการเปลี่ยนแปลง + title_user: ชุดการเปลี่ยนแปลงที่ทำโดย %{user} + title_friend: ชุดการเปลี่ยนแปลงที่ทำโดยเพื่อนของท่าน + title_nearby: ชุดการเปลี่ยนแปลงที่ทำโดยผู้ใช้ที่อยู่ใกล้เคียง + empty: ไม่พบชุดการเปลี่ยนแปลง + empty_area: ไม่พบชุดการเปลี่ยนแปลงในพื้นที่นี้ + empty_user: ผู้ใช้นี้ไม่มีชุดการเปลี่ยนแปลง + no_more: ไม่พบชุดการเปลี่ยนแปลงอีก + no_more_area: ไม่พบชุดการเปลี่ยนแปลงอีกในพื้นที่นี้ + no_more_user: ไม่พบชุดการเปลี่ยนแปลงอีกโดยผู้ใช้คนนี้ + load_more: แสดงเพิ่มขึ้น + timeout: + sorry: ขออภัย รายการชุดการเปลี่ยนแปลงที่ท่านร้องขอใช้เวลานานเกินสมควรในการสืบค้น + rss: + title_all: การสนทนาชุดการเปลี่ยนแปลงของ OpenStreetMap + title_particular: 'การอภิปรายชุดการเปลี่ยนแปลง OpenStreetMap #%{changeset_id}' + comment: 'ความคิดเห็นใหม่ที่มีต่อชุดการเปลี่ยนแปลง #%{changeset_id} โดย %{author}' + commented_at_html: ปรับปรุงเมื่อ %{when} ก่อน + commented_at_by_html: ปรับปรุงเมื่อ %{when} ก่อน โดย %{user} + full: การสนทนาแบบเต็ม + diary_entry: + new: + title: สร้างบันทึกใหม่ + publish_button: เผยแพร่ + list: + title: บันทึกของผู้ใช้ + title_friends: บันทึกของเพื่อน + title_nearby: บันทึกของผู้ใช้ที่อยู่ใกล้เคียง + user_title: บันทึกของ %{user} + in_language_title: รายการบันทึกทั้งหมดในภาษา %{language} + new: สร้างบันทึกใหม่ + new_title: สร้างบันทึกใหม่ในสมุดบันทึกประจำตัวของท่าน + 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} | %{title} + user_title: บันทึกของ %{user} + leave_a_comment: แสดงความคิดเห็น + login_to_leave_a_comment: '%{login_link} เพื่อแสดงความคิดเห็น' + login: ลงชื่อเข้าใช้ + save_button: บันทึก + no_such_entry: + title: ไม่มีรายการบันทึกที่ระบุ + heading: 'ไม่มีรายการรหัส: %{id}' + body: ขออภัย ไม่พบรายการบันทึกหรือข้อคิดเห็นที่กำกับด้วยรหัส %{id} โปรดตรวจการสะกดของท่าน + หรือถ้าไม่เป็นผลแสดงว่าลิงก์ที่ท่านคลิกมาผิดพลาด + diary_entry: + posted_by: ประกาศโดย %{link_user} เมื่อ %{created} ในภาษา %{language_link} + comment_link: แสดงความคิดเห็นต่อรายการนี้ + reply_link: ตอบกลับข้อความรายการนี้ + comment_count: + zero: ไม่มีข้อคิดเห็น + one: '%{count} ข้อคิดเห็น' + other: '%{count} ข้อคิดเห็น' + edit_link: แก้ไขรายการนี้ + hide_link: ซ่อนรายการนี้ + confirm: ยืนยัน + diary_comment: + comment_from: ความคิดเห็นจาก %{link_user} เมื่อ %{comment_created_at} + hide_link: ซ่อนข้อคิดเห็นนี้ + confirm: ยืนยัน + location: + location: 'ที่ตั้ง:' + view: ดู + edit: แก้ไข + feed: + user: + title: รายการบันทึก OpenStreetMap สำหรับผู้ใช้ %{user} + description: รายการบันทึกล่าสุด OpenStreetMap จากผู้ใช้ %{user} + language: + title: รายการบันทึก OpenStreetMap ในภาษา%{language_name} + description: รายการบันทึกล่าสุดจากผู้ใช้ OpenStreetMap ในภาษา%{language_name} + all: + title: รายการบันทึก OpenStreetMap + description: รายการบันทึกล่าสุดจากผู้ใช้ OpenStreetMap + comments: + has_commented_on: '%{display_name} ได้แสดงความคิดเห็นต่อรายการบันทึกต่อไปนี้' + post: เผยแพร่ + when: เมื่อ + comment: ความเห็น + ago: เมื่อ %{ago} ก่อน + newer_comments: ความคิดเห็นใหม่กว่า + older_comments: ความคิดเห็นเก่ากว่า + export: + title: ส่งออก + start: + area_to_export: พื้นที่ที่จะส่งออก + manually_select: เลือกพื้นที่อื่นด้วยตนเอง + format_to_export: รูปแบบที่จะส่งออก + osm_xml_data: ข้อมูล XML ของ OpenStreetMap + map_image: ภาพแผนที่ (แสดงชั้นภาพมาตรฐาน) + embeddable_html: HTML ฝังตัวได้ + licence: สัญญาอนุญาต + export_details: บรรดาข้อมูลที่ปรากฏในเว็บไซต์ OpenStreetMap อนุญาตให้ใช้ภายใต้สัญญาอนุญาต Open Data + Commons Open Database (ODbL). + too_large: + advice: 'ถ้าการส่งออกข้างต้นล้มเหลว โปรดพิจารณาใช้แหล่งข้อมูลตามที่ระบุด้านล่างนี้:' + body: พื้นที่ใหญ่เกินกว่าที่จะส่งออกเป็นข้อมูล XML ของ OpenStreetMap โปรดขยายเข้าหรือเลือกพื้นที่ที่เล็กลง + หรืออาจจะใช้แหล่งข้อมูลข้างล่างในการดาวน์โหลดแฟ้มข้อมูลจำนวนมาก + planet: + description: สำเนาของฐานข้อมูล OpenStreetMap ซึ่งปรับปรุงอย่างสม่ำเสมอ + geofabrik: + description: รายการทวีป ประเทศ และเมืองสำคัญซึ่งปรับปรุงอย่างสม่ำเสมอ + metro: + title: เมโทรเอกซ์แทรกซ์ + description: รายการเมืองสำคัญของโลกและพื้นที่โดยรอบ + other: + title: แหล่งข้อมูลอื่น + description: แหล่งข้อมูลอื่นตามที่ระบุไว้ใน OpenStreetMap wiki + options: ตัวเลือก + format: รูปแบบ + scale: มาตราส่วน + max: ขนาดสูงสุด + image_size: ขนาดภาพ + zoom: ย่อ-ขยาย + add_marker: เพิ่มเครื่องหมายลงในแผนที่ + latitude: 'ละติจูด:' + longitude: 'ลองจิจูด:' + output: การแสดงผล + paste_html: วาง HTML สำหรับนำไปใช้ในเว็บไซต์ + export_button: ส่งออก + geocoder: + search: + title: + latlon: ผลการค้นหาจาก เว็บไซต์นี้ + uk_postcode: ผลการค้นหาจาก NPEMap / FreeThe + Postcode + ca_postcode: ผลการค้นหาจาก Geocoder.CA + osm_nominatim: ผลการค้นหาจาก OpenStreetMap + Nominatim + geonames: ผลการค้นหาจาก GeoNames + osm_nominatim_reverse: ผลการค้นหาจาก OpenStreetMap + Nominatim + geonames_reverse: ผลการค้นหาจาก GeoNames + search_osm_nominatim: + prefix: + aerialway: + cable_car: รถกระเช้า + chair_lift: รถกระเช้าเปลือย + drag_lift: ลิฟต์ลากสกี + gondola: รถกระเช้า + station: สถานีรถกระเช้า + aeroway: + aerodrome: สนามบิน (ทุกประเภท) + apron: ลานจอดเครื่องบิน + gate: ประตูขึ้นเครื่อง + helipad: ลานจอดเฮลิคอปเตอร์ + runway: ทางวิ่งเครื่องบิน + taxiway: ทางขับเครื่องบิน + terminal: อาคารผู้โดยสาร + amenity: + animal_shelter: สถานสงเคราะห์สัตว์ + arts_centre: ศูนย์ศิลปะ + atm: บริการเงินสดด่วน + bank: ธนาคาร + bar: ร้านสุรา + bbq: ร้านอาหารย่าง + bench: ม้านั่ง + bicycle_parking: ที่จอดจักรยาน + bicycle_rental: บริการเช่าจักรยาน + biergarten: สวนเบียร์ + boat_rental: บริการเช่าเรือ + brothel: สถานบริการทางเพศ + bureau_de_change: ร้านรับแลกเงินตรา + bus_station: สถานีขนส่ง + cafe: ร้านกาแฟ + car_rental: บริการเช่ารถยนต์ + car_sharing: บริการร่วมเดินทาง + car_wash: บริการรับล้างรถ + casino: บ่อนไพ่ + charging_station: สถานีประจุไฟฟ้า + childcare: สถานรับเลี้ยงเด็ก + cinema: โรงภาพยนตร์ + clinic: คลินิก + clock: นาฬิกา + college: วิทยาลัย + community_centre: ศูนย์รวมชุมชน + courthouse: ศาล + crematorium: ฌาปนสถาน + dentist: ทันตแพทย์ + doctors: แพทย์ + dormitory: หอพักนักศึกษา + drinking_water: น้ำดื่ม + driving_school: สถานสอนขับรถ + embassy: สถานทูต + emergency_phone: โทรศัพท์ฉุกเฉิน + fast_food: อาหารจานด่วน + ferry_terminal: สถานีเรือข้ามฟาก + fire_hydrant: จุดรับน้ำดับเพลิง + fire_station: สถานดับเพลิง + food_court: ศูนย์อาหาร + fountain: น้ำพุ + fuel: สถานีบริการเชื้อเพลิง + gambling: การพนัน + grave_yard: สุสาน + gym: สถานออกกำลังกาย + health_centre: ศูนย์สุขภาพ + hospital: โรงพยาบาล + hunting_stand: บังไพรล่าสัตว์ + ice_cream: ร้านไอศกรีม + kindergarten: โรงเรียนอนุบาล + library: ห้องสมุด + market: ตลาด + marketplace: ตลาดนัด + monastery: วัดหรือโบสถ์ + motorcycle_parking: ที่จอดรถจักรยานยนต์ + nightclub: สถานบริการ + nursery: สถานรับเลี้ยงเด็ก + nursing_home: สถานสงเคราะห์หรือบ้านพักคนชรา + office: สำนักงาน + parking: ที่จอดรถ + parking_entrance: ทางเข้าที่จอดรถ + pharmacy: ร้านขายยา + place_of_worship: สถานที่ประกอบพิธีทางศาสนา + police: สถานีตำรวจ + post_box: ตู้ไปรษณีย์ + post_office: ที่ทำการไปรษณีย์ + preschool: โรงเรียนชั้นประถมวัย + prison: ทัณฑสถาน + pub: ร้านอาหาร + public_building: อาคารสาธารณะ + reception_area: พื้นที่ต้อนรับ + recycling: จุดรีไซเคิล + restaurant: ร้านอาหาร + retirement_home: บ้านพักวัยเกษียณ + sauna: สถานที่อบตัว + school: โรงเรียน + shelter: สถานที่พักพิง + shop: ร้านค้า + shower: สถานที่อาบน้ำ + social_centre: ศูนย์พบปะสมาคม + social_club: สโมสรพบปะ + social_facility: สโมสรพบปะ + studio: สถานที่บันทึกภาพและเสียง + swimming_pool: สระว่ายน้ำ + taxi: รถแท็กซี่ + telephone: โทรศัพท์สาธารณะ + theatre: โรงภาพยนตร์ + toilets: ห้องน้ำสาธารณะ + townhall: ศาลาว่าการเมือง + university: มหาวิทยาลัย + vending_machine: เครื่องขายสินค้า + veterinary: คลินิกสัตวแพทย์ + village_hall: ศาลากลางหมู่บ้าน + waste_basket: ถังขยะ + waste_disposal: ที่ทิ้งขยะ + youth_centre: ศูนย์เยาวชน + boundary: + administrative: ขอบเขตการปกครอง + census: ขอบเขตการสำรวจประชากร + national_park: อุทยานแห่งชาติ + protected_area: พื้นที่ปกป้อง + bridge: + aqueduct: สะพานส่งน้ำ + suspension: สะพานแขวน + swing: สะพานหันข้าง + viaduct: สะพานบก + "yes": สะพาน + building: + "yes": อาคาร + craft: + brewery: โรงทำสุรา + carpenter: ช่างไม้ + electrician: ช่างไฟฟ้า + gardener: คนสวน + painter: ช่างทาสี + photographer: นักถ่ายภาพ + plumber: ช่างท่อประปา + shoemaker: ช่างทำรองเท้า + tailor: ช่างตัดเสื้อผ้า + "yes": ร้านงานฝีมือ + emergency: + ambulance_station: สถานีรถพยาบาล + defibrillator: เครื่องช่วยกระตุ้นหัวใจ + landing_site: พื้นที่ลงจอดฉุกเฉิน + phone: โทรศัพท์ฉุกเฉิน + highway: + abandoned: ทางหลวงที่เลิกใช้แล้ว + bridleway: ทางเกวียน + bus_guideway: ทางรถสาธารณะชนิดบังคับล้อได้ + bus_stop: ที่หยุดรถสาธารณะ + construction: ทางหลวงกำลังสร้าง + cycleway: ทางจักรยาน + elevator: ลิฟต์ + emergency_access_point: จุดเข้าถึงฉุกเฉิน + footway: ทางเดินเท้า + ford: ถนนตัดทางน้ำ + living_street: ถนนใช้ร่วมรถและคน + milestone: หลักไมล์ + motorway: ทางหลวงพิเศษ + motorway_junction: แยกทางหลวงพิเศษ + motorway_link: ถนนทางหลวงพิเศษ + path: เส้นทาง + pedestrian: ทางคนเดิน + platform: ชานชาลา + primary: ถนนสายหลัก + primary_link: ถนนสายหลัก + proposed: ถนนที่เสนอให้สร้าง + raceway: ลานแข่งรถ + residential: ถนนในเขตที่พักอาศัย + rest_area: จุดแวะพัก + road: ถนน + secondary: ถนนสายรอง + secondary_link: ถนนสายรอง + service: ถนนสำหรับซ่อมบำรุง + services: บริการทางหลวงพิเศษ + speed_camera: กล้องจับความเร็ว + steps: ขั้น + street_lamp: ไฟส่องทาง + tertiary: ถนนสายย่อย + tertiary_link: ถนนสายย่อย + track: ราง + traffic_signals: สัญญาณจราจร + trail: ทางเดิน + trunk: ถนนสายประธาน + trunk_link: ถนนสายประธาน + unclassified: ถนนที่มิได้จำแนก + unsurfaced: ถนนที่ยังไม่ปูลาด + "yes": ถนน + historic: + archaeological_site: สถานที่ทางโบราณคดี + battlefield: สนามรบ + boundary_stone: หินแสดงขอบเขต + building: อาคารประวัติศาสตร์ + bunker: บังเกอร์ + castle: ปราสาท + church: โบสถ์ + city_gate: ประตูเมือง + citywalls: กำแพงเมือง + fort: ป้อม + heritage: สถานที่มรดก + house: บ้าน + icon: ไอคอน + manor: บ้านสวน + memorial: อนุสรณ์ + mine: เหมือง + monument: อนุสาวรีย์ + roman_road: ถนนโรมัน + ruins: ซากโบราณสถาน + stone: หลักหิน + tomb: สุสาน + tower: หอคอย + wayside_cross: กางเขนข้างทาง + wayside_shrine: ศาลเจ้าข้างทาง + wreck: ซากปรักหักพัง + junction: + "yes": ทางแยก + landuse: + allotments: ที่ดินแบ่งใช้ + basin: แอ่ง + brownfield: พื้นที่อุตสาหกรรมเดิม + cemetery: สุสาน + commercial: พื้นที่พาณิชยกรรม + conservation: การอนุรักษ์ + construction: การก่อสร้าง + farm: ไร่นา + farmland: ไร่นา + farmyard: ลานไร่นา + forest: ป่า + garages: โรงรถ + grass: หญ้า + greenfield: พื้นที่สีเขียว + industrial: พื้นที่อุตสาหกรรม + landfill: บ่อขยะ + meadow: ทุ่งหญ้า + military: เขตทหาร + mine: เหมือง + orchard: สวนผลไม้ + quarry: บ่อขุดหิน + railway: ทางรถไฟ + recreation_ground: สนามสำหรับเล่น + reservoir: อ่างเก็บน้ำ + reservoir_watershed: สันปันน้ำ + residential: เขตที่พักอาศัย + retail: ร้านค้าขายปลีก + road: พื้นที่ถนน + village_green: ลานหญ้าในเขตหมู่บ้าน + vineyard: ไร่องุ่น + "yes": การใช้ประโยชน์ที่ดิน + leisure: + beach_resort: สถานตากอากาศชายหาด + bird_hide: บังไพรดูนก + club: สโมสร + common: พื้นที่สาธารณประโยชน์ + dog_park: สวนสุนัข + fishing: พื้นที่ตกปลา + fitness_centre: ศูนย์ออกกำลังกาย + fitness_station: ศูนย์ออกกำลังกาย + garden: สวน + golf_course: สนามกอล์ฟ + horse_riding: สนามม้า + ice_rink: ลานสเก็ตน้ำแข็ง + marina: ที่จอดเรือ + miniature_golf: สนามกอล์ฟเล็ก + nature_reserve: พื้นที่สงวนธรรมชาติ + park: สวน + pitch: ลานกีฬา + playground: สนามเด็กเล่น + recreation_ground: สนามสำหรับเล่น + resort: สถานที่พักผ่อน + sauna: สถานที่อบตัว + slipway: ทางลาดสำหรับเรือ + sports_centre: ศูนย์กีฬา + stadium: สนามกีฬา + swimming_pool: สระว่ายน้ำ + track: ทางวิ่ง + water_park: สวนน้ำ + "yes": สถานที่เพื่อนันทนาการ + man_made: + lighthouse: ประภาคาร/กระโจมไฟ + pipeline: ท่อส่งน้ำมัน + tower: หอคอย + works: โรงงาน + "yes": ที่มนุษย์สร้างขึ้น + military: + airfield: สนามบินทหาร + barracks: โรงทหาร + bunker: หลุมหลบภัย + mountain_pass: + "yes": ช่องเขา + natural: + bay: อ่าว + beach: หาด + cape: ถ้ำ + cave_entrance: ทางเข้าถ้ำ + cliff: หน้าผา + crater: หลุมอุกกาบาต + dune: เนินทราย + fell: ทุ่งหญ้า + fjord: ฟยอร์ด + forest: ป่าดิบ + geyser: น้ำพุร้อน + glacier: ธารน้ำแข็ง + grassland: ทุ่งหญ้า + heath: ทุ่งไม้พุ่ม + hill: เนินเขา + island: เกาะ + land: ที่ดิน + marsh: ที่ลุ่มน้ำขัง + moor: ทุ่งหญ้าที่สูง + mud: โคลน + peak: ยอดเขา + point: จุด + reef: แนวปะการัง + ridge: สันเขา + rock: หลักหิน + saddle: หุบโค้ง + sand: ทราย + scree: ลาดหินร่วง + scrub: ป่าไม้พุ่ม + spring: น้ำพุ + stone: หลักหิน + strait: ช่องแคบ + tree: ต้นไม้ + valley: หุบผา + volcano: ภูเขาไฟ + water: น้ำ + wetland: พื้นที่ชุ่มน้ำ + wood: ไม้ + office: + accountant: นักบัญชี + administrative: การปกครอง + architect: สถาปนิก + company: บริษัท + employment_agency: บริษัทจัดหางาน + estate_agent: บริษัทอสังหาริมทรัพย์ + government: สำนักงานของรัฐบาล + insurance: สำนักงานประกันภัย + lawyer: ทนายความ + ngo: สำนักงานองค์กรเอกชน + telecommunication: ที่ทำการโทรคมนาคม + travel_agent: ตัวแทนการเดินทาง + "yes": สำนักงาน + place: + allotments: ที่ดินแบ่งใช้ + block: ช่วงตึก + airport: สนามบิน + city: เมือง + country: ประเทศ + county: จังหวัด + farm: ไร่นา + hamlet: ชุมชนขนาดเล็ก + house: บ้าน + houses: บ้าน + island: เกาะ + islet: เกาะขนาดเล็ก + isolated_dwelling: ที่อยู่อาศัยโดด + locality: ชุมชน + moor: ทุ่งหญ้าที่สูง + municipality: เทศบาล + neighbourhood: ชุมชน + postcode: รหัสไปรษณีย์ + region: ภูมิภาค + sea: ทะเล + state: รัฐ + subdivision: เขตการปกครองย่อย + suburb: ชานเมือง + town: เมือง + unincorporated_area: พื้นที่นอกเขตเทศบาล + village: หมู่บ้าน + "yes": สถานที่ + railway: + abandoned: ทางรถไฟที่เลิกใช้แล้ว + construction: ทางรถไฟกำลังสร้าง + disused: ทางรถไฟเลิกใช้แล้ว + disused_station: สถานีรถไฟยุบแล้ว + funicular: รถไฟขึ้นลงเนิน + halt: ที่หยุดรถไฟ + historic_station: สถานีรถไฟในอดีต + junction: ชุมทางรถไฟ + level_crossing: ทางผ่านเสมอระดับ + light_rail: รถไฟเบา + miniature: รถไฟเล็ก + monorail: รถราวหรือโมโนเรล + narrow_gauge: รถไฟรางแคบ + platform: ชานชาลารถไฟ + preserved: ทางรถไฟที่อนุรักษ์ไว้ + proposed: ทางรถไฟที่เสนอให้สร้าง + spur: ทางรถไฟสายย่อย + station: สถานีรถไฟ + stop: ที่หยุดรถไฟ + subway: รถไฟใต้ดิน + subway_entrance: ทางเข้ารถไฟใต้ดิน + switch: ประแจรถไฟ + tram: ทางรถราง + tram_stop: ที่หยุดรถราง + shop: + alcohol: ร้านขายสุรา + antiques: ร้านขายของเก่า + art: ร้านขายงานศิลปะ + bakery: ร้านขายขนมอบ + beauty: ร้านเสริมสวย + beverages: ร้านขายเครื่องดื่ม + bicycle: ร้านขายและเช่าจักรยาน + books: ร้านขายหนังสือ + boutique: ร้านเสริมสวย + butcher: ร้านขายเนื้อ + car: ร้านรถยนต์ + car_parts: ร้านอะไหล่รถยนต์ + car_repair: ร้านรับซ่อมรถยนต์ + carpet: ร้านขายพรม + charity: ร้านการกุศล + chemist: ร้านขายยา + clothes: ร้านขายเสื้อผ้า + computer: ร้านคอมพิวเตอร์ + confectionery: ร้านขายขนมหวาน + convenience: ร้านสะดวกซื้อ + copyshop: ร้านถ่ายเอกสาร + cosmetics: ร้านขายเครื่องสำอาง + deli: ร้านขายอาหารพิเศษ + department_store: ห้างสรรพสินค้า + discount: ร้านสินค้าลดราคา + doityourself: ทำด้วยตัวท่านเอง + dry_cleaning: บริการซักแห้ง + electronics: ร้านอิเล็กทรอนิกส์ + estate_agent: บริษัทอสังหาริมทรัพย์ + farm: ร้านในไร่นา + fashion: ร้านแฟชั่น + fish: ร้านขายปลา + florist: ร้านขายดอกไม้ + food: ร้านขายอาหาร + funeral_directors: บริการจัดการศพ + furniture: เครื่องเรือน + gallery: สถานที่แสดงงานศิลปะ + garden_centre: ศูนย์การจัดสวน + general: ร้านค้าทั่วไป + gift: ร้านของขวัญ + greengrocer: ร้านขายผักผลไม้ + grocery: ร้านชำ + hairdresser: ร้านทำผม + hardware: ร้านวัสดุก่อสร้าง + hifi: เครื่องเสียง + insurance: ประกันภัย + jewelry: ร้านเครื่องประดับ + kiosk: ร้านแผงลอย + laundry: ร้านซักรีด + mall: ห้างสรรพสินค้าขนาดใหญ่ + market: ตลาด + mobile_phone: ร้านโทรศัพท์มือถือ + motorcycle: ร้านรถจักรยานยนต์ + music: ร้านดนตรี + newsagent: ร้านขายหนังสือพิมพ์ + optician: จักษุแพทย์ + organic: ร้านขายอาหารอินทรีย์ + outdoor: ร้านขายอุปกรณ์ผจญภัย + pet: ร้านขายสัตว์เลี้ยงและอุปกรณ์ + pharmacy: ร้านขายยา + photo: ร้านถ่ายภาพ + salon: ร้านทำผมสตรี + second_hand: ร้านขายของมือสอง + shoes: ร้านขายรองเท้า + shopping_centre: ห้างสรรพสินค้า + sports: ร้านขายอุปกรณ์กีฬา + stationery: ร้านขายเครื่องเขียน + supermarket: ห้างสรรพสินค้า + tailor: ช่างตัดเสื้อผ้า + toys: ร้านขายของเล่น + travel_agency: ตัวแทนการเดินทาง + video: ร้านขายภาพยนตร์ + wine: ร้านขายสุรา + "yes": ร้านค้า + tourism: + alpine_hut: กระท่อมป่าสน + apartment: อาคารชุด + artwork: งานศิลปะ + attraction: แหล่งท่องเที่ยว + bed_and_breakfast: เรือนพักพร้อมอาหาร + cabin: กระท่อม + camp_site: ลานตั้งค่าย + caravan_site: ลานจอดรถบ้าน + chalet: กระท่อมพักผ่อน/ชาเลต์ + gallery: สถานที่แสดงงานศิลปะ + guest_house: เรือนพัก + hostel: โรงแรมนอนรวม + hotel: โรงแรม + information: ประชาสัมพันธ์ + motel: โรงแรมสำหรับผู้เดินทาง + museum: พิพิธภัณฑ์ + picnic_site: สถานที่ปิกนิก + theme_park: สวนสนุก + viewpoint: จุดชมวิว + zoo: สวนสัตว์ + tunnel: + culvert: ท่อระบายน้ำ + "yes": อุโมงค์ + waterway: + artificial: ทางน้ำที่มนุษย์สร้าง + boatyard: ที่จอดเรือ + canal: คลอง + dam: เขื่อน + derelict_canal: คลองเลิกใช้แล้ว + ditch: คู + dock: แอ่งจอดเรือ + drain: ทางระบายน้่ำ + lock: แอ่งยกเรือ + lock_gate: ประตูแอ่งยกเรือ + mooring: หลักผูกเรือ + rapids: แก่ง + river: แม่น้ำ + stream: ลำธาร + wadi: หุบวาดี + waterfall: น้ำตก + weir: ฝาย + "yes": ทางน้ำ + admin_levels: + level2: แนวเขตประเทศ + level4: แนวเขตรัฐ + level5: แนวเขตภูมิภาค + level6: แนวเขตจังหวัด + level8: แนวเขตเมือง/อำเภอ + level9: แนวเขตหมู่บ้าน + level10: แนวเขตชานเมือง + description: + title: + osm_nominatim: ตำบลที่ตั้งจาก OpenStreetMap + Nominatim + geonames: ตำบลที่ตั้งจาก GeoNames + types: + cities: เมือง + towns: เมือง + places: สถานที่ + results: + no_results: ไม่พบผลลัพธ์ + more_results: ดูผลลัพธ์เพิ่ม + layouts: + logo: + alt_text: ตราสัญลักษณ์ OpenStreetMap + home: กลับไปที่ตำแหน่งบ้าน + logout: ออกจากระบบ + log_in: ลงชื่อเข้าใช้ + log_in_tooltip: ลงชื่อเข้าใช้ด้วยบัญชีที่มีอยู่แล้ว + sign_up: สมัครบัญชี + start_mapping: เริ่มการทำแผนที่ + sign_up_tooltip: สร้างบัญชีสำหรับการแก้ไข + edit: แก้ไข + history: ประวัติ + export: ส่งออก + data: ข้อมูล + export_data: ส่งออกข้อมูล + gps_traces: รอยทาง GPS + gps_traces_tooltip: จัดการรอยทาง GPS + user_diaries: บันทึกของผู้ใช้ + user_diaries_tooltip: ดูบันทึกของผู้ใช้ + edit_with: แก้ไขด้วย %{editor} + tag_line: แผนที่โลกวิกิ ใช้งานได้ไม่เสียค่าใช้จ่าย + intro_header: ยินดีต้อนรับสู่ OpenStreetMap! + intro_text: OpenStreetMap เป็นแผนที่โลกที่สร้างโดยผู้คนเช่นท่าน และใช้งานได้ไม่เสียค่าใช้จ่ายภายใต้สัญญาอนุญาตแบบเปิด + intro_2_create_account: สร้างบัญชีผู้ใช้ใหม่ + partners_html: เซิร์ฟเวอร์สนับสนุนโดย %{ucl}, %{bytemark}, %{ic}, และ%{partners}อื่น + ๆ + partners_ucl: ยูซีแอล (วิทยาลัยอุดมศึกษาลอนดอน) + partners_ic: วิทยาลัยอิมพีเรียลลอนดอน + partners_bytemark: ไบต์มาร์กโฮสติง + partners_partners: องค์กรพันธมิตร + osm_offline: ฐานข้อมูลของ OpenStreetMap กำลังออฟไลน์เพื่อให้สามารถดำเนินการบำรุงรักษาตามปกติได้ + osm_read_only: ฐานข้อมูลของ OpenStreetMap กำลังอยู่ในโหมดอ่านอย่างเดียวเพื่อให้สามารถดำเนินการบำรุงรักษาตามปกติได้ + donate: สนับสนุน OpenStreetMap โดย %{link} สมทบทุนปรับปรุงฮาร์ดแวร์ + help: วิธีใช้ + about: เกี่ยวกับ + copyright: ลิขสิทธิ์ + community: ชุมชน + community_blogs: บทความชุมชน + community_blogs_title: บทความเพื่อชุมชนจากสมาชิก OpenStreetMap + foundation: มูลนิธิ + foundation_title: มูลนิธิ OpenStreetMap + make_a_donation: + title: สนับสนุน OpenStreetMap โดยการบริจาคเงิน + text: บริจาค + learn_more: เรียนรู้เพิ่มเติม + more: เพิ่มเติม + license_page: + foreign: + title: เกี่ยวกับการแปลนี้ + text: หากมีข้อขัดแย้งจากากรตีความหน้าที่แปลนี้กับหน้าเดิมในภาษาอังกฤษ %{english_original_link} + ให้ถือภาษาอังกฤษเป็นสำคัญถูกต้องเสมอ + english_link: หน้าเดิมในภาษาอังกฤษ + native: + title: เกี่ยวกับหน้านี้ + text: ท่านกำลังเรียกดูหน้าข้อมูลลิขสิทธิ์ในภาษาอังกฤษ และสามารถกลับไปที่หน้าภาษา + %{native_link} หรือกลับไปยังแผนที่ที่ %{mapping_link}. + native_link: รุ่นภาษาTHIS_LANGUAGE_NAME_HERE + mapping_link: เริ่มการทำแผนที่ + legal_babble: + title_html: ลิขสิทธิ์และสัญญาอนุญาต + intro_1_html: |- + OpenStreetMap® เป็นข้อมูลเปิดให้ใช้งาน และอนุญาตให้ใช้งานภายใต้สัญญาอนุญาต Open Data + Commons Open Database License (ODbL) โดยมูลนิธิ OpenStreetMap (OSMF). + intro_2_html: "ท่านสามารถทำสำเนา แจกจ่าย แพร่ภาพ และปรับใช้ข้อมูลของเรา\nตราบเท่าที่ได้ระบุชื่อ + OpenStreetMap ตลอดจนผู้ร่วมจัดทำไว้ในคำขอบคุณหรือที่มา\nถ้าท่านปรับแก้ไขหรือสร้างสรรค์งานใหม่โดยใช้ข้อมูลของเราเป็นพื้น + ท่านสามารถ\nแจกจ่ายผลลัพธ์ที่ได้ภายใต้สัญญาอนุญาตเดียวกันเท่านั้น โปรดดู ข้อกำหนดทางกฎหมาย + \nซึ่งจะอธิบายสิทธิและหน้าที่ที่ท่านพึงมี" + intro_3_html: |- + ภาพร่าง ลายเส้นแผนที่ตามที่ปรากฏ และเอกสารกำกับ อนุญาตให้ใช้งานตามสัญญาอนุญาต Creative + Commons Attribution-ShareAlike 2.0 (CC BY-SA) + credit_title_html: วิธีการแสดงที่มาหรือคำขอบคุณ OpenStreetMap + credit_1_html: |- + เราจำเป็นต้องให้ท่านแสดงที่มาหรือคำขอบคุณแก่ “© ผู้ร่วมสร้างสรรค์ OpenStreetMap + ”. + credit_2_html: |- + ท่านจะต้องระบุให้ชัดเจนเจาะจงว่าข้อมูลอนุญาตให้ใช้ตามสัญญาอนุญาต Open + Database License และถ้ามีการนำรูปแผนที่ไปใช้ รูปนั้นอนุญาตให้ใช้ตามสัญญาอนุญาต + CC BY-SA ในการนี้อาจจะลิงก์ไปยังหน้า + ข้อมูลลิขสิทธิ์ + นอกจากนี้ (จำเป็นหากท่านจ่ายแจกข้อมูล OSM) ท่านสามารถลิงก์ไปยังสัญญาอนุญาตโดยตรง + ในสื่ออย่างอื่น อาทิ สิ่งพิมพ์ ซึ่งไม่สามารถลิงก์ข้อมูลได้แนะนำให้ระบุเพียง openstreetmap.org + และ/หรือ opendatacommons.org และ/หรือ creativecommons.org + more_title_html: ค้นหาเพิ่มเติม + contributors_title_html: ผู้ร่วมสร้างสรรค์ของเรา + contributors_at_html: |- + ออสเตรีย: มีข้อมูลจาก + Stadt Wien (under + CC BY), + Land Vorarlberg และ + Land Tirol (under CC BY AT with amendments). + contributors_ca_html: |- + แคนาดา: มีข้อมูลจาก + GeoBase®, GeoGratis (© Department of Natural + Resources Canada), CanVec (© Department of Natural + Resources Canada) และ StatCan (Geography Division, + Statistics Canada) + contributors_fi_html: |- + ฟินแลนด์: มีข้อมูลจาก + ฐานข้อมูลการสำรวจภูมิศาสตร์แห่งชาติฟินแลนด์และฐานข้อมูลอื่น + อนุญาตให้ใช้ตาม + สัญญาอนุญาต NLSFI. + contributors_fr_html: |- + ฝรั่งเศส: มีข้อมูลจากอธิบดีกรมภาษี ( + Direction Générale des Impôts) + contributors_gb_html: |- + สหราชอาณาจักร: มีข้อมูลจากกองแผนที่ Ordnance + Survey data © ลิขสิทธิ์ราชการและสิทธิ์แห่งฐานข้อมูล + 2010-12 + infringement_title_html: การละเมิดลิขสิทธิ์ + welcome_page: + title: ยินดีต้อนรับ! + basic_terms: + title: เงื่อนไขพื้นฐานสำหรับการทำแผนที่ + questions: + title: มีคำถามอีกหรือไม่? + paragraph_1_html: "OpenStreetMap มีสื่อสำหรับค้นคว้า สอบถาม ตอบคำถาม \nสนทนา + ตลอดจนจัดทำวิธีการสร้างแผนที่\nขอรับความช่วยเหลือที่นี่" + start_mapping: เริ่มการทำแผนที่ + add_a_note: + title: ไม่มีเวลาแก้ไขใช่ไหม? เพิ่มบันทึกเดี๋ยวนี้! + paragraph_1_html: หากท่านต้องการแก้ไขสิ่งต่าง ๆ ไม่มากนัก และไม่มีเวลาเข้าใช้ระบบและเรียนรู้วิธีแก้ไขมากนัก + อาจจะเพิ่มบันทึกแทนได้ + paragraph_2_html: |- + แค่ไปที่แผนที่ แล้วคลิกไอคอน บันทึก: + . จากนั้นจะมีเครื่องหมายมาที่แผนที่ให้ท่านลากไปยัง + ตำแหน่งที่ต้องการ ใส่ข้อความที่ต้องการ คลิกบันทึก จากนั้นผู้ใช้ท่านอื่นจะเข้ามาตรวจสอบ + fixthemap: + title: รายงานปัญหา/แก้ไขข้อผิดพลาดในแผนที่ + how_to_help: + title: วิธีการช่วยเหลือ + join_the_community: + title: เข้าร่วมเป็นสมาชิก + explanation_html: หากท่านประสบปัญหาเกี่ยวกับข้อมูลแผนที่ของเรา หรือพบข้อผิดพลาด + เช่น ถนนหายไป หรือมีข้อผิดพลาดด้านที่อยู่ วิธีที่ดีที่สุดคือสมัครเป็นสมาชิก + OpenStreetMap เพื่อดำเนินการแก้ไขด้วยตัวท่านเอง + help_page: + beginners_guide: + url: http://wiki.openstreetmap.org/wiki/Th:Beginners%27_guide + mailing_lists: + title: รายการอีเมลรับข่าวสาร + forums: + title: กระดานสนทนา + about_page: + next: ถัดไป + open_data_title: ข้อมูลเปิดเผย + open_data_html: |- + OpenStreetMap อนุญาตให้ใช้ตามหลักเกณฑ์ข้อมูลเปิดเผย โดยจะนำไปใช้ในวัตถุประสงค์อื่นใดก็ได้ + แต่ต้องแสดงที่มาหรือให้คำขอบคุณต่อ OpenStreetMap ตลอดจนผู้ร่วมสร้างสรรค์ ถ้าท่านปรับแก้ สร้างสรรค์ + หรือกระทำการให้เกิดสิ่งอื่นใดใหม่ขึ้นต่องานที่มีนี้ ท่านสามารถแจกจ่ายได้แต่เพียงภายใต้สัญญาอนุญาตเดิม โปรดดู + หน้าลิขสิทธิ์และสัญญาอนุญาต ถ้าต้องการรายละเอียดเพิ่ม + legal_title: ข้อกำหนดทางกฎหมาย + legal_html: "เว็บไซต์และบริการที่เกี่ยวข้องนี้ดำเนินการและบำรุงรักษาอย่างเป็นทางการโดย\nมูลนิธิ OpenStreetMap (OSMF) \nในนามสมาชิกทุกคน + การใช้บริการที่ดำเนินการโดย OSMF จะต้องอยู่ใต้เงื่อนไข\nการใช้งานที่ยอมรับได้ + และนโยบายความเป็นส่วนบุคคล\n
    + \nโปรดติดต่อ OSMF \nถ้าท่านมีข้อสงสัยเกี่ยวกับสัญญาอนุญาต + ข้อมูลลิขสิทธิ์ คำถามกฎหมายและประเด็นที่เกี่ยวข้อง" + partners_title: องค์กรพันธมิตร + notifier: + diary_comment_notification: + subject: '[OpenStreetMap] ผู้ใช้ %{user} แสดงความคิดเห็นต่อรายการบันทึก' + hi: เรียนคุณ %{to_user}, + header: 'ผู้ใช้ %{from_user} ได้แสดงความคิดเห็นต่อบันทึก OpenStreetMap หัวเรื่อง + %{subject}:' + footer: ท่านสามารถอ่านความคิดเห็นได้ที่ลิงก์ %{readurl} และแสดงความคิดเห็นตอบได้ที่ + %{commenturl} หรือตอบกลับได้ที่ %{replyurl} + message_notification: + hi: เรียนคุณ %{to_user}, + header: 'ผู้ใช้ %{from_user} ส่งข้อความหาท่านผ่านทาง OpenStreetMap โดยมีหัวเรื่อง + %{subject}:' + footer_html: ท่านสามารถอ่านข้อความที่ลิงก์ %{readurl} และถ้าต้องการสามารถตอบกลับที่ลิงก์ + %{replyurl} + friend_notification: + hi: เรียนคุณ %{to_user}, + subject: '[OpenStreetMap] %{user} เพิ่มท่านในรายการเพื่อน' + had_added_you: ผู้ใช้ %{user} เพิ่มท่านในรายการเพื่อนบน OpenStreetMap + see_their_profile: ท่านสามารถดูหน้าประวัติส่วนตัวของเขาได้ที่ %{userurl}. + befriend_them: นอกจากนี้ท่านสามารถเพิ่มเขาในรายการเพื่อนได้ที่ %{befriendurl}. + gpx_notification: + greeting: สวัสดี, + your_gpx_file: ดูเหมือนว่าแฟ้มข้อมูล GPX ของท่าน + with_description: มีคำอธิบาย + and_the_tags: 'และป้ายกำกับต่อไปนี้:' + and_no_tags: และไม่มีป้ายกำกับ + failure: + subject: '[OpenStreetMap] การนำเข้า GPX ล้มเหลว' + failed_to_import: 'การนำเข้าล้มเหลว เนื่องจาก:' + more_info_1: รายละเอียดเพิ่มเติมเกี่ยวกับข้อผิดพลาดและความล้มเหลวในการนำเข้า + GPX และวิธีการหลีกเลี่ยง + more_info_2: 'ทั้งหมดสามารถพบได้ที่:' + success: + subject: '[OpenStreetMap] การนำเข้า GPX เรียบร้อย' + loaded_successfully: การนำเข้าสำเร็จ มีจำนวนจุด %{trace_points} จุด จากที่เป็นไปได้ทั้งหมด + %{possible_points} จุด + signup_confirm: + subject: '[OpenStreetMap] ยินดีต้อนรับสู่ OpenStreetMap' + greeting: เรียนท่านผู้ใช้งาน + created: มีบางคน (ซึ่งอาจเป็นท่าน) ได้สร้างบัญชีผู้ใช้ใหม่ไว้ที่ %{site_url} + confirm: 'ก่อนที่ทางเราจะดำเนินการต่อไปได้ เราขอให้ท่านยืนยันว่า ท่านได้สมัครสมาชิกจริงหรือไม่ + ถ้าจริง ขอให้ท่านคลิกลิงก์ข้างล่างเพื่อยืนยันบัญชีของท่าน:' + welcome: หลังจากที่ยืนยันบัญชีของท่านแล้ว เราจะให้รายละเอียดเพิ่มเติมเพื่อให้ท่านเริ่มใช้งานเว็บไซต์ได้ต่อไป + email_confirm: + subject: '[OpenStreetMap] ยืนยันที่อยู่อีเมลของท่าน' + email_confirm_plain: + greeting: เรียนท่านผู้ใช้งาน + hopefully_you: มีบางคน (ซึ่งอาจเป็นท่าน) ประสงค์จะเปลี่ยนที่อยู่อีเมลที่รักษาไว้ที่ + %{server_url} เป็น %{new_address} + click_the_link: ถ้าเป็นท่านจริง ขอให้คลิกลิงก์ด้านล่างเพื่อยืนยันการเปลี่ยนแปลง + email_confirm_html: + greeting: เรียนท่านผู้ใช้งาน + hopefully_you: มีบางคน (ซึ่งอาจเป็นท่าน) ประสงค์จะเปลี่ยนที่อยู่อีเมลที่รักษาไว้ที่ + %{server_url} เป็น %{new_address} + click_the_link: ถ้าเป็นท่านจริง ขอให้คลิกลิงก์ด้านล่างเพื่อยืนยันการเปลี่ยนแปลง + lost_password: + subject: '[OpenStreetMap] คำขอเปลี่ยนรหัสผ่านใหม่' + lost_password_plain: + greeting: เรียนท่านผู้ใช้งาน + hopefully_you: มีบางคน (ซึ่งอาจเป็นท่าน) ขอเปลี่ยนรหัสผ่านซึ่งกำกับบัญชีผู้ใช้ + openstreetmap.org + click_the_link: หากเป็นท่านจริง โปรดคลิกลิงก์ข้างล่าง เพื่อดำเนินการเปลี่ยนรหัสผ่านใหม่ + lost_password_html: + greeting: เรียนท่านผู้ใช้งาน + hopefully_you: มีบางคน (ซึ่งอาจเป็นท่าน) ขอเปลี่ยนรหัสผ่านซึ่งกำกับบัญชีผู้ใช้ + openstreetmap.org + click_the_link: หากเป็นท่านจริง โปรดคลิกลิงก์ข้างล่าง เพื่อดำเนินการเปลี่ยนรหัสผ่านใหม่ + note_comment_notification: + anonymous: ผู้ใช้ไม่ระบุตัวตน + greeting: เรียนท่านผู้ใช้งาน + commented: + subject_own: '[OpenStreetMap] ผู้ใช้ %{commenter} แสดงความคิดเห็นต่อบันทึกของท่าน' + subject_other: '[OpenStreetMap] ผู้ใช้ %{commenter} แสดงความคิดเห็นต่อบันทึกที่ท่านสนใจ' + your_note: ผู้ใช้ %{commenter} ได้แสดงความคิดเห็นต่อบันทึกของท่านที่อยู่ใกล้กับ + %{place} + commented_note: ผู้ใช้ %{commenter} ได้แสดงความคิดเห็นต่อบันทึกที่ท่านแสดงความเห็นก่อนหน้านี้ + บันทึกนั้นอยู่ใกล้กับ %{place} + closed: + subject_own: '[OpenStreetMap] ผู้ใช้ %{commenter} ได้แก้ไขหรือสนองตอบต่อบันทึกของท่านหนึ่งฉบับแล้ว' + subject_other: '[OpenStreetMap] ผู้ใช้ %{commenter} ได้แก้ไขหรือสนองตอบต่อบันทึกที่ท่านสนใจ' + your_note: ผู้ใช้ %{commenter} ได้แก้ไขหรือสนองตอบต่อบันทึกของท่านที่อยู่ใกล้กับ + %{place} + commented_note: ผู้ใช้ %{commenter} ได้แก้ไขหรือสนองตอบต่อบันทึกที่ท่านแสดงความเห็นก่อนหน้านี้ + บันทึกนั้นอยู่ใกล้กับ %{place} + reopened: + subject_own: '[OpenStreetMap] ผู้ใช้ %{commenter} ได้ขอรื้อฟื้นหรือเปิดใช้งานบันทึกของท่าน' + subject_other: '[OpenStreetMap] ผู้ใช้ %{commenter} ได้ขอรื้อฟื้นหรือเปิดใช้งานบันทึกที่ท่านสนใจ' + your_note: ผู้ใช้ %{commenter} ได้แก้ไขหรือสนองตอบต่อบันทึกของท่านที่อยู่ใกล้กับ + %{place} + commented_note: ผู้ใช้ %{commenter} ได้แก้ไขหรือสนองตอบต่อบันทึกที่ท่านแสดงความเห็นก่อนหน้านี้ + บันทึกนั้นอยู่ใกล้กับ %{place} + details: รายละเอียดเพิ่มเติมเกี่ยวกับบันทึกสามารถหาได้ที่ %{url} + changeset_comment_notification: + hi: เรียนคุณ %{to_user}, + greeting: เรียนท่านผู้ใช้งาน + commented: + subject_own: '[OpenStreetMap] ผู้ใช้ %{commenter} ได้แสดงความคิดเห็นต่อชุดการเปลี่ยนแปลงของท่าน' + subject_other: '[OpenStreetMap] ผู้ใช้ %{commenter} ได้แสดงความคิดเห็นต่อชุดการเปลี่ยนแปลงที่ท่านสนใจ' + your_changeset: ผู้ใช้ %{commenter} ได้แสดงความคิดเห็นต่อชุดการเปลี่ยนแปลงของท่านที่ทำไว้ + ณ เวลา %{time} + commented_changeset: ผู้ใช้ %{commenter} ได้แสดงความคิดเห็นต่อชุดการเปลี่ยนแปลงที่ท่านเฝ้าดู + ซึ่งสร้างโดยผู้ใช้ %{changeset_author} ณ เวลา %{time} + partial_changeset_with_comment: มีข้อคิดเห็น '%{changeset_comment}' + partial_changeset_without_comment: ไม่มีข้อคิดเห็น + details: รายละเอียดเพิ่มเติมเกี่ยวกับชุดการเปลี่ยนแปลงสามารถหาได้ที่ %{url} + unsubscribe: เพื่อบอกเลิกการรับข้อมูลการปรับปรุงชุดการเปลี่ยนแปลงนี้ โปรดไปนี้ + %{url} แล้วคลิก "เลิกรับข้อมูล". + message: + inbox: + title: จดหมายรับ + my_inbox: จดหมายรับส่วนตัว + outbox: จดหมายออก + messages: ท่านมี %{new_messages} และ %{old_messages} + new_messages: + one: ข้อความใหม่ %{count} ข้อความ + other: ข้อความใหม่ %{count} ข้อความ + old_messages: + one: ข้อความเก่า %{count} ข้อความ + other: ข้อความเก่า %{count} ข้อความ + from: จาก + subject: เรื่อง + date: วันที่ + no_messages_yet: ท่านยังไม่มีข้อความใด ๆ ทำไมไม่ลองติดต่อกับ%{people_mapping_nearby_link}บ้าง? + people_mapping_nearby: ผู้คนที่กำลังทำแผนที่ที่อยู่ใกล้เคียง + message_summary: + unread_button: ทำเครื่องหมายว่ายังไม่ได้อ่าน + read_button: ทำเครื่องหมายว่าอ่านแล้ว + reply_button: ตอบกลับ + delete_button: ลบ + new: + title: ส่งข้อความ + send_message_to: ส่งข้อความใหม่หาผู้ใช้ %{name} + subject: หัวเรื่อง + body: เนื้อหา + send_button: ส่ง + back_to_inbox: กลับไปที่กล่องจดหมายรับ + message_sent: ส่งข้อความแล้ว + limit_exceeded: เมื่อไม่นานมานี้ท่านส่งข้อความออกไปจำนวนมาก โปรดรอสักครู่ก่อนส่งข้อความต่อไป + no_such_message: + title: ไม่พบข้อความที่ระบุ + heading: ไม่พบข้อความที่ระบุ + body: ขออภัย ไม่พบข้อความที่กำกับด้วยรหัสดังกล่าว + outbox: + title: จดหมายออก + my_inbox: '%{inbox_link}ส่วนตัว' + inbox: จดหมายรับ + outbox: จดหมายออก + messages: + one: ท่านมีข้อความส่งแล้ว %{count} ฉบับ + other: ท่านมีข้อความส่งแล้ว %{count} ฉบับ + to: ถึง + subject: หัวเรื่อง + date: วันที่ + no_sent_messages: ท่านยังไม่มีข้อความใด ๆ ทำไมไม่ลองติดต่อกับ%{people_mapping_nearby_link}บ้าง? + people_mapping_nearby: ผู้คนที่กำลังทำแผนที่ที่อยู่ใกล้เคียง + reply: + wrong_user: ท่านเข้าระบบโดยใช้ชื่อผู้ใช้ `%{user}' แต่ข้อความที่ท่านกำลังจะตอบกลับไม่ได้ส่งถึงผู้ใช้ดังกล่าว + โปรดเข้าระบบใหม่โดยใช้ชื่อผู้ใช้นั้นเพื่อตอบกลับ + read: + title: อ่านข้อความ + from: จาก + subject: เรื่อง + date: วันที่ + reply_button: ตอบกลับ + unread_button: ทำเครื่องหมายว่ายังไม่ได้อ่าน + delete_button: ลบ + back: ย้อนกลับ + to: ถึง + wrong_user: ท่านเข้าระบบโดยใช้ชื่อผู้ใช้ `%{user}' แต่ข้อความที่ท่านกำลังจะตอบกลับไม่ได้ส่งโดยหรือส่งถึงผู้ใช้ดังกล่าว + โปรดเข้าระบบใหม่โดยใช้ชื่อผู้ใช้นั้นเพื่อตอบกลับ + sent_message_summary: + delete_button: ลบ + mark: + as_read: ข้อความถูกทำเครื่องหมายว่าอ่านแล้ว + as_unread: ข้อความถูกทำเครื่องหมายว่ายังไม่ได้อ่าน + delete: + deleted: ข้อความถูกลบแล้ว + site: + index: + js_1: ท่านกำลังใช้เบราว์เซอร์ที่ไม่รองรับจาวาสคริปต์ หรือท่านปิดใช้งานจาวาสคริปต์ + permalink: ลิงก์ถาวร + shortlink: ลิงก์ย่อ + createnote: เพิ่มบันทึก + edit: + not_public: ท่านยังไม่ได้ตั้งค่าการแก้ไขให้มองเห็นได้ทั่วไป + not_public_description: ท่านไม่สามารถแก้ไขแผนที่นี้ได้เว้นแต่จะดำเนินการสิ่งอื่นบางอย่าง + ท่านสามารถตั้งให้การแก้ไขของท่านมองเห็นได้ทั่วไปที่%{user_page} + user_page_link: หน้าผู้ใช้ + no_iframe_support: เบราว์เซอร์ของท่านไม่รองรับการใช้งานเฟรมภายในหน้า HTML จึงไม่สามารถใช้ส่วนประกอบนี้ได้ + sidebar: + search_results: ผลการค้นหา + close: ปิด + search: + search: ค้นหา + get_directions: ขอเส้นทาง + get_directions_title: ค้นหาเส้นทางระหว่างจุดสองจุด + from: จาก + to: ถึง + where_am_i: ข้าพเจ้าอยู่ที่ไหน? + where_am_i_title: อธิบายตำแหน่งปัจจุบันโดยใช้เครื่องมือค้นหา + submit_text: ไป + key: + table: + entry: + motorway: ทางหลวงพิเศษ + main_road: ถนนสายหลัก + trunk: ถนนสายประธาน + primary: ถนนสายหลัก + secondary: ถนนสายรอง + unclassified: ถนนที่มิได้จำแนก + track: รอยทาง + bridleway: ทางเกวียน + cycleway: ทางจักรยาน + cycleway_national: ทางจักรยานระดับประเทศ + cycleway_regional: ทางจักรยานระดับภูมิภาค + cycleway_local: ทางจักรยานระดับท้องถิ่น + footway: ทางเดินเท้า + rail: ทางรถไฟ + subway: รถไฟใต้ดิน + tram: + - รถไฟเบา + - รถราง + cable: + - รถกระเช้า + - รถกระเช้าเปลือย + runway: + - ทางวิ่งสนามบิน + - ทางขับเครื่องบิน + apron: + - โรงซ่อมบำรุงเครื่องบิน + - อาคารผู้โดยสาร + admin: ขอบเขตการปกครอง + forest: ป่า + wood: ไม้ + golf: สนามกอล์ฟ + park: สวน + resident: เขตที่พักอาศัย + common: + - ที่ส่วนกลาง + - ทุ่งหญ้า + retail: พื้นที่พาณิชยกรรม + industrial: พื้นที่อุตสาหกรรม + commercial: พื้นที่พาณิชยกรรม + heathland: ทุ่งไม้พุ่ม + lake: + - ทะเลสาบ + - อ่างเก็บน้ำ + farm: ไร่นา + brownfield: พื้นที่อุตสาหกรรมเดิม + cemetery: สุสาน + allotments: ที่ดินแบ่งใช้ + pitch: ลานกีฬา + centre: ศูนย์กีฬา + reserve: พื้นที่สงวนธรรมชาติ + military: เขตทหาร + school: + - โรงเรียน + - มหาวิทยาลัย + building: อาคารสำคัญ + station: สถานีรถไฟ + summit: + - ยอดเขา + - ยอดเขา + tunnel: เส้นประ = อุโมงค์ + bridge: เส้นทึบ = สะพาน + private: พื้นที่ส่วนบุคคล + destination: การเข้าถึงที่จุดปลายทาง + construction: ถนนกำลังก่อสร้าง + bicycle_shop: ร้านขายและเช่าจักรยาน + bicycle_parking: ที่จอดจักรยาน + toilets: ห้องน้ำสาธารณะ + richtext_area: + edit: แก้ไข + preview: แสดงตัวอย่าง + markdown_help: + title_html: ตัดอ่านโดย Markdown + headings: หัวเรื่องหลัก + heading: หัวเรื่องหลัก + subheading: หัวเรื่องย่อย + unordered: รายการไม่เรียงลำดับ + ordered: รายการเรียงลำดับ + first: รายการแรก + second: รายการที่สอง + link: ลิงก์ + text: ข้อความ + image: รูปภาพ + alt: ข้อความทดแทนภาพ + url: ที่อยู่ลิงก์ + trace: + visibility: + private: ส่วนตัว (เผยแพร่ในนามผู้ไม่ประสงค์ออกนาม แต่ละจุดไม่เรียงลำดับ) + public: สาธารณะ (แสดงในรายการรอยทาง และในนามผู้ไม่ประสงค์ออกนาม แต่ละจุดไม่เรียงลำดับ) + trackable: ติดตามได้ (แสดงในนามผู้ไม่ประสงค์ออกนาม แต่ละจุดมีเวลากำกับ) + identifiable: ระบุได้ (แสดงเป็นชื่อให้ติดตามได้ แต่ละจุดมีเวลากำกับ) + create: + upload_trace: อัปโหลดรอยทาง GPS + edit: + tags_help: คั่นด้วยจุลภาค + save_button: บันทึกการเปลี่ยนแปลง + visibility: 'สถานะการแสดง:' + visibility_help: นี่หมายความว่าอะไร? + trace_form: + upload_gpx: 'อัปโหลดแฟ้ม GPX:' + description: 'คำอธิบาย:' + tags: 'ป้ายกำกับ:' + tags_help: คั่นด้วยจุลภาค + visibility: 'สถานะการแสดง:' + visibility_help: นี่หมายความว่าอะไร? + upload_button: อัปโหลด + help: วิธีใช้ + trace_header: + upload_trace: อัปโหลดรอยทาง + see_all_traces: แสดงรอยทางทั้งหมด + see_your_traces: แสดงรอยทางของท่าน + list: + public_traces: รอยทาง GPS สาธารณะ + your_traces: รอยทาง GPS ของท่าน + user: + login: + openid_logo_alt: เข้าใช้งานด้วย OpenID + auth_providers: + openid: + title: เข้าใช้งานด้วย OpenID + alt: เข้าใช้งานด้วยลิงก์ OpenID + google: + title: เข้าใช้งานด้วย Google + alt: เข้าใช้งานด้วย Google OpenID + facebook: + title: เข้าใช้งานด้วย Facebook + alt: เข้าใช้งานด้วยบัญชี Facebook + windowslive: + title: เข้าใช้งานด้วย Windows Live + alt: เข้าใช้งานด้วยบัญชี Windows Live + logout: + title: ออกจากระบบ + logout_button: ออกจากระบบ + lost_password: + title: ตั้งรหัสผ่านใหม่ + heading: ลืมรหัสผ่านหรือ? + new password button: ตั้งรหัสผ่านใหม่ + new: + email address: 'ที่อยู่อีเมล:' + confirm email address: 'ยืนยันที่อยู่อีเมล:' + not displayed publicly: ที่อยู่ของท่านจะไม่แสดงให้บุคคลภายนอกเห็น โปรดดู นโบายความเป็นส่วนบุคคล ถ้าต้องการรายละเอียดเพิ่มเติม + display name: 'ชื่อที่ใช้แสดง:' + display name description: ชื่อที่แสดงต่อสาธารณะ ท่านสามารถเปลี่ยนในภายหลังได้ในหน้าการตั้งค่า + external auth: 'บัญชีผู้ใช้จากเว็บอื่น:' + password: 'รหัสผ่าน:' + confirm password: 'ยืนยันรหัสผ่าน:' + use external auth: นอกจากนี้ ท่านสามารถใช้บัญชีผู้ใช้จากเว็บอื่นในการเข้าใช้งานได้ + auth no password: ถ้ามีบัญชีผู้ใช้จากเว็บอื่น โดยปกติไม่จำเป็นต้องมีรหัสผ่าน + แต่ถ้าเข้าใช้งานเครื่องมือบางตัวหรือเซิร์ฟเวอร์ก็ยังจำเป็นต้องมีรหัสผ่านอยู่ + continue: สมัครบัญชี + terms accepted: ขอบคุณสำหรับการตอบรับเงื่อนไขผู้ร่วมสร้างสรรค์! + terms declined: ขออภัย ท่านมิได้ยอมรับเงื่อนไขผู้ร่วมสร้างสรรค์ เราจึงไม่สามารถดำเนินการต่อไปได้ + รายละเอียดเพิ่มเติมโปรดดูหน้านี้. + terms: + title: เงื่อนไขผู้ร่วมสร้างสรรค์ + heading: เงื่อนไขผู้ร่วมสร้างสรรค์ + read and accept: โปรดอ่านข้อตกลงต่อไปนี้และเลือกปุ่ม ยอมรับ เพื่อยืนยันว่าท่านยอมรับเงื่อนไขนี้ในการสร้างสรรค์ที่เคยทำมาและที่จะทำต่อไปในอนาคต + consider_pd: นอกเหนือจากข้อตกลงข้างต้น ข้าพเจ้ายินดีสละการสร้างสรรค์ของข้าพเจ้าให้เป็นงานอันไม่มีลิขสิทธิ์ + consider_pd_why: นี้คืออะไร? + agree: ยอมรับ + decline: ไม่ยอมรับ + legale_select: 'ประเทศที่พำนัก:' + legale_names: + france: ฝรั่งเศส + italy: อิตาลี + rest_of_world: พื้นที่อื่น ๆ ในโลก + no_such_user: + title: ไม่มีผู้ใช้ที่ระบุ + heading: ไม่พบผู้ใช้ชื่อ %{user} + view: + create_block: กีดกันผู้ใช้นี้ + activate_user: เปิดใช้งานผู้ใช้นี้ + deactivate_user: ปิดใช้งานผู้ใช้นี้ + account: + title: แก้ไขบัญชี + contributor terms: + link text: นี้คืออะไร? + profile description: 'คำอธิบายหน้าประวัติส่วนตัว:' + preferred languages: 'ภาษาที่ต้องการ:' + preferred editor: 'ตัวแก้ไขที่ต้องการใช้:' + image: 'รูปภาพ:' + gravatar: + gravatar: ใช้ Gravatar + link text: นี้คืออะไร? + disabled: Gravatar ถูกปิดใช้ + enabled: การแสดง Gravatar ของท่านถูกเปิดใช้ + new image: เพิ่มรูปภาพ + keep image: ใช้รูปภาพปัจจุบัน + delete image: ลบรูปภาพปัจจุบัน + replace image: เปลี่ยนรูปภาพปัจจุบัน + image size hint: (ภาพขนาดสี่เหลี่ยม 100x100 จะดีที่สุด) + 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: โปรดตรวจสอบอีเมลของท่าน! + introduction_1: เราได้ส่งอีเมลยืนยันให้ท่านแล้ว + introduction_2: โปรดยืนยันบัญชีของท่านโดยคลิกลิงก์ในอีเมล หลังจากนั้นท่านสามารถเริ่มใช้งานแผนที่ได้ + press confirm button: คลิกปุ่ม ยืนยัน ข้างล่างเพื่อเปิดใช้บัญชีของท่าน + button: ยืนยัน + success: บัญชีของท่านยืนยันเสร็จแล้ว ขอบคุณสำหรับการสมัครใช้งาน! + already active: บัญชีนี้ได้ถูกยืนยันมาก่อนแล้ว + unknown token: รหัสยืนยันหมดอายุหรือผิดพลาด + reconfirm_html: ถ้าท่านต้องการให้เราส่งอีเมลยืนยันซ้ำ โปรดคลิกที่นี่. + confirm_resend: + success: เราได้ส่งบันทึกยืนยันใหม่ไปยังอีเมล %{email} เมื่อท่านยืนยันแล้ว จะสามารถเริ่มทำแผนที่ได้ทันที

    ถ้าท่านมีระบบป้องกันสแปม โปรดให้ %{sender} อยู่ในรายการปลอดภัย (whitelist) + เพราะเราไม่สามารถตอบอีเมลยืนยันใด ๆ ได้ + failure: ไม่พบผู้ใช้ %{name} + confirm_email: + heading: ยืนยันการเปลี่ยนแปลงที่อยู่อีเมล + press confirm button: คลิกปุ่ม ยืนยัน ข้างล่างเพื่อยืนยันที่อยู่อีเมลใหม่ + button: ยืนยัน + success: ยืนยันการเปลี่ยนแปลงที่อยู่อีเมลเรียบร้อย! + failure: อีเมลนี้ถูกยืนยันกับคำขอนี้เรียบร้อย + unknown_token: รหัสยืนยันหมดอายุหรือผิดพลาด + set_home: + flash success: ตำแหน่งที่อยู่บ้านบันทึกเรียบร้อย + go_public: + flash success: การแก้ไขของท่านเป็นสาธารณะ ท่านสามารถแก้ไขได้ + make_friend: + heading: เพิ่มผู้ใช้ %{user} ในรายการเพื่อนหรือไม่? + button: เพิ่มในรายการเพื่อน + success: ผู้ใช้ %{name} อยู่ในรายการเพื่อนของท่านเรียบร้อย! + failed: ขออภัย ไม่สามารถเพิ่มผู้ใช้ %{name} ในรายการเพื่อน + already_a_friend: ท่านมีผู้ใช้ %{name}ในรายการเพื่อนอยู่แล้ว + remove_friend: + heading: ต้องการลบผู้ใช้ %{user} ออกจากรายการเพื่อนหรือไม่? + button: ลบจากรายการเพื่อน + success: ท่านได้ลบผู้ใช้ %{name} ออกจากรายการเพื่อน + not_a_friend: ผู้ใช้ %{name} ไม่ได้อยู่ในรายการเพื่อนของท่าน + filter: + not_an_administrator: ท่านต้องเป็นผู้ดูแลระบบจึงจะสามารกระทำสิ่งนี้ได้ + list: + title: ผู้ใช้ + heading: ผู้ใช้ + showing: + one: หน้าที่ %{page} (%{first_item} จาก %{items}) + other: หน้าที่ %{page} (%{first_item}-%{last_item} จาก %{items}) + summary: '%{name} สร้างจากไอพี %{ip_address} เมื่อ %{date}' + suspended: + title: บัญชีถูกระงับ + heading: บัญชีถูกระงับ + webmaster: ผู้ดูแลเว็บ + body: |2- + +

    + ขออภัยอย่างสูง เนื่องจากมีการกระทำต้องสงสัย บัญชีของท่านถูกระงับโดยอัตโนมัติ +

    +

    + การดำเนินการอื่นใดจะถูกกลั่นกรองโดยผู้ดูแลเว็บในเวลาไม่นานจากนี้ หรืออาจจะชี้แจงต่อ%{webmaster}หากต้องการเหตุผล +

    + auth_failure: + connection_failed: การเชื่อมต่อกับผู้ให้บริการบัญชีภายนอกล้มเหลว + invalid_credentials: ชื่อผู้ใช้และ/หรือรหัสผ่านไม่ถูกต้อง + no_authorization_code: ไม่มีรหัสยืนยัน + unknown_signature_algorithm: ขั้นตอนวิธีลายมือชื่อไม่ทราบ + invalid_scope: ขอบข่ายผิดพลาด + auth_association: + heading: บัญชีภายนอกของท่านยังมิได้ต่อเชื่อมกับบัญชี OpenStreetMap + option_1: ถ้าท่านเป็นผู้ใช้ OpenStreetMap ใหม่ โปรดใช้แบบฟอร์มข้างล่างสร้างบัญชีผู้ใช้ + option_2: "ถ้าท่านมีบัญชีผู้ใช้แล้ว สามารถเข้าสู่ระบบโดยใช้ชื่อผู้ใช้ รหัสผ่าน + \nแล้วผูกโยงบัญชีกับบัญชีภายนอกในหน้าการตั้งค่าา" + user_role: + filter: + not_an_administrator: ท่านไม่ได้เป็นผู้ดูแลระบบ จึงไม่สามารถจัดการเรื่องแต่งตั้งถอดถอนสถานะของผู้ใช้งานได้ + not_a_role: ข้อความ `%{role}' ไม่ใช่สถานะผู้ใช้งานที่ถูกต้อง + already_has_role: ผู้ใช้มีสถานะเป็น %{role} อยู่แล้ว + doesnt_have_role: ผู้ใช้ไม่ได้มีสถานะ %{role} + grant: + title: ยืนยันการแต่งตั้งสถานะ + heading: ยืนยันการแต่งตั้งสถานะ + are_you_sure: ท่านแน่ใจว่าต้องการแต่งตั้งสถานะ `%{role}' แก่ผู้ใช้ `%{name}' + หรือไม่? + confirm: ยืนยัน + fail: ไม่สามารถแต่งตั้งสถานะ `%{role}' แก่ผู้ใช้ `%{name}' โปรดตรวจสอบว่าทั้งผู้ใช้และสถานะเป็นที่ถูกต้องดีแล้ว + revoke: + title: ยืนยันการถอดถอนสถานะ + heading: ยืนยันการถอดถอนสถานะ + are_you_sure: ท่านแน่ใจว่าต้องการถอดถอนสถานะ `%{role}' จากผู้ใช้ `%{name}' หรือไม่? + confirm: ยืนยัน + fail: ไม่สามารถถอดถอนสถานะ `%{role}' แก่ผู้ใช้ `%{name}' โปรดตรวจสอบว่าทั้งผู้ใช้และสถานะเป็นที่ถูกต้องดีแล้ว + javascripts: + share: + format: 'รูปแบบ:' + scale: 'ขนาด:' + map: + base: + cycle_map: แผนที่จักรยาน + transport_map: แผนที่การขนส่ง + hot: เพื่อมนุษยธรรม + layers: + header: ชั้นแผนที่ + notes: หมายเหตุแผนที่ + data: ข้อมูลแผนที่ + donate_link_text: + site: + edit_tooltip: แก้ไขแผนที่ + edit_disabled_tooltip: ขยายเพื่อแก้ไขแผนที่ + createnote_tooltip: เพิ่มบันทึกลงในแผนที่ + changesets: + show: + subscribe: บอกรับข้อมูล + unsubscribe: เลิกรับข้อมูล + directions: + instructions: + continue_without_exit: เคลื่อนต่อไปทางถนน %{name} + offramp_right_without_exit: ใช้ทางลาดด้านขวาไปที่ถนน %{name} + onramp_right_without_exit: เลี่ยวขวาที่ทางลาดไปที่ถนน %{name} + endofroad_right_without_exit: เมื่อถึงสุดถนนเลี้ยวขวาไปที่ถนน %{name} + merge_right_without_exit: เลี้ยวขวาเข้าสู่ถนน %{name} ซึ่งเป็นทางเอก + fork_right_without_exit: ที่ทางแยกเลี้ยวขวาไปที่ถนน %{name} + uturn_without_exit: วกกลับไปตามถนน %{name} + sharp_left_without_exit: เลี้ยวซ้ายหักไปที่ %{name} + turn_left_without_exit: เลี้ยวซ้ายไปที่ %{name} + offramp_left_without_exit: ใช้ทางลาดด้านซ้ายไปที่ %{name} + onramp_left_without_exit: เลี้ยวซ้ายบนทางลาดไปที่ถนน %{name} + endofroad_left_without_exit: เมื่อถึงสุดถนนเลี้ยวซ้ายไปที่ถนน %{name} + merge_left_without_exit: เลี้ยวซ้ายเข้าสู่ถนน %{name} ซึ่งเป็นทางเอก + fork_left_without_exit: ที่ทางแยกเลี้ยวซ้ายไปที่ถนน %{name} + slight_left_without_exit: ขยับซ้ายเล็กน้อยไปที่ %{name} + roundabout_with_exit: ณ วงเวียน ใช้ทางออก %{exit} ไปที่ถนน %{name} + turn_left_with_exit: ณ วงเวียน เลี้ยวซ้ายไปที่ถนน %{name} + slight_left_with_exit: ณ วงเวียน ขยับซ้ายไปที่ถนน %{name} + turn_right_with_exit: ณ วงเวียน เลี้ยวขวาไปที่ถนน %{name} + slight_right_with_exit: ณ วงเวียน ขยับขวาไปที่ถนน %{name} + continue_with_exit: ณ วงเวียน ตรงไปที่ถนน %{name} + unnamed: ถนนไม่มีชื่อ + courtesy: เอื้อเฟื้อเส้นทางโดย %{link} + time: เวลา + query: + node: หมุด + way: เส้นทาง + relation: ความสัมพันธ์ + nothing_found: ไม่พบส่วนประกอบ + error: 'มีความผิดพลาดขณะติดต่อ %{server}: %{error}' + timeout: หมดเวลาขณะพยายามติดต่อ %{server} + context: + directions_from: เส้นทางจากที่นี่ + directions_to: เส้นทางมาที่นี่ + add_note: เพิ่มบันทึกที่นี่ + show_address: แสดงที่อยู่ + query_features: สอบถามส่วนประกอบ + centre_map: วางแผนที่ตรงกลางที่นี่ + redaction: + edit: + description: คำอธิบาย + heading: แก้ไขการตรวจทาน + submit: บันทึกการตรวจทาน + title: แก้ไขการตรวจทาน + index: + empty: ไม่มีการตรวจทานให้แสดง + heading: รายการการตรวจทาน + title: รายการการตรวจทาน + new: + description: คำอธิบาย + heading: กรอกรายละเอียดการตรวจทานใหม่ + submit: สร้างการตรวจทาน + title: สร้างการตรวจทานใหม่ + show: + description: 'คำอธิบาย:' + heading: แสดงการตรวจทาน "%{title}" + title: แสดงการตรวจทาน + user: 'ผู้สร้าง:' + edit: แก้ไขการตรวจทานนี้ + destroy: ลบการตรวจทานนี้ + confirm: ท่านแน่ใจหรือไม่? + create: + flash: การตรวจทานสร้างเรียบร้อย + update: + flash: การเปลี่ยนแปลงบันทึกเรียบร้อย + destroy: + not_empty: การตรวจทานยังไม่ว่าง โปรดถอดการตรวจทานรุ่นเก่า ๆ ที่เกี่ยวเนื่องกับการตรวจทานนี้ก่อนลบทิ้ง + flash: การตรวจทานถูกลบแล้ว + error: มีความผิดพลาดขณะลบการตรวจทานนี้ +... diff --git a/config/locales/tl.yml b/config/locales/tl.yml index a7cf3f1c3..55644dc7c 100644 --- a/config/locales/tl.yml +++ b/config/locales/tl.yml @@ -8,6 +8,7 @@ # Author: Jewel457 # Author: Jojit fb # Author: KahitAnongPangalan +# Author: LR Guanzon # Author: Leeheonjin # Author: Macofe # Author: 아라 @@ -91,18 +92,31 @@ tl: editor: default: Likas na pagtatakda (kasalukuyang %{name}) potlatch: - name: Pagbibigay-daan 1 - description: Pagbibigay-daan 1 (patnugot na nasa loob ng pantingin-tingin) + name: Potlatch 1 + description: Potlatch 1 (patnugot na nasa loob ng pantingin-tingin) + id: + name: iD + description: iD (patnugot na nasa loob ng pantingin-tingin) potlatch2: - name: Pagbibigay-daan 2 - description: Pagbibigay-daan 2 (patnugot na nasa loob ng pantingin-tingin) + name: Potlatch 2 + description: Potlatch 2 (patnugot na nasa loob ng pantingin-tingin) remote: name: Pangmalayong Pantaban description: Pangmalayong Pantaban (JOSM o Merkaartor) browse: created: Nilikha closed: Isinara + created_html: Nilikha %{time} ang nakaraan + closed_html: Isinara %{time} ang nakaraan + created_by_html: Nilikha %{time} ang nakaraan ni + %{user} + deleted_by_html: Binura %{time} ang nakaraan ni + %{user} + edited_by_html: Binago %{time} ang nakaraan ni %{user} + closed_by_html: Isinara %{time} ang nakaraan ni + %{user} version: Bersyon + in_changeset: Pangkat ng pagbabago anonymous: Hindi nagpapakilala (anonimo) no_comment: (walang mga puna) part_of: Bahagi ng @@ -113,11 +127,15 @@ tl: changeset: title: 'Pangkat ng pagbabago: %{id}' belongs_to: May-akda + comment: Mga puna (%{count}) + hidden_commented_by: Nakatagong puna mula kay %{user} %{when} + ang nakaraan changesetxml: XML ng pangkat ng pagbabago osmchangexml: XML ng osmChange feed: title: '%{id} ng pangkat ng pagbabago' title_comment: '%{id} ng angkat ng pagbabago - %{comment}' + join_discussion: Lumagda para sumali sa talakayan relation: members: Mga kasapi relation_member: @@ -131,7 +149,7 @@ tl: entry: Kaugnayan %{relation_name} entry_role: Kaugnayan %{relation_name} (bilang %{relation_role}) not_found: - sorry: Paumanhin, ang %{type} na may ID na %{id}, ay hindi matagpuan. + sorry: 'Paumanhin, %{type} #%{id} ay hindi matagpuan.' type: node: buko way: daan @@ -163,8 +181,12 @@ tl: key: Ang pahina ng paglalarawan ng wiki para sa tatak na %{key} tag: Ang pahina ng paglalarawan ng wiki para sa tatak na %{key}=%{value} wikipedia_link: Ang %{page} ng artikulo sa Wikipedia + telephone_link: Tawagan ang %{phone_number} note: description: Paglalarawan + commented_by: Puna mula kay %{user} %{when} ang + nakaraan + hidden_by: Itinago ni %{user} %{when} ang nakaraan changeset: changeset_paging_nav: showing_page: Ika-%{page} na pahina @@ -186,10 +208,17 @@ tl: title_friend: Mga pangkat ng pagbabago ng mga kaibigan mo title_nearby: Mga pangkat ng pagbabago ng kalapit na mga tagagamit empty: Walang natagpuang mga aparato/gadyet. + empty_area: Walang pangkat ng pagbabago sa lugar na ito. + empty_user: Walang pangkat ng pagbabago mula sa tagagamit na ito. + no_more: Wala nang mga pangkat ng pagbabago ang nakita. + no_more_area: Wala nang mga pangkat ng pagbabago sa lugar na ito. + no_more_user: Wala nang mga pangkat ng pagbabago mula sa tagagamit na ito. load_more: Magkarga pa timeout: sorry: Paumanhin, ang talaan ng mga pangkat ng pagbabagong hiniling mo ay naging napakatagal bago nakuhang muli. + rss: + comment: 'Bagong puna sa pangkat ng pagbabago #%{changeset_id} ni %{author}' diary_entry: new: title: Bagong Pagpapasok sa Talaarawan @@ -235,7 +264,8 @@ tl: comment_link: Punahin ang pagpapasok na ito reply_link: Tumugon sa pagpapasok na ito comment_count: - one: 1 puna + zero: Wala pang mga puna + one: '%{count} puna' other: '%{count} mga puna' edit_link: Baguhin ang ipinasok na ito hide_link: Itago ang ipinasok na ito @@ -270,6 +300,7 @@ tl: newer_comments: Mas Bagong mga Pagpuna older_comments: Mas Lumang mga Puna export: + title: Iluwas start: area_to_export: Pook na Iluluwas manually_select: Kinakamay na pumili ng ibang lugar @@ -284,6 +315,8 @@ tl: too_large: body: Masyadong malaki ang lugar na ito upang mailuwas bilang Dato ng XML ng OpenStreetMap. Mangyaring lumapit o pumili ng isang mas maliit na pook. + overpass: + title: Overpass API other: title: Iba pang mga Pinagmulan options: Mga mapagpipilian @@ -302,7 +335,6 @@ tl: search: title: latlon: Mga kinalabasan mula sa Panloob - us_postcode: Mga kinalabasan mula sa Geocoder.us uk_postcode: Mga kinalabasan mula sa NPEMap / FreeThe Postcode ca_postcode: Mga kinalabasan mula sa Geocoder.CA @@ -324,6 +356,7 @@ tl: taxiway: Daanan ng Taksi terminal: Terminal amenity: + animal_shelter: Kanlungan ng hayop arts_centre: Lunduyan ng Sining atm: ATM bank: Bangko @@ -333,6 +366,7 @@ tl: bicycle_parking: Paradahan ng Bisikleta bicycle_rental: Arkilahan ng Bisikleta biergarten: Inuman ng Serbesa + boat_rental: Arkilahan ng Bangka brothel: Bahay-aliwan bureau_de_change: Tanggapang Palitan ng Pera bus_station: Himpilan ng Bus @@ -374,11 +408,14 @@ tl: library: Aklatan market: Pamilihan marketplace: Palengke + monastery: Monasteryo + motorcycle_parking: Paradahan ng Motorsiklo nightclub: Alibangbang nursery: Alagaan ng mga Bata nursing_home: Alagaan ng mga Matatanda office: Tanggapan parking: Paradahan + parking_entrance: Pasukan ng Paradahan pharmacy: Botika place_of_worship: Sambahan police: Pulis @@ -426,10 +463,14 @@ tl: building: "yes": Gusali craft: + brewery: Serbeserya carpenter: Anluwage gardener: Hardinero + painter: Pintor photographer: Litratista + tailor: Mananahi emergency: + ambulance_station: Istasyon ng Ambulansya phone: Teleponong Pangsakuna highway: abandoned: Pinabayaang daang-bayan @@ -465,6 +506,7 @@ tl: tertiary: Pampangatlong Kalsada tertiary_link: Pampangatlong Kalsada track: Pinak + traffic_signals: Mga Senyas sa Trapiko trail: Bulaos trunk: Pangunahing Ruta trunk_link: Pangunahing Ruta @@ -549,6 +591,8 @@ tl: water_park: Liwasang Tubigan "yes": Pampalipas oras man_made: + lighthouse: Parola + pipeline: Linya ng tubo tower: Tore works: Pabrika "yes": Gawa ng tao @@ -723,6 +767,7 @@ tl: sports: Tindahang Pampalakasan stationery: Tindahan ng Papel supermarket: Malaking Pamilihan + tailor: Mananahi toys: Tindahan ng Laruan travel_agency: Ahensiya ng Paglalakbay video: Tindahan ng Bidyo @@ -767,6 +812,8 @@ tl: wadi: Tuyot na Ilog waterfall: Talon weir: Pilapil + admin_levels: + level8: Hangganan ng Lungsod description: title: osm_nominatim: Kinalalagyan mula sa Nominatim @@ -795,6 +842,7 @@ tl: edit: Baguhin history: Kasaysayan export: Iluwas + export_data: Iluwas ang Datos gps_traces: Mga Bakas ng GPS gps_traces_tooltip: Pamahalaan ang mga Bakas ng GPS user_diaries: Mga Talaarawan ng mga Tagagamit @@ -802,10 +850,12 @@ tl: edit_with: Mamatnugot sa pamamagitan ng %{editor} tag_line: Ang Malayang Mapa sa Daigdig ng Wiki intro_header: Maligayang pagdating sa OpenStreetMap! + intro_text: Ang OpenStreetMap ay isang mapa ng mundo na nilikha ng mga taong katulad + mo at malayang gamitin sa ilalim ng isang bukas na lisensya. intro_2_create_account: Lumikha ng isang akawnt ng tagagamit partners_html: Ang pagpapasinaya ay sinusuportahan ng %{ucl}, %{ic} at %{bytemark}, at iba pang %{partners}. - partners_ucl: Ang Sentro ng UCL VR + partners_ucl: UCL partners_ic: Dalubhasaang Pang-imperyo Londres partners_bytemark: Pagpapasinaya ng Bytemark partners_partners: mga kawaksi @@ -818,7 +868,7 @@ tl: ng Uri ng Hardwer. help: Tulong about: Patungkol - copyright: Karapatang-ari at Lisensiya + copyright: Karapatang-ari community: Pamayanan community_blogs: Mga Blog ng Pamayanan community_blogs_title: Mga blog mula sa mga kasapi ng pamayanan ng OpenStreetMap @@ -915,7 +965,7 @@ tl: ng paglalathala ng Estado." contributors_gb_html: "Nagkakasiang mga Kaharian: Naglalaman ng Ordinansiya \nsa dato ng Pagsisiyasat © Karapatan sa Paglalathala - ng Korona at karapatan \nsa kalipunan ng dato 2010." + ng Korona at karapatan \nsa kalipunan ng dato 2010-12." contributors_footer_1_html: "Para sa karagdagang mga detalye ng mga ito, at iba pang pinanggalingan na ginamit \nupang mapainam ang OpenStreetMap, paki tingnan ang Pahina @@ -924,12 +974,21 @@ tl: ay hindi nagpapahiwatig na ang orihinal \nna tagapagbigay ng dato ay tumatangkilik sa OpenStreetMap, nagbibigay ng anumang garantiya, o \ntumatanggap ng anumang pananagutan." + infringement_title_html: Paglabag sa karapatang-ari + infringement_1_html: Ang mga tagapag-ambag ng OSM ay pinaalalahanan na huwag + magdagdag ng datos mula sa anumang mapagkukunan na may karapatang-ari na nakalaan + (halimbawa, Google Maps o naka-print na mga mapa) nang walang pahintulot mula + sa mga may hawak ng karapatang-ari. + trademarks_title_html: Mga Trademark welcome_page: title: Maligayang pagdating! whats_on_the_map: title: Anong nasa Mapa + rules: + title: Mga Patakaran! questions: title: May mga tanong? + start_mapping: Simulan ang Pagmamapa fixthemap: title: Mag-ulat ng problema/ Ayusin ang mapa how_to_help: @@ -937,15 +996,37 @@ tl: help_page: welcome: title: Maligayang pagdating sa OSM + irc: + title: IRC about_page: next: Kasunod + copyright_html: ©Mga tagapag-ambag
    ng OpenStreetMap + used_by: Ang %{name} ay nagpapatakbo ng dato ng mapa sa libu-libong mga website, + mga mobile na app, at aparatong hardware + lede_text: Ang OpenStreetMap ay nilikha ng isang komunidad ng mga nagmamapa na + nag-aambag at nagpapanatili ng dato tungkol sa mga kalsada, mga daanan, mga + kapihan, mga istasyon ng tren, at iba pa, sa buong mundo. + community_driven_html: |- + Ang komunidad ng OpenStreetMap ay iba-iba, masigasig, at lumalaki araw-araw. Ang aming mga tagapag-ambag ay binubuo ng mga tagahanga ng mapa, mga propesyonal ng GIS, mga inhinyero na nagpapatakbo sa mga server ng OSM, mga boluntaryo sa pagmamapa ng mga lugar na apektado ng kalamidad, at higit pa. + Upang matuto nang higit pa, tignan ang mga
    talaarawan ng mga tagagamit, mga blog ng komunidad, at ang websayt ng OSM Foundation. + open_data_title: Bukas na Dato + open_data_html: 'Ang OpenStreetMap ay bukas na datos: malaya kang gamitin + ito para sa anumang layunin hangga''t nagbigay ka ng kredito sa OpenStreetMap + at ang mga tagapag-ambag nito. Kung babaguhin mo o binuo mula sa data sa ilang + mga paraan, maaari mong ipamahagi ang mga resulta sa ilalim lamang ng parehong + lisensya. Tingnan ang pahina ng Karapatang-ari + at Lisensya para sa mga detalye.' + legal_html: |- + Ang site na ito at maraming iba pang mga kaugnay na serbisyo ay opisyal na pinatatakbo ng OpenStreetMap Foundation (OSMF) sa ngalan ng komunidad. Ang paggamit ng lahat ng mga serbisyo na pinatatakbo ng OSMF ay napapailalim sa aming Patakaran sa Tanggapang Paggamit at Patakaran sa Pagkapribado +
    + Mangyaring makipag-ugnay sa OSMF kung mayroon kang mga katanungan tungkol sa paglilisensya, karapatang-ari, o iba pang mga legal na isyu at katanungan. + partners_title: Mga Kawaksi notifier: diary_comment_notification: - subject: Si %{user} ng [OpenStreetMap] ay nagbigay ng puna sa ipinasok mo sa - talaarawan + subject: '[OpenStreetMap] Si %{user} ay nagbigay ng puna sa ipinasok mo sa talaarawan' hi: Kumusta %{to_user}, - header: 'Pinuna ni %{from_user} ang iyong kamakailang pagpapasok sa talaarawan - ng OpenStreetMap na may paksang %{subject}:' + header: 'Pinuna ni %{from_user} ang isang pagpapasok sa talaarawan ng OpenStreetMap + na may paksang %{subject}:' footer: Mababasa mo rin ang puna roon sa %{readurl} at maaari kang pumuna roon sa %{commenturl} o tumugon doon sa %{replyurl} message_notification: @@ -954,6 +1035,7 @@ tl: header: 'Nagpadala sa iyo si %{from_user} ng isang mensahe sa pamamagitan ng OpenStreetMap na may paksang %{subject}:' friend_notification: + hi: Kumusta %{to_user}, subject: Idinagdag ka ni %{user} ng [OpenStreetMap] bilang isang kaibigan had_added_you: Idinagdag ka ni %{user} bilang isang kaibigan doon sa OpenStreetMap. see_their_profile: Maaari mong makita ang kanilang balangkas sa %{userurl}. @@ -1004,7 +1086,13 @@ tl: click_the_link: Kung ikaw ito, mangyaring pindutin ang kawing na nasa ibaba upang itakdang muli ang hudyat mo. note_comment_notification: + anonymous: Isang di-nagpakilalang tagagamit + greeting: Kumusta, + changeset_comment_notification: + hi: Kumusta %{to_user}, greeting: Kumusta, + commented: + partial_changeset_without_comment: walang puna message: inbox: title: Kahon ng pumapasok @@ -1067,6 +1155,7 @@ tl: date: Petsa reply_button: Tumugon unread_button: Tatakan bilang hindi pa nababasa + delete_button: Burahin back: Bumalik to: Para kay wrong_user: Lumagda ka bilang si `%{user}' ngunit ang mensaheng hiniling mong @@ -1086,6 +1175,9 @@ tl: js_2: Ang OpenStreetMap ay gumagamit ng JavaScript para sa madulas nitong mapa. permalink: Permalink shortlink: Maikling kawing + license: + copyright: Karapatang-sipi ng OpenStreetMap at mga tagapag-ambag nito, sa + ilalim ng isang bukas na lisensya remote_failed: Nabigo ang pamamatnugot - tiyaking naikarga ang JOSM or Merkaartor at kung gumagana ang pagpipilian ng malayong pantaban edit: @@ -1185,6 +1277,7 @@ tl: private: Pribadong pagpunta destination: Pagpapapunta sa patutunguhan construction: Mga kalsadang ginagawa + bicycle_parking: Paradahan ng bisikleta toilets: Mga banyo richtext_area: edit: Baguhin @@ -1313,7 +1406,7 @@ tl: message: Pangkasalukuyang hindi makukuha ang sistema ng pagkakarga ng talaksang GPX offline: - heading: Hindi nakaugnay sa Internet na Imbakan ng GPX + heading: Hindi nakaugnay sa Internet ang imbakan ng GPX message: Pangkasalukuyang hindi makukuha ang sistema ng pagkakarga at pag-iimbak ng talaksang GPX. application: @@ -1324,6 +1417,8 @@ tl: not_a_moderator: Kailangan mong maging isang tagapamagitan upang maisagawa ang galaw na iyan. setup_user_auth: + blocked_zero_hour: Mayroon kang isang importanteng mensahe sa websayt ng OpenStreetMap. + Kailangan mong basahin ang mensahe bago mo masagip ang iyong mga pagbabago. blocked: Hinadlangan ang pagpunta mo sa API. Mangyaring lumagda sa ugnayang-mukha ng web upang makaalam ng marami pa. need_to_see_terms: Pansamantalang inantala ang pagpunta mo sa API. Mangyaring @@ -1358,8 +1453,8 @@ tl: url: 'URL ng Kahalip ng Kahilingan:' access_url: 'URL ng Kahalip ng Pagpapapunta:' authorize_url: 'Payagan ang URL:' - support_notice: Tinatangkilik namin ang HMAC-SHA1 (iminumungkahi) pati na ang - tekstong lantad na nasa pamamaraang ssl. + support_notice: Sinusuportahan namin ang mga lagda ng HMAC-SHA1 (iminumungkahi) + at RSA-SHA1. edit: Baguhin ang mga Detalye delete: Burahin ang Kliyente confirm: Natitiyak mo ba? @@ -1539,9 +1634,8 @@ tl: spam score: 'Puntos ng Basurang Liham:' description: Paglalarawan user location: Kinalalagyan ng tagagamit - if set location: Kapat itinakda mo ang kinalalagyan mo, isang marilag na mapa - at mga abubot ang lilitaw dito. Maitatakda mo ang iyong kinalalagyan ng tahanan - sa iyong pahina ng %{settings_link}. + if set location: Itakda ang iyong lokasyon ng bahay sa pahinang %{settings_link} + upang makita ang mga kalapit na tagagamit. settings_link_text: mga pagtatakda your friends: Mga kaibigan mo no friends: Hindi ka pa nagdaragdag ng sinumang mga kaibigan. @@ -1565,17 +1659,14 @@ tl: activate_user: Pasiglahin ang tagagamit na ito deactivate_user: Tanggalin ang prebelehiyo ng 'User' confirm_user: Tiyakin ang tagagamit na ito - hide_user: itago ang tagagamit na ito - unhide_user: huwag itago ang tagagamit na ito - delete_user: burahin ang tagagamit na ito + hide_user: Itago ang Tagagamit na ito + unhide_user: Huwag itago ang Tagagamit na ito + delete_user: Burahin ang Tagagamit na ito confirm: Tiyakin - friends_changesets: Tumingin-tingin sa lahat ng pagtatakda ng mga pagbabago - ng mga kaibigan - friends_diaries: Tumingin-tingin sa lahat ng mga lahok ng mga kaibigan - nearby_changesets: Tumingin-tingin sa lahat ng mga pagtatakda ng pagbabago ng - kanugnog na mga tagagamit - nearby_diaries: Tumingin-tingin sa lahat ng mga inilahok sa talaarawan ng kanugnog - na mga tagagamit + friends_changesets: mga pagbabago ng mga kaibigan + friends_diaries: mga lahok ng mga kaibigan + nearby_changesets: mga pagtatakda ng pagbabago mula sa kalapit na mga tagagamit + nearby_diaries: mga inilahok sa talaarawan ng kalapit na mga tagagamit popup: your location: Kinalalagyan mo nearby mapper: Malapit na tagapagmapa @@ -1586,6 +1677,7 @@ tl: current email address: 'Pangkasalukuyang Tirahan ng E-liham:' new email address: 'Bagong Tirahan ng E-liham:' email never displayed publicly: (hindi kailanman ipinapakita sa madla) + external auth: 'Panlabas na Pagpapatunay:' openid: link: http://wiki.openstreetmap.org/wiki/OpenID link text: ano ba ito? @@ -1626,6 +1718,8 @@ tl: gravatar: gravatar: Gamitin ang Gravatar link text: ano ba ito? + disabled: Hindi na pinagana ang Gravatar. + enabled: Pinagana ang pagpapakita ng iyong Gravatar. new image: Magdagdag ng isang larawan keep image: Panatilihin ang kasalukuyang larawan delete image: Tanggalin ang pangkasalukuyang larawan @@ -1652,7 +1746,7 @@ tl: button: Tiyakin success: Natiyak ang akawnt mo, salamat sa pagpapatala! already active: Natiyak na ang akawnt na ito. - unknown token: Tila hindi yata umiiral ang kahalip na iyan. + unknown token: Tila lumipas o hindi umiiral ang kahalip na iyan. confirm_resend: success: Nagpadala kami ng isang paunawa ng pagtitiyak sa %{email} at kapag tiniyak mo nang iyong akawnt sa lalong madaling panahon maaari ka nang magsimula @@ -1680,7 +1774,7 @@ tl: failed: Paumanhin, nabigong maidagdag si %{name} bilang isang kaibigan. already_a_friend: Kaibigan ka na ni %{name}. remove_friend: - heading: Tanggalin si %{user} bilang isang kaibigan? + heading: Tanggalin bilang isang kaibigan si %{user}? button: Tanggalin bilang kaibigan success: Si %{name} ay tinanggal mula sa mga kaibigan mo. not_a_friend: Si %{name} ay hindi isa sa mga kaibigan mo. @@ -1837,6 +1931,7 @@ tl: heading: '%{block_on} hinadlangan ni %{block_by}' time_future: Magwawakas sa %{time} time_past: Nagwakas noong %{time} na ang nakalilipas + ago: '%{time} ang nakaraan' status: Kalagayan show: Ipakita edit: Baguhin @@ -1848,26 +1943,42 @@ tl: needs_view: Ang tagagamit ay kailangang lumagda muna bago mahawi ang hadlang na ito. note: + rss: + commented: bagong puna (malapit sa %{place}) mine: + id: Id description: Paglalarawan created_at: Nilikha Noong + last_changed: Huling binago + ago_html: '%{when} ang nakaraan' javascripts: close: Isara share: title: Ibahagi cancel: Huwag ituloy short_url: Maiksing URL + paste_html: Idikit ang HTML na ibabaon sa websayt map: + zoom: + in: Lumapit base: standard: Pamantayan cycle_map: Mapa ng Pagbibisikleta transport_map: Mapa ng Transportasyon + layers: + data: Dato ng Mapa + copyright: © Mga tagapag-ambag ng OpenStreetMap site: edit_tooltip: Baguhin ang mapa edit_disabled_tooltip: Lumapit upang baguhin ang mapa + map_data_zoom_in_tooltip: Lumapit upang makita ang datos ng mapa notes: show: hide: Itago + resolve: Lutasin + comment_and_resolve: Pumuna at Lutasin + query: + relation: Kaugnayan redaction: edit: description: Paglalarawan diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 60be65ec1..fdc614cab 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -403,7 +403,6 @@ tr: search: title: latlon: OSM'in sonuçları - us_postcode: Geocoder.us'ın sonuçları uk_postcode: FreeThe Postcode sonuçları (İngiltere) ca_postcode: Geocoder.CA'dan sonuçları @@ -1098,6 +1097,7 @@ tr: header: 'OpenStreetMap kullanıcı %{from_user} sana %{subject} konulu bir mesaj gönderdi:' friend_notification: + hi: Merhaba %{to_user}, subject: '[OpenStreetMap] kullanıcı %{user} seni arkadaş olarak ekledi' had_added_you: Kullanıcı %{user} seni arkadaş olarak OpenStreetMap'te ekledi. see_their_profile: '%{userurl} üzerinden profillerini görebilirsiniz.' @@ -1115,10 +1115,14 @@ tr: subject: '[OpenStreetMap]''e hoşgeldin' greeting: Merhaba! created: Birisi (umarım sen) %{site_url} sitesinde yeni bir hesap açtı. + welcome: Hesabınızı doğruladıktan sonra size, başlamanız için gereken bazı ek + bilgiler vereceğiz. email_confirm: subject: '[OpenStreetMap] E-posta adresi onaylama mesajı' email_confirm_plain: greeting: Merhaba, + hopefully_you: Birisi (umarız ki siz) %{server_url} adresindeki e-posta adresinizi + %{new_address} olarak değiştirmek istiyor. click_the_link: Bu e-posta adresi sana aitse onaylamak için aşağıdaki bağlantıyı tıkla. email_confirm_html: @@ -1131,10 +1135,14 @@ tr: subject: '[OpenStreetMap] Parola sıfırlama isteği' lost_password_plain: greeting: Merhaba, + hopefully_you: Birisi (muhtemelen siz) bu e-posta adresinin openstreetmap.org + hesabındaki şifresinin sıfırlanmasını istedi. click_the_link: Bu sizseniz, lütfen parolanızı sıfırlamak için aşağıdaki bağlantıya tıklayın. lost_password_html: greeting: Merhaba, + hopefully_you: Birisi (muhtemelen siz) bu e-posta adresinin openstreetmap.org + hesabındaki şifresinin sıfırlanmasını istedi. click_the_link: Bu sizseniz, lütfen parolanızı sıfırlamak için aşağıdaki bağlantıya tıklayın. note_comment_notification: @@ -1143,6 +1151,27 @@ tr: commented: subject_own: '[OpenStreetMap] notlarından birisini %{commenter} tarafından yorumlandı' + subject_other: '[OpenStreetMap] %{commenter}, ilgilendiğiniz bir not üzerinde + yorum yaptı.' + your_note: '%{commenter}, %{place} yakınlarındaki harita notlarınızdan biri + üzerinde bir yorum yaptı.' + commented_note: '%{commenter}, yorum yaptığınız bir harita notu üzerine yorum + yaptı. Bu not %{place} yakınlarında.' + closed: + subject_own: '[OpenStreetMap] %{commenter}, notlarınızdan birini çözdü.' + subject_other: '[OpenStreetMap] %{commenter}, ilgilendiğiniz notlardan birini + çözdü' + your_note: '%{commenter}, %{place} yakınlarındaki harita notlarınızdan birini + çözdü.' + commented_note: '%{commenter} yorum yaptığınız harita notlarınızdan birini + çözdü. Bu not %{place} yakınlarında.' + reopened: + subject_own: '[OpenStreetMap] %{commenter}, notlarınızdan birini yeniden etkinleştirdi.' + subject_other: '[OpenStreetMap] %{commenter}, ilgilendiğiniz bir notu yeniden + etkinleştirdi' + your_note: '%{commenter}, %{place} yakınlarındaki harita notlarınızdan birini + yeniden etkinleştirdi.' + details: Not hakkındaki ayrıntılı bilgiler %{url} bağlantısında görülebilir. changeset_comment_notification: hi: Merhaba %{to_user}, greeting: Merhaba, @@ -1193,6 +1222,7 @@ tr: date: Tarih reply_button: Yanıtla unread_button: Okunmadı olarak işaretle + delete_button: Sil back: Geri to: Alıcı sent_message_summary: @@ -1204,15 +1234,21 @@ tr: deleted: Mesaj silindi site: index: + js_1: JavaScript desteklemeyen bir tarayıcı kullanıyorsunuz ya da JavaScript + devre dışı bırakılmış. js_2: OpenStreetMap harita gösterim için JavaScript kullanıyor. permalink: Kalıcı Bağlantı shortlink: Kısa Bağlantı createnote: Bir not ekle license: copyright: Telif Hakkı OpenStreetMap ve katılımcılar, açık lisans altında + remote_failed: Düzenleme başarısız - JOSM veya Merkaartor'un yüklendiğinden + ve uzaktan kontrol seçeneğinin etkinleştirildiğinden emin olun. edit: user_page_link: kullanıcı sayfası anon_edits: (%{link}) + potlatch2_unsaved_changes: Kaydedilmemiş değişiklikleriniz var. (Potlatch 2'de + kaydetmek için kaydet'e tıklamalısınız.) id_not_configured: iD yapılandırılmamış no_iframe_support: Bu özelliği görüntülemek için gerekli olan HTML iframe tarayıcınız desteklemiyor. @@ -1288,6 +1324,8 @@ tr: private: Özel giriş destination: Hedef noktası construction: yapım aşamasında yolu + bicycle_shop: Bisikletçi + bicycle_parking: Bisiklet parkı toilets: Tuvaletler richtext_area: edit: Düzenle @@ -1401,6 +1439,9 @@ tr: heading: GPX Yükleme Servisi Çevrimdışı georss: title: OpenStreetMap GPS İzleri + application: + require_moderator: + not_a_moderator: Bu eylemi gerçekleştirebilmek için moderatör olmalısınız. oauth: oauthorize_success: verification: Doğrulama kodu %{code}. diff --git a/config/locales/uk.yml b/config/locales/uk.yml index d29b62c08..d7b8dd4cb 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -412,7 +412,6 @@ uk: search: title: latlon: Результати від OpenStreetMap - us_postcode: Результати від Geocoder.us uk_postcode: Результати від NPEMap / FreeThe Postcode ca_postcode: Результати від Geocoder.CA @@ -1420,6 +1419,7 @@ uk: date: Дата reply_button: Відповісти unread_button: Позначити як непрочитане + delete_button: Видалити back: Назад to: 'Кому:' wrong_user: Ви увійшли як „%{user}“, але повідомлення, яке ви хочете прочитати, @@ -2392,6 +2392,7 @@ uk: ascend: Вгору engines: graphhopper_bicycle: Велосипед (GraphHopper) + graphhopper_car: Автівкою (GraphHopper) graphhopper_foot: Пішки (GraphHopper) mapquest_bicycle: Велосипед (MapQuest) mapquest_car: Машина (MapQuest) diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 71d197d67..252fbfc36 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -258,7 +258,7 @@ vi: diary_entry: new: title: Mục Nhật ký Mới - publish_button: Xuất bản + publish_button: Đăng list: title: Các Nhật ký Cá nhân title_friends: Các nhật ký của bạn bè @@ -381,7 +381,6 @@ vi: search: title: latlon: Kết quả nội bộ - us_postcode: Kết quả Geocoder.us uk_postcode: Kết quả NPEMap / FreeThe Postcode ca_postcode: Kết quả Geocoder.CA @@ -948,7 +947,7 @@ vi: intro_2_create_account: Mở tài khoản mới partners_html: Dịch vụ nhờ sự hỗ trợ hosting của %{ucl}, %{ic}, và %{bytemark}, cũng như %{partners} khác. - partners_ucl: Trung tâm VR tại UCL + partners_ucl: UCL partners_ic: Đại học Hoàng gia Luân Đôn partners_bytemark: Bytemark Hosting partners_partners: các công ty bảo trợ @@ -1222,6 +1221,7 @@ vi: footer_html: Bạn cũng có thể đọc tin nhắn này tại %{readurl} và có thể trả lời tại %{replyurl} friend_notification: + hi: Chào %{to_user}, subject: '[OpenStreetMap] %{user} đã kết bạn với bạn' had_added_you: '%{user} đã thêm bạn vào danh sách bạn tại OpenStreetMap.' see_their_profile: Có thể xem trang cá nhân của họ tại %{userurl}. @@ -1378,6 +1378,7 @@ vi: date: Ngày reply_button: Trả lời unread_button: Đánh dấu là chưa đọc + delete_button: Xóa back: Quay lại to: Tới wrong_user: Bạn đã đăng nhập dùng tài khoản “%{user}” nhưng vừa yêu cầu đọc @@ -1675,6 +1676,8 @@ vi: invalid: Dấu hiệu cho phép không hợp lệ. revoke: flash: Bạn đã thu hồi dấu của %{application} + permissions: + missing: Bạn chưa cấp phép cho ứng dụng sử dụng chức năng này oauth_clients: new: title: Đăng ký chương trình mới @@ -1960,7 +1963,8 @@ vi: enabled: Kích hoạt. Không vô danh và có thể sửa đổi dữ liệu. enabled link: http://wiki.openstreetmap.org/wiki/Anonymous_edits?uselang=vi enabled link text: đây là gì? - disabled: Vô hiệu. Không thể sửa đổi dữ liệu. all previous edits are anonymous. + disabled: Vô hiệu. Không thể sửa đổi dữ liệu. Tất cả các sửa đổi truớc là + vô danh. disabled link text: tại sao không thể sửa đổi? public editing note: heading: Sửa đổi công khai @@ -2326,8 +2330,10 @@ vi: edit_help: Di chuyển bản đồ và phóng to một vị trí mà bạn muốn sửa đổi, rồi nhấn chuột vào đây. directions: + ascend: Lên engines: graphhopper_bicycle: Xe đạp (GraphHopper) + graphhopper_car: Xe hơi (GraphHopper) graphhopper_foot: Đi bộ (GraphHopper) mapquest_bicycle: Xe đạp (MapQuest) mapquest_car: Xe hơi (MapQuest) @@ -2336,6 +2342,7 @@ vi: mapzen_bicycle: Xe đạp (Mapzen) mapzen_car: Xe hơi (Mapzen) mapzen_foot: Đi bộ (Mapzen) + descend: Xuống directions: Chỉ đường distance: Tầm xa errors: diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 42e893804..8b43a3338 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -11,6 +11,7 @@ # Author: Impersonator 1 # Author: Jienus # Author: Jiwei +# Author: Koalberry # Author: Liangent # Author: Liuxinyu970226 # Author: Mmyangfl @@ -393,7 +394,6 @@ zh-CN: search: title: latlon: 来自内部的结果 - us_postcode: 来自 Geocoder.us 的结果 uk_postcode: 来自 NPEMap / FreeThe Postcode 的结果 ca_postcode: 来自 Geocoder.CA 的结果 @@ -961,7 +961,7 @@ zh-CN: intro_header: 欢迎访问 OpenStreetMap! intro_text: OpenStreetMap 是一个世界地图,由像您一样的人们所构筑,可依据开放许可协议自由使用。 intro_2_create_account: 创建用户账户 - partners_html: 主机由%{ucl}、%{bytemark}和%{ic},以及其他%{partners}所支持。 + partners_html: 主机由%{ucl}、%{bytemark}、%{ic},以及其他%{partners}所支持。 partners_ucl: 伦敦大学学院 partners_ic: 伦敦帝国学院 partners_bytemark: Bytemark主机 @@ -1016,8 +1016,7 @@ zh-CN: more_title_html: 了解更多 more_1_html: |- 请在OSMF许可协议页面和法律常见问题阅读更多关于使用我们的数据,以及如何表明我们是作者的信息。 + href="http://osmfoundation.org/Licence">OSMF许可协议页面阅读更多关于使用我们的数据,以及如何表明我们是作者的信息。 more_2_html: 尽管 OpenStreetMap 开放数据,但是我们无法为第三方提供免费的地图 API。详见我们的 API使用政策、地图图块使用政策及名称服务使用政策。 @@ -1134,10 +1133,10 @@ zh-CN: local_knowledge_html: OpenStreetMap 强调使用本地知识。贡献者们使用航空图像、GPS 设备与传统的地区地图来确保 OSM 的精确性和时效性。 community_driven_title: 社区驱动 - community_driven_html: |- - OpenStreetMap 是一个多元化的社区,它充满激情,并且每天都在成长。我们的参与者包括地图制作爱好者,地理信息系统(GIS)从业人员,维护 OSM 服务器的工程师,标注灾害区域的人道主义自愿者,已经其他很多各界人士。 - 想更多的了解社区请参见用户日记, - 社区博客,以及 OSM 基金会 网站。 + community_driven_html: OpenStreetMap 是一个多元化的社区,它充满激情,并且每天都在成长。我们的参与者包括地图制作爱好者,地理信息系统(GIS)从业人员,维护 + OSM 服务器的工程师,标注灾害区域的人道主义自愿者,已经其他很多各界人士。想更多的了解社区请参见OpenStreetMap博客、用户日记、社区博客,以及 + OSM 基金会网站。 open_data_title: 开放数据 open_data_html: OpenStreetMap 是开源数据:只要您表明使用了 OpenStreetMap 并承认其贡献者的工作,您就可以使用 OpenStreetMap。如果您改变或者使用这些数据,您必须按照相同的版权协议发布结果。详情请参见版权协议。 @@ -1290,6 +1289,7 @@ zh-CN: date: 日期 reply_button: 回复 unread_button: 标记为未读 + delete_button: 删除 back: 返回 to: 收件人 wrong_user: 您已经以 '%{user}' 的身份登录,但是您想要阅读的消息并非寄给这个用户。请以正确的用户身份登录以阅读这个消息。 @@ -1335,7 +1335,7 @@ zh-CN: get_directions_title: 查找两点之间的方向 from: 从 to: 至 - where_am_i: 我在哪里? + where_am_i: 这是哪里? where_am_i_title: 使用搜索引擎说明当前位置 submit_text: 提交 key: @@ -1445,7 +1445,7 @@ zh-CN: start_coord: 起始坐标: map: 地图 edit: 编辑 - owner: 所有人: + owner: 所有者: description: 说明: tags: 标签: tags_help: 用逗号分隔 @@ -1482,7 +1482,7 @@ zh-CN: start_coordinates: 起始坐标: map: 地图 edit: 编辑 - owner: 所有人: + owner: 所有者: description: 说明: tags: 标签: none: 无 @@ -2125,7 +2125,7 @@ zh-CN: header: 地图图层 notes: 地图笔记 data: 地图数据 - gps: 公开 GPS 痕迹 + gps: 公开 GPS 轨迹 overlays: 启用解决地图问题的覆盖层 title: 图层 copyright: © OpenStreetMap 贡献者 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index a4b2c59a5..70fbd5a57 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -1,6 +1,7 @@ # Messages for Traditional Chinese (中文(繁體)‎) # Exported from translatewiki.net # Export driver: phpyaml +# Author: A2093064 # Author: Anakmalaysia # Author: Cwlin0416 # Author: EagerLin @@ -391,7 +392,6 @@ zh-TW: search: title: latlon: 來自內部的結果 - us_postcode: 來自Geocoder.us的結果 uk_postcode: 來自NPEMap / FreeThe Postcode的結果 ca_postcode: 來自Geocoder.CA的結果 osm_nominatim: 來自OpenStreetMap @@ -1314,6 +1314,7 @@ zh-TW: date: 日期 reply_button: 回覆 unread_button: 標記為未讀 + delete_button: 刪除 back: 返回 to: 收件者 wrong_user: 您已經以 "%{user}" 的身份登入,但是您想要閱讀的訊息並非寄給那個使用者。請以正確的使用者身份登入以閱讀它。 @@ -1620,7 +1621,7 @@ zh-TW: my_tokens: 我授權的應用程式 list_tokens: 下列密鑰已核發給您名下的應用程式: application: 應用程式名稱 - issued_at: 簽發於 + issued_at: 已發於 revoke: 撤銷! my_apps: 我的用戶端應用程式 no_apps: 您是否有想要註冊以使用於 %{oauth} 標準的應用程式?您必須先註冊您的網頁應用程式,才能對這個服務進行 OAuth 要求。 @@ -1837,7 +1838,7 @@ zh-TW: current email address: 目前的電子郵件地址: new email address: 新的電子郵件地址: email never displayed publicly: (永遠不公開顯示) - external auth: 外部認証: + external auth: 外部認證: openid: link: HTTP://wiki.openstreetmap.org/wiki/OpenID link text: 這是什麼? @@ -1941,8 +1942,8 @@ zh-TW: body: "

    \n對不起,您的帳號已因可疑\n活動被自動暫停。 \n

    \n

    \n這項決定將在短期內由行政員審核,或是如果你想討論這一點\n,可以聯絡 %{webmaster}。 \n

    " auth_failure: - connection_failed: 連線至認証供應者失敗 - invalid_credentials: 無效的認証憑証 + connection_failed: 連線至認證供應者失敗 + invalid_credentials: 無效的認證憑證 no_authorization_code: 無授權碼 unknown_signature_algorithm: 不明的簽章演算法 invalid_scope: 無效範圍 diff --git a/config/routes.rb b/config/routes.rb index 277bd34ea..8a5dca166 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -246,7 +246,6 @@ OpenStreetMap::Application.routes.draw do # geocoder match "/search" => "geocoder#search", :via => :get, :as => :search match "/geocoder/search_latlon" => "geocoder#search_latlon", :via => :get - match "/geocoder/search_us_postcode" => "geocoder#search_us_postcode", :via => :get match "/geocoder/search_uk_postcode" => "geocoder#search_uk_postcode", :via => :get match "/geocoder/search_ca_postcode" => "geocoder#search_ca_postcode", :via => :get match "/geocoder/search_osm_nominatim" => "geocoder#search_osm_nominatim", :via => :get diff --git a/db/migrate/001_create_osm_db.rb b/db/migrate/001_create_osm_db.rb index 3935fb6b0..2edb658e4 100644 --- a/db/migrate/001_create_osm_db.rb +++ b/db/migrate/001_create_osm_db.rb @@ -1,6 +1,6 @@ require "migrate" -class CreateOsmDb < ActiveRecord::Migration +class CreateOsmDb < ActiveRecord::Migration[5.0] def self.up create_table "current_nodes", :id => false do |t| t.column "id", :bigint, :null => false diff --git a/db/migrate/002_cleanup_osm_db.rb b/db/migrate/002_cleanup_osm_db.rb index 0710417e3..92a4f671a 100644 --- a/db/migrate/002_cleanup_osm_db.rb +++ b/db/migrate/002_cleanup_osm_db.rb @@ -1,6 +1,6 @@ require "migrate" -class CleanupOsmDb < ActiveRecord::Migration +class CleanupOsmDb < ActiveRecord::Migration[5.0] def self.up change_column "current_nodes", "latitude", :float, :limit => 53, :null => false change_column "current_nodes", "longitude", :float, :limit => 53, :null => false diff --git a/db/migrate/003_sql_session_store_setup.rb b/db/migrate/003_sql_session_store_setup.rb index 9531ccc5e..47c711daf 100644 --- a/db/migrate/003_sql_session_store_setup.rb +++ b/db/migrate/003_sql_session_store_setup.rb @@ -1,6 +1,6 @@ require "migrate" -class SqlSessionStoreSetup < ActiveRecord::Migration +class SqlSessionStoreSetup < ActiveRecord::Migration[5.0] def self.up create_table "sessions" do |t| t.column "session_id", :string diff --git a/db/migrate/004_user_enhancements.rb b/db/migrate/004_user_enhancements.rb index f45d441ab..68c6cd1de 100644 --- a/db/migrate/004_user_enhancements.rb +++ b/db/migrate/004_user_enhancements.rb @@ -1,6 +1,6 @@ require "migrate" -class UserEnhancements < ActiveRecord::Migration +class UserEnhancements < ActiveRecord::Migration[5.0] def self.up add_column "diary_entries", "latitude", :float, :limit => 53 add_column "diary_entries", "longitude", :float, :limit => 53 diff --git a/db/migrate/005_tile_tracepoints.rb b/db/migrate/005_tile_tracepoints.rb index 00e5af293..2433c3f4f 100644 --- a/db/migrate/005_tile_tracepoints.rb +++ b/db/migrate/005_tile_tracepoints.rb @@ -1,6 +1,6 @@ require "migrate" -class TileTracepoints < ActiveRecord::Migration +class TileTracepoints < ActiveRecord::Migration[5.0] def self.up add_column "gps_points", "tile", :bigint add_index "gps_points", ["tile"], :name => "points_tile_idx" diff --git a/db/migrate/006_tile_nodes.rb b/db/migrate/006_tile_nodes.rb index 29200d06a..138168a7b 100644 --- a/db/migrate/006_tile_nodes.rb +++ b/db/migrate/006_tile_nodes.rb @@ -1,35 +1,35 @@ require "migrate" -class TileNodes < ActiveRecord::Migration +class TileNodes < ActiveRecord::Migration[5.0] def self.upgrade_table(from_table, to_table, model) if ENV["USE_DB_FUNCTIONS"] - execute <<-END_SQL + execute <<-SQL INSERT INTO #{to_table} (id, latitude, longitude, user_id, visible, tags, timestamp, tile) SELECT id, ROUND(latitude * 10000000), ROUND(longitude * 10000000), user_id, visible, tags, timestamp, tile_for_point(CAST(ROUND(latitude * 10000000) AS INTEGER), CAST(ROUND(longitude * 10000000) AS INTEGER)) FROM #{from_table} - END_SQL + SQL else - execute <<-END_SQL + execute <<-SQL INSERT INTO #{to_table} (id, latitude, longitude, user_id, visible, tags, timestamp, tile) SELECT id, ROUND(latitude * 10000000), ROUND(longitude * 10000000), user_id, visible, tags, timestamp, 0 FROM #{from_table} - END_SQL + SQL model.all.each(&:save!) end end def self.downgrade_table(from_table, to_table) - execute <<-END_SQL + execute <<-SQL INSERT INTO #{to_table} (id, latitude, longitude, user_id, visible, tags, timestamp) SELECT id, latitude / 10000000, longitude / 10000000, user_id, visible, tags, timestamp FROM #{from_table} - END_SQL + SQL end def self.up diff --git a/db/migrate/007_add_relations.rb b/db/migrate/007_add_relations.rb index 12684abc8..258f1c5bc 100644 --- a/db/migrate/007_add_relations.rb +++ b/db/migrate/007_add_relations.rb @@ -1,6 +1,6 @@ require "migrate" -class AddRelations < ActiveRecord::Migration +class AddRelations < ActiveRecord::Migration[5.0] def self.up # enums work like strings but are more efficient create_enumeration :nwr_enum, %w[Node Way Relation] diff --git a/db/migrate/008_remove_segments.rb b/db/migrate/008_remove_segments.rb index 62f618abf..5c9bd1c39 100644 --- a/db/migrate/008_remove_segments.rb +++ b/db/migrate/008_remove_segments.rb @@ -1,6 +1,6 @@ require "migrate" -class RemoveSegments < ActiveRecord::Migration +class RemoveSegments < ActiveRecord::Migration[5.0] def self.up have_segs = select_value("SELECT count(*) FROM current_segments").to_i.nonzero? @@ -10,7 +10,7 @@ class RemoveSegments < ActiveRecord::Migration cmd = "db/migrate/008_remove_segments_helper" src = "#{cmd}.cc" if !File.exist?(cmd) || File.mtime(cmd) < File.mtime(src) - system("c++ -O3 -Wall `mysql_config --cflags --libs` " + + system("c++ -O3 -Wall `mysql_config --cflags --libs` " \ "#{src} -o #{cmd}") || raise end diff --git a/db/migrate/009_way_nodes_node_idx.rb b/db/migrate/009_way_nodes_node_idx.rb index ccbc9a5a2..dc4ca41ff 100644 --- a/db/migrate/009_way_nodes_node_idx.rb +++ b/db/migrate/009_way_nodes_node_idx.rb @@ -1,4 +1,4 @@ -class WayNodesNodeIdx < ActiveRecord::Migration +class WayNodesNodeIdx < ActiveRecord::Migration[5.0] def self.up add_index "way_nodes", ["node_id"], :name => "way_nodes_node_idx" end diff --git a/db/migrate/010_diary_comments.rb b/db/migrate/010_diary_comments.rb index ac0f5e23a..00912988e 100644 --- a/db/migrate/010_diary_comments.rb +++ b/db/migrate/010_diary_comments.rb @@ -1,6 +1,6 @@ require "migrate" -class DiaryComments < ActiveRecord::Migration +class DiaryComments < ActiveRecord::Migration[5.0] def self.up create_table "diary_comments", :id => false do |t| t.column "id", :bigserial, :primary_key => true, :null => false diff --git a/db/migrate/011_add_user_image.rb b/db/migrate/011_add_user_image.rb index 807e93d59..c25afb413 100644 --- a/db/migrate/011_add_user_image.rb +++ b/db/migrate/011_add_user_image.rb @@ -1,4 +1,4 @@ -class AddUserImage < ActiveRecord::Migration +class AddUserImage < ActiveRecord::Migration[5.0] def self.up add_column "users", "image", :text end diff --git a/db/migrate/012_add_admin_flag.rb b/db/migrate/012_add_admin_flag.rb index 24f2d4ed7..d409f9f1e 100644 --- a/db/migrate/012_add_admin_flag.rb +++ b/db/migrate/012_add_admin_flag.rb @@ -1,4 +1,4 @@ -class AddAdminFlag < ActiveRecord::Migration +class AddAdminFlag < ActiveRecord::Migration[5.0] def self.up add_column "users", "administrator", :boolean, :default => false, :null => false end diff --git a/db/migrate/013_add_email_valid.rb b/db/migrate/013_add_email_valid.rb index 8552c2733..4e9112957 100644 --- a/db/migrate/013_add_email_valid.rb +++ b/db/migrate/013_add_email_valid.rb @@ -1,4 +1,4 @@ -class AddEmailValid < ActiveRecord::Migration +class AddEmailValid < ActiveRecord::Migration[5.0] def self.up add_column "users", "email_valid", :boolean, :default => false, :null => false User.update_all("email_valid = (active != 0)") # email_valid is :boolean, but active is :integer. "email_valid = active" (see r11802 or earlier) will fail for stricter dbs than mysql diff --git a/db/migrate/014_add_new_email.rb b/db/migrate/014_add_new_email.rb index 4077b7ca3..e9e547738 100644 --- a/db/migrate/014_add_new_email.rb +++ b/db/migrate/014_add_new_email.rb @@ -1,4 +1,4 @@ -class AddNewEmail < ActiveRecord::Migration +class AddNewEmail < ActiveRecord::Migration[5.0] def self.up add_column "users", "new_email", :string end diff --git a/db/migrate/015_add_user_visible.rb b/db/migrate/015_add_user_visible.rb index 869f24c37..561c767c3 100644 --- a/db/migrate/015_add_user_visible.rb +++ b/db/migrate/015_add_user_visible.rb @@ -1,4 +1,4 @@ -class AddUserVisible < ActiveRecord::Migration +class AddUserVisible < ActiveRecord::Migration[5.0] def self.up add_column "users", "visible", :boolean, :default => true, :null => false User.update_all(:visible => true) diff --git a/db/migrate/016_add_creation_ip.rb b/db/migrate/016_add_creation_ip.rb index 341566940..0bcdb856f 100644 --- a/db/migrate/016_add_creation_ip.rb +++ b/db/migrate/016_add_creation_ip.rb @@ -1,4 +1,4 @@ -class AddCreationIp < ActiveRecord::Migration +class AddCreationIp < ActiveRecord::Migration[5.0] def self.up add_column "users", "creation_ip", :string end diff --git a/db/migrate/017_add_gpx_indexes.rb b/db/migrate/017_add_gpx_indexes.rb index 1778dcc75..72d28bb2d 100644 --- a/db/migrate/017_add_gpx_indexes.rb +++ b/db/migrate/017_add_gpx_indexes.rb @@ -1,4 +1,4 @@ -class AddGpxIndexes < ActiveRecord::Migration +class AddGpxIndexes < ActiveRecord::Migration[5.0] def self.up add_index "gpx_files", ["user_id"], :name => "gpx_files_user_id_idx" add_index "gpx_file_tags", ["tag"], :name => "gpx_file_tags_tag_idx" diff --git a/db/migrate/018_create_acls.rb b/db/migrate/018_create_acls.rb index e5a524dc1..f4fb0799d 100644 --- a/db/migrate/018_create_acls.rb +++ b/db/migrate/018_create_acls.rb @@ -1,6 +1,6 @@ require "migrate" -class CreateAcls < ActiveRecord::Migration +class CreateAcls < ActiveRecord::Migration[5.0] def self.up create_table "acls", :id => false do |t| t.column "id", :primary_key, :null => false diff --git a/db/migrate/019_add_timestamp_indexes.rb b/db/migrate/019_add_timestamp_indexes.rb index c6b3bc7c2..8122fe1b2 100644 --- a/db/migrate/019_add_timestamp_indexes.rb +++ b/db/migrate/019_add_timestamp_indexes.rb @@ -1,4 +1,4 @@ -class AddTimestampIndexes < ActiveRecord::Migration +class AddTimestampIndexes < ActiveRecord::Migration[5.0] def self.up add_index :current_ways, :timestamp, :name => :current_ways_timestamp_idx add_index :current_relations, :timestamp, :name => :current_relations_timestamp_idx diff --git a/db/migrate/020_populate_node_tags_and_remove.rb b/db/migrate/020_populate_node_tags_and_remove.rb index 0fd1dc564..2a81a2b9a 100644 --- a/db/migrate/020_populate_node_tags_and_remove.rb +++ b/db/migrate/020_populate_node_tags_and_remove.rb @@ -1,6 +1,6 @@ require "migrate" -class PopulateNodeTagsAndRemove < ActiveRecord::Migration +class PopulateNodeTagsAndRemove < ActiveRecord::Migration[5.0] def self.up have_nodes = select_value("SELECT count(*) FROM current_nodes").to_i.nonzero? @@ -10,7 +10,7 @@ class PopulateNodeTagsAndRemove < ActiveRecord::Migration cmd = "db/migrate/020_populate_node_tags_and_remove_helper" src = "#{cmd}.c" if !File.exist?(cmd) || File.mtime(cmd) < File.mtime(src) - system("cc -O3 -Wall `mysql_config --cflags --libs` " + + system("cc -O3 -Wall `mysql_config --cflags --libs` " \ "#{src} -o #{cmd}") || raise end diff --git a/db/migrate/021_move_to_innodb.rb b/db/migrate/021_move_to_innodb.rb index 6ef3587d1..5be81b695 100644 --- a/db/migrate/021_move_to_innodb.rb +++ b/db/migrate/021_move_to_innodb.rb @@ -1,6 +1,6 @@ require "migrate" -class MoveToInnodb < ActiveRecord::Migration +class MoveToInnodb < ActiveRecord::Migration[5.0] @conv_tables = %w[nodes ways way_tags way_nodes current_way_tags relation_members relations relation_tags current_relation_tags] @ver_tbl = %w[nodes ways relations] diff --git a/db/migrate/022_key_constraints.rb b/db/migrate/022_key_constraints.rb index 5a6a9296f..535d7d21d 100644 --- a/db/migrate/022_key_constraints.rb +++ b/db/migrate/022_key_constraints.rb @@ -1,6 +1,6 @@ require "migrate" -class KeyConstraints < ActiveRecord::Migration +class KeyConstraints < ActiveRecord::Migration[5.0] def self.up # Primary keys add_primary_key :current_node_tags, [:id, :k] diff --git a/db/migrate/023_add_changesets.rb b/db/migrate/023_add_changesets.rb index 933a62cd5..8d19fc1c3 100644 --- a/db/migrate/023_add_changesets.rb +++ b/db/migrate/023_add_changesets.rb @@ -1,6 +1,6 @@ require "migrate" -class AddChangesets < ActiveRecord::Migration +class AddChangesets < ActiveRecord::Migration[5.0] @conv_user_tables = %w[current_nodes current_relations current_ways nodes relations ways] def self.up @@ -28,7 +28,7 @@ class AddChangesets < ActiveRecord::Migration # all edits up to the API change, # all the changesets will have the id of the user that made them. # We need to generate a changeset for each user in the database - execute "INSERT INTO changesets (id, user_id, created_at, open)" + + execute "INSERT INTO changesets (id, user_id, created_at, open)" \ "SELECT id, id, creation_time, false from users;" @conv_user_tables.each do |tbl| diff --git a/db/migrate/024_order_relation_members.rb b/db/migrate/024_order_relation_members.rb index fbb276dd5..e773da3cd 100644 --- a/db/migrate/024_order_relation_members.rb +++ b/db/migrate/024_order_relation_members.rb @@ -1,6 +1,6 @@ require "migrate" -class OrderRelationMembers < ActiveRecord::Migration +class OrderRelationMembers < ActiveRecord::Migration[5.0] def self.up # add sequence column. rails won't let us define an ordering here, # as defaults must be constant. diff --git a/db/migrate/025_add_end_time_to_changesets.rb b/db/migrate/025_add_end_time_to_changesets.rb index 4255c6f67..5bd2d5879 100644 --- a/db/migrate/025_add_end_time_to_changesets.rb +++ b/db/migrate/025_add_end_time_to_changesets.rb @@ -1,6 +1,6 @@ require "migrate" -class AddEndTimeToChangesets < ActiveRecord::Migration +class AddEndTimeToChangesets < ActiveRecord::Migration[5.0] def self.up # swap the boolean closed-or-not for a time when the changeset will # close or has closed. diff --git a/db/migrate/026_add_changeset_user_index.rb b/db/migrate/026_add_changeset_user_index.rb index fed0af7c0..049fdc760 100644 --- a/db/migrate/026_add_changeset_user_index.rb +++ b/db/migrate/026_add_changeset_user_index.rb @@ -1,4 +1,4 @@ -class AddChangesetUserIndex < ActiveRecord::Migration +class AddChangesetUserIndex < ActiveRecord::Migration[5.0] def self.up add_index "changesets", ["user_id"], :name => "changesets_user_id_idx" end diff --git a/db/migrate/027_add_changeset_indexes.rb b/db/migrate/027_add_changeset_indexes.rb index 0d4bba0e8..26b96bfba 100644 --- a/db/migrate/027_add_changeset_indexes.rb +++ b/db/migrate/027_add_changeset_indexes.rb @@ -1,4 +1,4 @@ -class AddChangesetIndexes < ActiveRecord::Migration +class AddChangesetIndexes < ActiveRecord::Migration[5.0] def self.up add_index "nodes", ["changeset_id"], :name => "nodes_changeset_id_idx" add_index "ways", ["changeset_id"], :name => "ways_changeset_id_idx" diff --git a/db/migrate/028_add_more_changeset_indexes.rb b/db/migrate/028_add_more_changeset_indexes.rb index 8fc9345a3..4f07b9d58 100644 --- a/db/migrate/028_add_more_changeset_indexes.rb +++ b/db/migrate/028_add_more_changeset_indexes.rb @@ -1,6 +1,6 @@ require "migrate" -class AddMoreChangesetIndexes < ActiveRecord::Migration +class AddMoreChangesetIndexes < ActiveRecord::Migration[5.0] def self.up add_index "changesets", ["created_at"], :name => "changesets_created_at_idx" add_index "changesets", ["closed_at"], :name => "changesets_closed_at_idx" diff --git a/db/migrate/029_add_user_foreign_keys.rb b/db/migrate/029_add_user_foreign_keys.rb index 224d589a8..84771f826 100644 --- a/db/migrate/029_add_user_foreign_keys.rb +++ b/db/migrate/029_add_user_foreign_keys.rb @@ -1,6 +1,6 @@ require "migrate" -class AddUserForeignKeys < ActiveRecord::Migration +class AddUserForeignKeys < ActiveRecord::Migration[5.0] def change add_foreign_key :changesets, :users, :name => "changesets_user_id_fkey" add_foreign_key :diary_comments, :users, :name => "diary_comments_user_id_fkey" diff --git a/db/migrate/030_add_foreign_keys.rb b/db/migrate/030_add_foreign_keys.rb index 02d9813bd..d55c96380 100644 --- a/db/migrate/030_add_foreign_keys.rb +++ b/db/migrate/030_add_foreign_keys.rb @@ -1,6 +1,6 @@ require "migrate" -class AddForeignKeys < ActiveRecord::Migration +class AddForeignKeys < ActiveRecord::Migration[5.0] def self.up add_foreign_key :changeset_tags, :changesets, :column => :id, :name => "changeset_tags_id_fkey" add_foreign_key :diary_comments, :diary_entries, :name => "diary_comments_diary_entry_id_fkey" diff --git a/db/migrate/031_create_countries.rb b/db/migrate/031_create_countries.rb index b146cbadb..180605b26 100644 --- a/db/migrate/031_create_countries.rb +++ b/db/migrate/031_create_countries.rb @@ -1,7 +1,7 @@ require "migrate" require "rexml/document" -class CreateCountries < ActiveRecord::Migration +class CreateCountries < ActiveRecord::Migration[5.0] def self.up create_table :countries, :id => false do |t| t.column :id, :primary_key, :null => false diff --git a/db/migrate/032_add_user_locale.rb b/db/migrate/032_add_user_locale.rb index de3654775..cf5f05808 100644 --- a/db/migrate/032_add_user_locale.rb +++ b/db/migrate/032_add_user_locale.rb @@ -1,4 +1,4 @@ -class AddUserLocale < ActiveRecord::Migration +class AddUserLocale < ActiveRecord::Migration[5.0] def self.up add_column "users", "locale", :string end diff --git a/db/migrate/033_change_diary_entries_language.rb b/db/migrate/033_change_diary_entries_language.rb index 674ae3d49..db011d83f 100644 --- a/db/migrate/033_change_diary_entries_language.rb +++ b/db/migrate/033_change_diary_entries_language.rb @@ -1,4 +1,4 @@ -class ChangeDiaryEntriesLanguage < ActiveRecord::Migration +class ChangeDiaryEntriesLanguage < ActiveRecord::Migration[5.0] def self.up remove_column "diary_entries", "language" add_column "diary_entries", "language_code", :string, :null => false, :default => "en" diff --git a/db/migrate/034_create_languages.rb b/db/migrate/034_create_languages.rb index c41856e1e..603ad3066 100644 --- a/db/migrate/034_create_languages.rb +++ b/db/migrate/034_create_languages.rb @@ -1,6 +1,6 @@ require "migrate" -class CreateLanguages < ActiveRecord::Migration +class CreateLanguages < ActiveRecord::Migration[5.0] def change create_table :languages, :id => false do |t| t.string :code, :null => false diff --git a/db/migrate/035_change_user_locale.rb b/db/migrate/035_change_user_locale.rb index cfdb657f2..4155fbced 100644 --- a/db/migrate/035_change_user_locale.rb +++ b/db/migrate/035_change_user_locale.rb @@ -1,6 +1,6 @@ require "migrate" -class ChangeUserLocale < ActiveRecord::Migration +class ChangeUserLocale < ActiveRecord::Migration[5.0] def self.up remove_foreign_key :users, :column => :locale, :name => "users_locale_fkey" diff --git a/db/migrate/036_add_visible_to_message.rb b/db/migrate/036_add_visible_to_message.rb index 22b121951..ecbe2d0d1 100644 --- a/db/migrate/036_add_visible_to_message.rb +++ b/db/migrate/036_add_visible_to_message.rb @@ -1,4 +1,4 @@ -class AddVisibleToMessage < ActiveRecord::Migration +class AddVisibleToMessage < ActiveRecord::Migration[5.0] def self.up add_column :messages, :visible, :boolean, :default => true, :null => false end diff --git a/db/migrate/037_add_sender_visible_to_message.rb b/db/migrate/037_add_sender_visible_to_message.rb index 305473a62..4ab347388 100644 --- a/db/migrate/037_add_sender_visible_to_message.rb +++ b/db/migrate/037_add_sender_visible_to_message.rb @@ -1,4 +1,4 @@ -class AddSenderVisibleToMessage < ActiveRecord::Migration +class AddSenderVisibleToMessage < ActiveRecord::Migration[5.0] def self.up rename_column :messages, :visible, :to_user_visible add_column :messages, :from_user_visible, :boolean, :default => true, :null => false diff --git a/db/migrate/038_add_message_sender_index.rb b/db/migrate/038_add_message_sender_index.rb index 723ef7814..0df145711 100644 --- a/db/migrate/038_add_message_sender_index.rb +++ b/db/migrate/038_add_message_sender_index.rb @@ -1,4 +1,4 @@ -class AddMessageSenderIndex < ActiveRecord::Migration +class AddMessageSenderIndex < ActiveRecord::Migration[5.0] def self.up add_index :messages, [:from_user_id], :name => "messages_from_user_id_idx" end diff --git a/db/migrate/039_add_more_controls_to_gpx_files.rb b/db/migrate/039_add_more_controls_to_gpx_files.rb index 5a905c044..945a7021d 100644 --- a/db/migrate/039_add_more_controls_to_gpx_files.rb +++ b/db/migrate/039_add_more_controls_to_gpx_files.rb @@ -1,6 +1,6 @@ require "migrate" -class AddMoreControlsToGpxFiles < ActiveRecord::Migration +class AddMoreControlsToGpxFiles < ActiveRecord::Migration[5.0] def self.up create_enumeration :gpx_visibility_enum, %w[private public trackable identifiable] add_column :gpx_files, :visibility, :gpx_visibility_enum, :default => "public", :null => false diff --git a/db/migrate/040_create_oauth_tables.rb b/db/migrate/040_create_oauth_tables.rb index a2eeeca7a..e718bbc17 100644 --- a/db/migrate/040_create_oauth_tables.rb +++ b/db/migrate/040_create_oauth_tables.rb @@ -1,4 +1,4 @@ -class CreateOauthTables < ActiveRecord::Migration +class CreateOauthTables < ActiveRecord::Migration[5.0] def self.up create_table :client_applications do |t| t.string :name diff --git a/db/migrate/041_add_fine_o_auth_permissions.rb b/db/migrate/041_add_fine_o_auth_permissions.rb index c37dc2c1b..3ce10c4e6 100644 --- a/db/migrate/041_add_fine_o_auth_permissions.rb +++ b/db/migrate/041_add_fine_o_auth_permissions.rb @@ -1,4 +1,4 @@ -class AddFineOAuthPermissions < ActiveRecord::Migration +class AddFineOAuthPermissions < ActiveRecord::Migration[5.0] PERMISSIONS = [:allow_read_prefs, :allow_write_prefs, :allow_write_diary, :allow_write_api, :allow_read_gpx, :allow_write_gpx].freeze def self.up diff --git a/db/migrate/042_add_foreign_keys_to_oauth_tables.rb b/db/migrate/042_add_foreign_keys_to_oauth_tables.rb index f8e36711f..4268dddd1 100644 --- a/db/migrate/042_add_foreign_keys_to_oauth_tables.rb +++ b/db/migrate/042_add_foreign_keys_to_oauth_tables.rb @@ -1,6 +1,6 @@ require "migrate" -class AddForeignKeysToOauthTables < ActiveRecord::Migration +class AddForeignKeysToOauthTables < ActiveRecord::Migration[5.0] def change add_foreign_key :oauth_tokens, :users, :name => "oauth_tokens_user_id_fkey" add_foreign_key :oauth_tokens, :client_applications, :name => "oauth_tokens_client_application_id_fkey" diff --git a/db/migrate/043_add_referer_to_user_token.rb b/db/migrate/043_add_referer_to_user_token.rb index 554cc937e..0bfe07073 100644 --- a/db/migrate/043_add_referer_to_user_token.rb +++ b/db/migrate/043_add_referer_to_user_token.rb @@ -1,4 +1,4 @@ -class AddRefererToUserToken < ActiveRecord::Migration +class AddRefererToUserToken < ActiveRecord::Migration[5.0] def self.up add_column :user_tokens, :referer, :text end diff --git a/db/migrate/044_create_user_roles.rb b/db/migrate/044_create_user_roles.rb index e5cf07cd3..3a3fa3faf 100644 --- a/db/migrate/044_create_user_roles.rb +++ b/db/migrate/044_create_user_roles.rb @@ -1,6 +1,6 @@ require "migrate" -class CreateUserRoles < ActiveRecord::Migration +class CreateUserRoles < ActiveRecord::Migration[5.0] def self.up create_enumeration :user_role_enum, %w[administrator moderator] diff --git a/db/migrate/045_create_user_blocks.rb b/db/migrate/045_create_user_blocks.rb index 71081f5c1..3ccd522f9 100644 --- a/db/migrate/045_create_user_blocks.rb +++ b/db/migrate/045_create_user_blocks.rb @@ -1,6 +1,6 @@ require "migrate" -class CreateUserBlocks < ActiveRecord::Migration +class CreateUserBlocks < ActiveRecord::Migration[5.0] def change create_table :user_blocks do |t| t.column :user_id, :bigint, :null => false diff --git a/db/migrate/046_alter_user_roles_and_blocks.rb b/db/migrate/046_alter_user_roles_and_blocks.rb index 5957b13ba..812572e23 100644 --- a/db/migrate/046_alter_user_roles_and_blocks.rb +++ b/db/migrate/046_alter_user_roles_and_blocks.rb @@ -1,6 +1,6 @@ require "migrate" -class AlterUserRolesAndBlocks < ActiveRecord::Migration +class AlterUserRolesAndBlocks < ActiveRecord::Migration[5.0] def self.up # the initial granter IDs can be "self" - there are none of these # in the current live DB, but there may be some in people's own local diff --git a/db/migrate/047_add_visible_to_diaries.rb b/db/migrate/047_add_visible_to_diaries.rb index 994bebd17..4e76f04ca 100644 --- a/db/migrate/047_add_visible_to_diaries.rb +++ b/db/migrate/047_add_visible_to_diaries.rb @@ -1,4 +1,4 @@ -class AddVisibleToDiaries < ActiveRecord::Migration +class AddVisibleToDiaries < ActiveRecord::Migration[5.0] def self.up add_column :diary_entries, :visible, :boolean, :null => false, :default => true add_column :diary_comments, :visible, :boolean, :null => false, :default => true diff --git a/db/migrate/048_add_diary_creation_indexes.rb b/db/migrate/048_add_diary_creation_indexes.rb index d99831a3a..54edfe065 100644 --- a/db/migrate/048_add_diary_creation_indexes.rb +++ b/db/migrate/048_add_diary_creation_indexes.rb @@ -1,4 +1,4 @@ -class AddDiaryCreationIndexes < ActiveRecord::Migration +class AddDiaryCreationIndexes < ActiveRecord::Migration[5.0] def self.up add_index :diary_entries, [:created_at], :name => "diary_entry_created_at_index" add_index :diary_entries, [:user_id, :created_at], :name => "diary_entry_user_id_created_at_index" diff --git a/db/migrate/049_improve_changeset_user_index.rb b/db/migrate/049_improve_changeset_user_index.rb index f02a63dcb..824911327 100644 --- a/db/migrate/049_improve_changeset_user_index.rb +++ b/db/migrate/049_improve_changeset_user_index.rb @@ -1,4 +1,4 @@ -class ImproveChangesetUserIndex < ActiveRecord::Migration +class ImproveChangesetUserIndex < ActiveRecord::Migration[5.0] def self.up add_index :changesets, [:user_id, :id], :name => "changesets_user_id_id_idx" remove_index :changesets, :name => "changesets_user_id_idx" diff --git a/db/migrate/050_add_user_index_to_diary_comments.rb b/db/migrate/050_add_user_index_to_diary_comments.rb index e1fe0def2..48e0593ba 100644 --- a/db/migrate/050_add_user_index_to_diary_comments.rb +++ b/db/migrate/050_add_user_index_to_diary_comments.rb @@ -1,4 +1,4 @@ -class AddUserIndexToDiaryComments < ActiveRecord::Migration +class AddUserIndexToDiaryComments < ActiveRecord::Migration[5.0] def self.up add_index :diary_comments, [:user_id, :created_at], :name => "diary_comment_user_id_created_at_index" end diff --git a/db/migrate/051_add_status_to_user.rb b/db/migrate/051_add_status_to_user.rb index f3a550c60..d3adcee33 100644 --- a/db/migrate/051_add_status_to_user.rb +++ b/db/migrate/051_add_status_to_user.rb @@ -1,6 +1,6 @@ require "migrate" -class AddStatusToUser < ActiveRecord::Migration +class AddStatusToUser < ActiveRecord::Migration[5.0] def self.up create_enumeration :user_status_enum, %w[pending active confirmed suspended deleted] diff --git a/db/migrate/052_add_contributor_terms_to_user.rb b/db/migrate/052_add_contributor_terms_to_user.rb index f2eae9047..01835b981 100644 --- a/db/migrate/052_add_contributor_terms_to_user.rb +++ b/db/migrate/052_add_contributor_terms_to_user.rb @@ -1,4 +1,4 @@ -class AddContributorTermsToUser < ActiveRecord::Migration +class AddContributorTermsToUser < ActiveRecord::Migration[5.0] def self.up add_column :users, :terms_agreed, :datetime add_column :users, :consider_pd, :boolean, :null => false, :default => false diff --git a/db/migrate/053_add_map_bug_tables.rb b/db/migrate/053_add_map_bug_tables.rb index 0ad968d0a..aac3c11c4 100644 --- a/db/migrate/053_add_map_bug_tables.rb +++ b/db/migrate/053_add_map_bug_tables.rb @@ -1,6 +1,6 @@ require "migrate" -class AddMapBugTables < ActiveRecord::Migration +class AddMapBugTables < ActiveRecord::Migration[5.0] def self.up create_enumeration :map_bug_status_enum, %w[open closed hidden] diff --git a/db/migrate/054_refactor_map_bug_tables.rb b/db/migrate/054_refactor_map_bug_tables.rb index 70ed81e45..e29ec0704 100644 --- a/db/migrate/054_refactor_map_bug_tables.rb +++ b/db/migrate/054_refactor_map_bug_tables.rb @@ -1,6 +1,6 @@ require "migrate" -class RefactorMapBugTables < ActiveRecord::Migration +class RefactorMapBugTables < ActiveRecord::Migration[5.0] def self.up create_table :map_bug_comment do |t| t.column :bug_id, :bigint, :null => false diff --git a/db/migrate/055_change_map_bug_comment_type.rb b/db/migrate/055_change_map_bug_comment_type.rb index 4f979da98..6b8407623 100644 --- a/db/migrate/055_change_map_bug_comment_type.rb +++ b/db/migrate/055_change_map_bug_comment_type.rb @@ -1,6 +1,6 @@ require "migrate" -class ChangeMapBugCommentType < ActiveRecord::Migration +class ChangeMapBugCommentType < ActiveRecord::Migration[5.0] def self.up change_column :map_bug_comment, :comment, :text end diff --git a/db/migrate/056_add_date_closed.rb b/db/migrate/056_add_date_closed.rb index 50aeb6c4f..7b1a3233d 100644 --- a/db/migrate/056_add_date_closed.rb +++ b/db/migrate/056_add_date_closed.rb @@ -1,6 +1,6 @@ require "migrate" -class AddDateClosed < ActiveRecord::Migration +class AddDateClosed < ActiveRecord::Migration[5.0] def self.up add_column :map_bugs, :date_closed, :timestamp end diff --git a/db/migrate/057_add_map_bug_comment_event.rb b/db/migrate/057_add_map_bug_comment_event.rb index 6ba2b5a76..0d1a2c8ab 100644 --- a/db/migrate/057_add_map_bug_comment_event.rb +++ b/db/migrate/057_add_map_bug_comment_event.rb @@ -1,6 +1,6 @@ require "migrate" -class AddMapBugCommentEvent < ActiveRecord::Migration +class AddMapBugCommentEvent < ActiveRecord::Migration[5.0] def self.up create_enumeration :map_bug_event_enum, %w[opened closed reopened commented hidden] diff --git a/db/migrate/20100513171259_add_user_date_index_to_changeset.rb b/db/migrate/20100513171259_add_user_date_index_to_changeset.rb index f1d7f43e8..7c9c13782 100644 --- a/db/migrate/20100513171259_add_user_date_index_to_changeset.rb +++ b/db/migrate/20100513171259_add_user_date_index_to_changeset.rb @@ -1,4 +1,4 @@ -class AddUserDateIndexToChangeset < ActiveRecord::Migration +class AddUserDateIndexToChangeset < ActiveRecord::Migration[5.0] def self.up add_index :changesets, [:user_id, :created_at], :name => "changesets_user_id_created_at_idx" end diff --git a/db/migrate/20100516124737_add_open_id.rb b/db/migrate/20100516124737_add_open_id.rb index bbe54430d..74d86440c 100644 --- a/db/migrate/20100516124737_add_open_id.rb +++ b/db/migrate/20100516124737_add_open_id.rb @@ -1,4 +1,4 @@ -class AddOpenId < ActiveRecord::Migration +class AddOpenId < ActiveRecord::Migration[5.0] def self.up add_column :users, :openid_url, :string add_index :users, [:openid_url], :name => "user_openid_url_idx", :unique => true diff --git a/db/migrate/20100910084426_add_callback_to_oauth_tokens.rb b/db/migrate/20100910084426_add_callback_to_oauth_tokens.rb index 179b80fab..5db1201fd 100644 --- a/db/migrate/20100910084426_add_callback_to_oauth_tokens.rb +++ b/db/migrate/20100910084426_add_callback_to_oauth_tokens.rb @@ -1,4 +1,4 @@ -class AddCallbackToOauthTokens < ActiveRecord::Migration +class AddCallbackToOauthTokens < ActiveRecord::Migration[5.0] def self.up add_column :oauth_tokens, :callback_url, :string add_column :oauth_tokens, :verifier, :string, :limit => 20 diff --git a/db/migrate/20101114011429_add_editor_preference_to_user.rb b/db/migrate/20101114011429_add_editor_preference_to_user.rb index 7d39cd200..b7f82e325 100644 --- a/db/migrate/20101114011429_add_editor_preference_to_user.rb +++ b/db/migrate/20101114011429_add_editor_preference_to_user.rb @@ -1,4 +1,4 @@ -class AddEditorPreferenceToUser < ActiveRecord::Migration +class AddEditorPreferenceToUser < ActiveRecord::Migration[5.0] def self.up add_column :users, :preferred_editor, :string end diff --git a/db/migrate/20110322001319_add_terms_seen_to_user.rb b/db/migrate/20110322001319_add_terms_seen_to_user.rb index 3cab89652..a95f15b4e 100644 --- a/db/migrate/20110322001319_add_terms_seen_to_user.rb +++ b/db/migrate/20110322001319_add_terms_seen_to_user.rb @@ -1,4 +1,4 @@ -class AddTermsSeenToUser < ActiveRecord::Migration +class AddTermsSeenToUser < ActiveRecord::Migration[5.0] def self.up add_column :users, :terms_seen, :boolean, :null => false, :default => false diff --git a/db/migrate/20110508145337_cleanup_bug_tables.rb b/db/migrate/20110508145337_cleanup_bug_tables.rb index e7dfcb793..2a285b453 100644 --- a/db/migrate/20110508145337_cleanup_bug_tables.rb +++ b/db/migrate/20110508145337_cleanup_bug_tables.rb @@ -1,4 +1,4 @@ -class CleanupBugTables < ActiveRecord::Migration +class CleanupBugTables < ActiveRecord::Migration[5.0] def self.up rename_column :map_bugs, :date_created, :created_at rename_column :map_bugs, :last_changed, :updated_at diff --git a/db/migrate/20110521142405_rename_bugs_to_notes.rb b/db/migrate/20110521142405_rename_bugs_to_notes.rb index 44ca1f484..a22041a29 100644 --- a/db/migrate/20110521142405_rename_bugs_to_notes.rb +++ b/db/migrate/20110521142405_rename_bugs_to_notes.rb @@ -1,6 +1,6 @@ require "migrate" -class RenameBugsToNotes < ActiveRecord::Migration +class RenameBugsToNotes < ActiveRecord::Migration[5.0] def self.up rename_enumeration "map_bug_status_enum", "note_status_enum" rename_enumeration "map_bug_event_enum", "note_event_enum" diff --git a/db/migrate/20110925112722_rename_ids.rb b/db/migrate/20110925112722_rename_ids.rb index 9cdbaaa36..7d7aa8f94 100644 --- a/db/migrate/20110925112722_rename_ids.rb +++ b/db/migrate/20110925112722_rename_ids.rb @@ -1,4 +1,4 @@ -class RenameIds < ActiveRecord::Migration +class RenameIds < ActiveRecord::Migration[5.0] def change rename_column :changeset_tags, :id, :changeset_id rename_column :current_node_tags, :id, :node_id diff --git a/db/migrate/20111116184519_update_oauth.rb b/db/migrate/20111116184519_update_oauth.rb index 59ab9c39b..654e79ef3 100644 --- a/db/migrate/20111116184519_update_oauth.rb +++ b/db/migrate/20111116184519_update_oauth.rb @@ -1,4 +1,4 @@ -class UpdateOauth < ActiveRecord::Migration +class UpdateOauth < ActiveRecord::Migration[5.0] def up add_column :oauth_tokens, :scope, :string add_column :oauth_tokens, :valid_to, :timestamp diff --git a/db/migrate/20111212183945_add_lowercase_user_indexes.rb b/db/migrate/20111212183945_add_lowercase_user_indexes.rb index f25175590..7d1a5e9a9 100644 --- a/db/migrate/20111212183945_add_lowercase_user_indexes.rb +++ b/db/migrate/20111212183945_add_lowercase_user_indexes.rb @@ -1,6 +1,6 @@ require "migrate" -class AddLowercaseUserIndexes < ActiveRecord::Migration +class AddLowercaseUserIndexes < ActiveRecord::Migration[5.0] def up add_index :users, [], :columns => "LOWER(display_name)", :name => "users_display_name_lower_idx" add_index :users, [], :columns => "LOWER(email)", :name => "users_email_lower_idx" diff --git a/db/migrate/20120123184321_switch_to_paperclip.rb b/db/migrate/20120123184321_switch_to_paperclip.rb index f46d61bb5..8dfcce4fb 100644 --- a/db/migrate/20120123184321_switch_to_paperclip.rb +++ b/db/migrate/20120123184321_switch_to_paperclip.rb @@ -1,4 +1,4 @@ -class SwitchToPaperclip < ActiveRecord::Migration +class SwitchToPaperclip < ActiveRecord::Migration[5.0] def up rename_column :users, :image, :image_file_name end diff --git a/db/migrate/20120208122334_merge_acl_address_and_mask.rb b/db/migrate/20120208122334_merge_acl_address_and_mask.rb index 9153da1e5..1e67f46dd 100644 --- a/db/migrate/20120208122334_merge_acl_address_and_mask.rb +++ b/db/migrate/20120208122334_merge_acl_address_and_mask.rb @@ -10,7 +10,7 @@ class IPAddr end end -class MergeAclAddressAndMask < ActiveRecord::Migration +class MergeAclAddressAndMask < ActiveRecord::Migration[5.0] def up Acl.find_each do |acl| address = IPAddr.new(acl.address) diff --git a/db/migrate/20120208194454_add_domain_to_acl.rb b/db/migrate/20120208194454_add_domain_to_acl.rb index 43dd82923..5dd1b6957 100644 --- a/db/migrate/20120208194454_add_domain_to_acl.rb +++ b/db/migrate/20120208194454_add_domain_to_acl.rb @@ -1,4 +1,4 @@ -class AddDomainToAcl < ActiveRecord::Migration +class AddDomainToAcl < ActiveRecord::Migration[5.0] def up add_column :acls, :domain, :string change_column :acls, :address, :inet, :null => true diff --git a/db/migrate/20120214210114_add_text_format.rb b/db/migrate/20120214210114_add_text_format.rb index 165524d2c..8e6853188 100644 --- a/db/migrate/20120214210114_add_text_format.rb +++ b/db/migrate/20120214210114_add_text_format.rb @@ -1,6 +1,6 @@ require "migrate" -class AddTextFormat < ActiveRecord::Migration +class AddTextFormat < ActiveRecord::Migration[5.0] def up create_enumeration :format_enum, %w[html markdown text] add_column :users, :description_format, :format_enum, :null => false, :default => "html" diff --git a/db/migrate/20120219161649_add_user_image_fingerprint.rb b/db/migrate/20120219161649_add_user_image_fingerprint.rb index 5c9dd4083..c3dc5c51a 100644 --- a/db/migrate/20120219161649_add_user_image_fingerprint.rb +++ b/db/migrate/20120219161649_add_user_image_fingerprint.rb @@ -1,4 +1,4 @@ -class AddUserImageFingerprint < ActiveRecord::Migration +class AddUserImageFingerprint < ActiveRecord::Migration[5.0] def up add_column :users, :image_fingerprint, :string, :null => true diff --git a/db/migrate/20120318201948_create_redactions.rb b/db/migrate/20120318201948_create_redactions.rb index 8a1cf6bf3..1cdcc8625 100644 --- a/db/migrate/20120318201948_create_redactions.rb +++ b/db/migrate/20120318201948_create_redactions.rb @@ -1,6 +1,6 @@ require "migrate" -class CreateRedactions < ActiveRecord::Migration +class CreateRedactions < ActiveRecord::Migration[5.0] def change create_table :redactions do |t| t.string :title diff --git a/db/migrate/20120328090602_drop_session_table.rb b/db/migrate/20120328090602_drop_session_table.rb index 0ffcb899b..ad0789ae3 100644 --- a/db/migrate/20120328090602_drop_session_table.rb +++ b/db/migrate/20120328090602_drop_session_table.rb @@ -1,6 +1,6 @@ require "migrate" -class DropSessionTable < ActiveRecord::Migration +class DropSessionTable < ActiveRecord::Migration[5.0] def up drop_table "sessions" end diff --git a/db/migrate/20120404205604_add_user_and_description_to_redaction.rb b/db/migrate/20120404205604_add_user_and_description_to_redaction.rb index 5de170ca7..32d188c8f 100644 --- a/db/migrate/20120404205604_add_user_and_description_to_redaction.rb +++ b/db/migrate/20120404205604_add_user_and_description_to_redaction.rb @@ -1,6 +1,6 @@ require "migrate" -class AddUserAndDescriptionToRedaction < ActiveRecord::Migration +class AddUserAndDescriptionToRedaction < ActiveRecord::Migration[5.0] def change add_column :redactions, :user_id, :bigint, :null => false add_column :redactions, :description_format, :format_enum, :null => false, :default => "markdown" diff --git a/db/migrate/20120808231205_add_counter_caches.rb b/db/migrate/20120808231205_add_counter_caches.rb index a26f204da..1dffb8ffd 100644 --- a/db/migrate/20120808231205_add_counter_caches.rb +++ b/db/migrate/20120808231205_add_counter_caches.rb @@ -1,4 +1,4 @@ -class AddCounterCaches < ActiveRecord::Migration +class AddCounterCaches < ActiveRecord::Migration[5.0] def self.up add_column :users, :changesets_count, :integer, :null => false, :default => 0 add_column :users, :traces_count, :integer, :null => false, :default => 0 diff --git a/db/migrate/20121005195010_add_diary_entry_counter_caches.rb b/db/migrate/20121005195010_add_diary_entry_counter_caches.rb index 9c2c72710..1a61ddd41 100644 --- a/db/migrate/20121005195010_add_diary_entry_counter_caches.rb +++ b/db/migrate/20121005195010_add_diary_entry_counter_caches.rb @@ -1,4 +1,4 @@ -class AddDiaryEntryCounterCaches < ActiveRecord::Migration +class AddDiaryEntryCounterCaches < ActiveRecord::Migration[5.0] def self.up add_column :users, :diary_entries_count, :integer, :null => false, :default => 0 diff --git a/db/migrate/20121012044047_add_image_use_gravatar_to_users.rb b/db/migrate/20121012044047_add_image_use_gravatar_to_users.rb index e430d5b3c..532edd2c7 100644 --- a/db/migrate/20121012044047_add_image_use_gravatar_to_users.rb +++ b/db/migrate/20121012044047_add_image_use_gravatar_to_users.rb @@ -1,4 +1,4 @@ -class AddImageUseGravatarToUsers < ActiveRecord::Migration +class AddImageUseGravatarToUsers < ActiveRecord::Migration[5.0] def self.up add_column :users, :image_use_gravatar, :boolean, :null => false, :default => false diff --git a/db/migrate/20121119165817_drop_nearby_place_from_notes.rb b/db/migrate/20121119165817_drop_nearby_place_from_notes.rb index bbef25946..1aaa43fff 100644 --- a/db/migrate/20121119165817_drop_nearby_place_from_notes.rb +++ b/db/migrate/20121119165817_drop_nearby_place_from_notes.rb @@ -1,4 +1,4 @@ -class DropNearbyPlaceFromNotes < ActiveRecord::Migration +class DropNearbyPlaceFromNotes < ActiveRecord::Migration[5.0] def up remove_column :notes, :nearby_place end diff --git a/db/migrate/20121202155309_remove_author_name_from_note_comment.rb b/db/migrate/20121202155309_remove_author_name_from_note_comment.rb index 60d0ab23b..b844d0ca1 100644 --- a/db/migrate/20121202155309_remove_author_name_from_note_comment.rb +++ b/db/migrate/20121202155309_remove_author_name_from_note_comment.rb @@ -1,4 +1,4 @@ -class RemoveAuthorNameFromNoteComment < ActiveRecord::Migration +class RemoveAuthorNameFromNoteComment < ActiveRecord::Migration[5.0] def up remove_column :note_comments, :author_name end diff --git a/db/migrate/20121203124841_change_note_address_to_inet.rb b/db/migrate/20121203124841_change_note_address_to_inet.rb index e4e53e35a..5ba8611cf 100644 --- a/db/migrate/20121203124841_change_note_address_to_inet.rb +++ b/db/migrate/20121203124841_change_note_address_to_inet.rb @@ -1,4 +1,4 @@ -class ChangeNoteAddressToInet < ActiveRecord::Migration +class ChangeNoteAddressToInet < ActiveRecord::Migration[5.0] def up execute "ALTER TABLE note_comments ALTER COLUMN author_ip TYPE inet USING CAST(author_ip AS inet)" end diff --git a/db/migrate/20130328184137_add_write_notes_permission.rb b/db/migrate/20130328184137_add_write_notes_permission.rb index c7da1740f..6db39f49f 100644 --- a/db/migrate/20130328184137_add_write_notes_permission.rb +++ b/db/migrate/20130328184137_add_write_notes_permission.rb @@ -1,4 +1,4 @@ -class AddWriteNotesPermission < ActiveRecord::Migration +class AddWriteNotesPermission < ActiveRecord::Migration[5.0] def up add_column :oauth_tokens, :allow_write_notes, :boolean, :null => false, :default => false add_column :client_applications, :allow_write_notes, :boolean, :null => false, :default => false diff --git a/db/migrate/20131212124700_add_created_at_index_to_note_comments.rb b/db/migrate/20131212124700_add_created_at_index_to_note_comments.rb index 832204734..baee598cb 100644 --- a/db/migrate/20131212124700_add_created_at_index_to_note_comments.rb +++ b/db/migrate/20131212124700_add_created_at_index_to_note_comments.rb @@ -1,4 +1,4 @@ -class AddCreatedAtIndexToNoteComments < ActiveRecord::Migration +class AddCreatedAtIndexToNoteComments < ActiveRecord::Migration[5.0] def change add_index :note_comments, :created_at end diff --git a/db/migrate/20140115192822_add_text_index_to_note_comments.rb b/db/migrate/20140115192822_add_text_index_to_note_comments.rb index fe9134048..cc9736988 100644 --- a/db/migrate/20140115192822_add_text_index_to_note_comments.rb +++ b/db/migrate/20140115192822_add_text_index_to_note_comments.rb @@ -1,6 +1,6 @@ require "migrate" -class AddTextIndexToNoteComments < ActiveRecord::Migration +class AddTextIndexToNoteComments < ActiveRecord::Migration[5.0] def up add_index :note_comments, [], :columns => "to_tsvector('english', body)", :using => "GIN", :name => "index_note_comments_on_body" end diff --git a/db/migrate/20140117185510_drop_countries.rb b/db/migrate/20140117185510_drop_countries.rb index 083319284..1b58c9fc0 100644 --- a/db/migrate/20140117185510_drop_countries.rb +++ b/db/migrate/20140117185510_drop_countries.rb @@ -1,4 +1,4 @@ -class DropCountries < ActiveRecord::Migration +class DropCountries < ActiveRecord::Migration[5.0] def up drop_table :countries end diff --git a/db/migrate/20140210003018_add_user_image_content_type.rb b/db/migrate/20140210003018_add_user_image_content_type.rb index d212931fc..4001ae8fb 100644 --- a/db/migrate/20140210003018_add_user_image_content_type.rb +++ b/db/migrate/20140210003018_add_user_image_content_type.rb @@ -1,4 +1,4 @@ -class AddUserImageContentType < ActiveRecord::Migration +class AddUserImageContentType < ActiveRecord::Migration[5.0] def change add_column :users, :image_content_type, :string end diff --git a/db/migrate/20140507110937_create_changeset_comments.rb b/db/migrate/20140507110937_create_changeset_comments.rb index 0b36fa228..d4475b4d8 100644 --- a/db/migrate/20140507110937_create_changeset_comments.rb +++ b/db/migrate/20140507110937_create_changeset_comments.rb @@ -1,6 +1,6 @@ require "migrate" -class CreateChangesetComments < ActiveRecord::Migration +class CreateChangesetComments < ActiveRecord::Migration[5.0] def change create_table :changeset_comments do |t| t.column :changeset_id, :bigint, :null => false diff --git a/db/migrate/20140519141742_add_join_table_between_users_and_changesets.rb b/db/migrate/20140519141742_add_join_table_between_users_and_changesets.rb index 4eab95ce7..a5cfabd69 100644 --- a/db/migrate/20140519141742_add_join_table_between_users_and_changesets.rb +++ b/db/migrate/20140519141742_add_join_table_between_users_and_changesets.rb @@ -1,6 +1,6 @@ require "migrate" -class AddJoinTableBetweenUsersAndChangesets < ActiveRecord::Migration +class AddJoinTableBetweenUsersAndChangesets < ActiveRecord::Migration[5.0] def change create_table :changesets_subscribers, :id => false do |t| t.column :subscriber_id, :bigint, :null => false diff --git a/db/migrate/20150110152606_change_default_formats.rb b/db/migrate/20150110152606_change_default_formats.rb index 84bc2be40..3f18f6ac2 100644 --- a/db/migrate/20150110152606_change_default_formats.rb +++ b/db/migrate/20150110152606_change_default_formats.rb @@ -1,4 +1,4 @@ -class ChangeDefaultFormats < ActiveRecord::Migration +class ChangeDefaultFormats < ActiveRecord::Migration[5.0] def up change_column_default :diary_entries, :body_format, "markdown" change_column_default :diary_comments, :body_format, "markdown" diff --git a/db/migrate/20150111192335_subscribe_old_changesets.rb b/db/migrate/20150111192335_subscribe_old_changesets.rb index cca8293f5..0a722b3a1 100644 --- a/db/migrate/20150111192335_subscribe_old_changesets.rb +++ b/db/migrate/20150111192335_subscribe_old_changesets.rb @@ -1,4 +1,4 @@ -class SubscribeOldChangesets < ActiveRecord::Migration +class SubscribeOldChangesets < ActiveRecord::Migration[5.0] def up Changeset.find_each do |changeset| changeset.subscribers << changeset.user unless changeset.subscribers.exists?(changeset.user.id) diff --git a/db/migrate/20150222101847_rename_openid_url.rb b/db/migrate/20150222101847_rename_openid_url.rb index b0735b746..8d49dc973 100644 --- a/db/migrate/20150222101847_rename_openid_url.rb +++ b/db/migrate/20150222101847_rename_openid_url.rb @@ -1,4 +1,4 @@ -class RenameOpenidUrl < ActiveRecord::Migration +class RenameOpenidUrl < ActiveRecord::Migration[5.0] def change rename_column :users, :openid_url, :auth_uid add_column :users, :auth_provider, :string diff --git a/db/migrate/20150818224516_set_default_gravatar_to_false_for_privacy.rb b/db/migrate/20150818224516_set_default_gravatar_to_false_for_privacy.rb index 49f94c9de..28f3c828d 100644 --- a/db/migrate/20150818224516_set_default_gravatar_to_false_for_privacy.rb +++ b/db/migrate/20150818224516_set_default_gravatar_to_false_for_privacy.rb @@ -1,4 +1,4 @@ -class SetDefaultGravatarToFalseForPrivacy < ActiveRecord::Migration +class SetDefaultGravatarToFalseForPrivacy < ActiveRecord::Migration[5.0] def up change_column :users, :image_use_gravatar, :boolean, :default => false end diff --git a/db/migrate/20161002153425_add_join_table_between_users_and_diary_entries.rb b/db/migrate/20161002153425_add_join_table_between_users_and_diary_entries.rb index cb8e455dd..088b9d28b 100644 --- a/db/migrate/20161002153425_add_join_table_between_users_and_diary_entries.rb +++ b/db/migrate/20161002153425_add_join_table_between_users_and_diary_entries.rb @@ -1,6 +1,6 @@ require "migrate" -class AddJoinTableBetweenUsersAndDiaryEntries < ActiveRecord::Migration +class AddJoinTableBetweenUsersAndDiaryEntries < ActiveRecord::Migration[5.0] def self.up create_table :diary_entry_subscriptions, :id => false do |t| t.column :user_id, :bigint, :null => false diff --git a/db/migrate/20161011010929_subscribe_authors_to_diary_entries.rb b/db/migrate/20161011010929_subscribe_authors_to_diary_entries.rb index 3fcbdf5fb..219386900 100644 --- a/db/migrate/20161011010929_subscribe_authors_to_diary_entries.rb +++ b/db/migrate/20161011010929_subscribe_authors_to_diary_entries.rb @@ -1,4 +1,4 @@ -class SubscribeAuthorsToDiaryEntries < ActiveRecord::Migration +class SubscribeAuthorsToDiaryEntries < ActiveRecord::Migration[5.0] def up DiaryEntry.find_each do |diary_entry| diary_entry.subscriptions.create(:user => diary_entry.user) unless diary_entry.subscribers.exists?(diary_entry.user.id) diff --git a/db/migrate/20170222134109_add_user_indexes.rb b/db/migrate/20170222134109_add_user_indexes.rb index 62330df9c..b138039ea 100644 --- a/db/migrate/20170222134109_add_user_indexes.rb +++ b/db/migrate/20170222134109_add_user_indexes.rb @@ -1,4 +1,4 @@ -class AddUserIndexes < ActiveRecord::Migration +class AddUserIndexes < ActiveRecord::Migration[5.0] def change add_index :oauth_tokens, [:user_id] add_index :client_applications, [:user_id] diff --git a/lib/bounding_box.rb b/lib/bounding_box.rb index 51972efbc..f12683d3c 100644 --- a/lib/bounding_box.rb +++ b/lib/bounding_box.rb @@ -66,18 +66,14 @@ class BoundingBox def check_boundaries # check the bbox is sane if min_lon > max_lon - raise OSM::APIBadBoundingBox.new( - "The minimum longitude must be less than the maximum longitude, but it wasn't" - ) + raise OSM::APIBadBoundingBox, "The minimum longitude must be less than the maximum longitude, but it wasn't" end if min_lat > max_lat - raise OSM::APIBadBoundingBox.new( - "The minimum latitude must be less than the maximum latitude, but it wasn't" - ) + raise OSM::APIBadBoundingBox, "The minimum latitude must be less than the maximum latitude, but it wasn't" end if min_lon < -LON_LIMIT || min_lat < -LAT_LIMIT || max_lon > +LON_LIMIT || max_lat > +LAT_LIMIT - raise OSM::APIBadBoundingBox.new("The latitudes must be between #{-LAT_LIMIT} and #{LAT_LIMIT}," + - " and longitudes between #{-LON_LIMIT} and #{LON_LIMIT}") + raise OSM::APIBadBoundingBox, "The latitudes must be between #{-LAT_LIMIT} and #{LAT_LIMIT}," \ + " and longitudes between #{-LON_LIMIT} and #{LON_LIMIT}" end self end @@ -85,8 +81,8 @@ class BoundingBox def check_size(max_area = MAX_REQUEST_AREA) # check the bbox isn't too large if area > max_area - raise OSM::APIBadBoundingBox.new("The maximum bbox size is " + max_area.to_s + - ", and your request was too large. Either request a smaller area, or use planet.osm") + raise OSM::APIBadBoundingBox, "The maximum bbox size is " + max_area.to_s + + ", and your request was too large. Either request a smaller area, or use planet.osm" end self end @@ -171,9 +167,7 @@ class BoundingBox def from_bbox_array(bbox_array) unless bbox_array - raise OSM::APIBadUserInput.new( - "The parameter bbox is required, and must be of the form min_lon,min_lat,max_lon,max_lat" - ) + raise OSM::APIBadUserInput, "The parameter bbox is required, and must be of the form min_lon,min_lat,max_lon,max_lat" end # Take an array of length 4, create a bounding box with min_lon, min_lat, max_lon and # max_lat within their respective boundaries. diff --git a/lib/classic_pagination/pagination_helper.rb b/lib/classic_pagination/pagination_helper.rb index 18decb119..3ff3c3b95 100644 --- a/lib/classic_pagination/pagination_helper.rb +++ b/lib/classic_pagination/pagination_helper.rb @@ -130,6 +130,6 @@ module ActionView html end - end # PaginationHelper - end # Helpers -end # ActionView + end + end +end diff --git a/lib/consistency_validations.rb b/lib/consistency_validations.rb index 0d17d2830..7e9b33586 100644 --- a/lib/consistency_validations.rb +++ b/lib/consistency_validations.rb @@ -7,26 +7,26 @@ module ConsistencyValidations # This will throw an exception if there is an inconsistency def check_consistency(old, new, user) if new.id != old.id || new.id.nil? || old.id.nil? - raise OSM::APIPreconditionFailedError.new("New and old IDs don't match on #{new.class}. #{new.id} != #{old.id}.") + raise OSM::APIPreconditionFailedError, "New and old IDs don't match on #{new.class}. #{new.id} != #{old.id}." elsif new.version != old.version raise OSM::APIVersionMismatchError.new(new.id, new.class.to_s, new.version, old.version) elsif new.changeset.nil? - raise OSM::APIChangesetMissingError.new + raise OSM::APIChangesetMissingError elsif new.changeset.user_id != user.id - raise OSM::APIUserChangesetMismatchError.new + raise OSM::APIUserChangesetMismatchError elsif !new.changeset.is_open? - raise OSM::APIChangesetAlreadyClosedError.new(new.changeset) + raise OSM::APIChangesetAlreadyClosedError, new.changeset end end # This is similar to above, just some validations don't apply def check_create_consistency(new, user) if new.changeset.nil? - raise OSM::APIChangesetMissingError.new + raise OSM::APIChangesetMissingError elsif new.changeset.user_id != user.id - raise OSM::APIUserChangesetMismatchError.new + raise OSM::APIUserChangesetMismatchError elsif !new.changeset.is_open? - raise OSM::APIChangesetAlreadyClosedError.new(new.changeset) + raise OSM::APIChangesetAlreadyClosedError, new.changeset end end @@ -37,11 +37,11 @@ module ConsistencyValidations # check user credentials - only the user who opened a changeset # may alter it. if changeset.nil? - raise OSM::APIChangesetMissingError.new + raise OSM::APIChangesetMissingError elsif user.id != changeset.user_id - raise OSM::APIUserChangesetMismatchError.new + raise OSM::APIUserChangesetMismatchError elsif !changeset.is_open? - raise OSM::APIChangesetAlreadyClosedError.new(changeset) + raise OSM::APIChangesetAlreadyClosedError, changeset end end end diff --git a/lib/daemons/gpx_import_ctl b/lib/daemons/gpx_import_ctl index 00b3a00b3..495ce1fb1 100755 --- a/lib/daemons/gpx_import_ctl +++ b/lib/daemons/gpx_import_ctl @@ -6,7 +6,7 @@ require "erb" class Hash def with_symbols! - keys.each { |key| self[key.to_s.to_sym] = self[key] } + each_key { |key| self[key.to_s.to_sym] = self[key] } self end end diff --git a/lib/diff_reader.rb b/lib/diff_reader.rb index c2e7f1839..94c41a6d5 100644 --- a/lib/diff_reader.rb +++ b/lib/diff_reader.rb @@ -86,8 +86,8 @@ class DiffReader with_element do |model_name, _model_attributes| model = MODELS[model_name] if model.nil? - raise OSM::APIBadUserInput.new("Unexpected element type #{model_name}, " + - "expected node, way or relation.") + raise OSM::APIBadUserInput, "Unexpected element type #{model_name}, " \ + "expected node, way or relation." end # new in libxml-ruby >= 2, expand returns an element not associated # with a document. this means that there's no encoding parameter, @@ -130,7 +130,7 @@ class DiffReader # take the first element and check that it is an osmChange element @reader.read - raise OSM::APIBadUserInput.new("Document element should be 'osmChange'.") if @reader.name != "osmChange" + raise OSM::APIBadUserInput, "Document element should be 'osmChange'." if @reader.name != "osmChange" result = OSM::API.new.get_xml_doc result.root.name = "diffResult" @@ -152,7 +152,7 @@ class DiffReader # check if the placeholder ID has been given before and throw # an exception if it has - we can't create the same element twice. model_sym = model.to_s.downcase.to_sym - raise OSM::APIBadUserInput.new("Placeholder IDs must be unique for created elements.") if ids[model_sym].include? placeholder_id + raise OSM::APIBadUserInput, "Placeholder IDs must be unique for created elements." if ids[model_sym].include? placeholder_id # some elements may have placeholders for other elements in the # diff, so we must fix these before saving the element. @@ -252,7 +252,7 @@ class DiffReader else # no other actions to choose from, so it must be the users fault! - raise OSM::APIChangesetActionInvalid.new(action_name) + raise OSM::APIChangesetActionInvalid, action_name end end diff --git a/lib/gpx.rb b/lib/gpx.rb index 3ec11c5c4..ee9d53afa 100644 --- a/lib/gpx.rb +++ b/lib/gpx.rb @@ -31,7 +31,7 @@ module GPX elsif reader.name == "ele" && point point.altitude = reader.read_string.to_f elsif reader.name == "time" && point - point.timestamp = DateTime.parse(reader.read_string) + point.timestamp = Time.parse(reader.read_string) end elsif reader.node_type == XML::Reader::TYPE_END_ELEMENT if reader.name == "trkpt" && point && point.valid? diff --git a/lib/not_redactable.rb b/lib/not_redactable.rb index 7fe119fea..6a5773296 100644 --- a/lib/not_redactable.rb +++ b/lib/not_redactable.rb @@ -6,6 +6,6 @@ module NotRedactable end def redact!(_r) - raise OSM::APICannotRedactError.new + raise OSM::APICannotRedactError end end diff --git a/lib/osm.rb b/lib/osm.rb index 80b68c2a9..e4835a76b 100644 --- a/lib/osm.rb +++ b/lib/osm.rb @@ -532,7 +532,7 @@ module OSM # Parse a float, raising a specified exception on failure def self.parse_float(str, klass, *args) Float(str) - rescue + rescue StandardError raise klass.new(*args) end @@ -553,7 +553,7 @@ module OSM tilesql = QuadTile.sql_for_area(bbox, prefix) bbox = bbox.to_scaled - "#{tilesql} AND #{prefix}latitude BETWEEN #{bbox.min_lat} AND #{bbox.max_lat} " + + "#{tilesql} AND #{prefix}latitude BETWEEN #{bbox.min_lat} AND #{bbox.max_lat} " \ "AND #{prefix}longitude BETWEEN #{bbox.min_lon} AND #{bbox.max_lon}" end diff --git a/lib/redactable.rb b/lib/redactable.rb index 6adfec72a..d827cfd74 100644 --- a/lib/redactable.rb +++ b/lib/redactable.rb @@ -13,7 +13,7 @@ module Redactable def redact!(redaction) # check that this version isn't the current version - raise OSM::APICannotRedactError.new if is_latest_version? + raise OSM::APICannotRedactError if is_latest_version? # make the change self.redaction = redaction diff --git a/lib/rich_text.rb b/lib/rich_text.rb index db296967b..d0539b2b0 100644 --- a/lib/rich_text.rb +++ b/lib/rich_text.rb @@ -57,9 +57,9 @@ module RichText def linkify(text) if text.html_safe? - Rinku.auto_link(text, :urls, tag_options(:rel => "nofollow")).html_safe + Rinku.auto_link(text, :urls, tag_builder.tag_options(:rel => "nofollow")).html_safe else - Rinku.auto_link(text, :urls, tag_options(:rel => "nofollow")) + Rinku.auto_link(text, :urls, tag_builder.tag_options(:rel => "nofollow")) end end end diff --git a/lib/session_persistence.rb b/lib/session_persistence.rb index 7d42b71e7..5e933f48a 100644 --- a/lib/session_persistence.rb +++ b/lib/session_persistence.rb @@ -41,7 +41,7 @@ module SessionPersistence # session_expires_after 1.hour # session_expires_after 2.weeks def session_expires_after(seconds) - session[session_persistence_key] = seconds + session[session_persistence_key] = seconds.to_i end # Expire the session. @@ -55,7 +55,7 @@ module SessionPersistence if session[session_persistence_key] request.session_options[:expire_after] = session[session_persistence_key] end - rescue + rescue StandardError reset_session end end diff --git a/lib/tasks/auto_annotate_models.rake b/lib/tasks/auto_annotate_models.rake new file mode 100644 index 000000000..53252b769 --- /dev/null +++ b/lib/tasks/auto_annotate_models.rake @@ -0,0 +1,48 @@ +# NOTE: only doing this in development as some production environments (Heroku) +# NOTE: are sensitive to local FS writes, and besides -- it's just not proper +# NOTE: to have a dev-mode tool do its thing in production. +if Rails.env.development? + task :set_annotation_options do + # You can override any of these by setting an environment variable of the + # same name. + Annotate.set_defaults( + "routes" => "false", + "position_in_routes" => "before", + "position_in_class" => "before", + "position_in_test" => "before", + "position_in_fixture" => "before", + "position_in_factory" => "before", + "position_in_serializer" => "before", + "show_foreign_keys" => "true", + "show_indexes" => "true", + "simple_indexes" => "false", + "model_dir" => "app/models", + "root_dir" => "", + "include_version" => "false", + "require" => "", + "exclude_tests" => "true", + "exclude_fixtures" => "true", + "exclude_factories" => "true", + "exclude_serializers" => "true", + "exclude_scaffolds" => "true", + "exclude_controllers" => "true", + "exclude_helpers" => "true", + "ignore_model_sub_dir" => "false", + "ignore_columns" => nil, + "ignore_routes" => nil, + "ignore_unknown_models" => "false", + "hide_limit_column_types" => "integer,boolean", + "skip_on_db_migrate" => "false", + "format_bare" => "true", + "format_rdoc" => "false", + "format_markdown" => "false", + "sort" => "false", + "force" => "false", + "trace" => "false", + "wrapper_open" => nil, + "wrapper_close" => nil + ) + end + + Annotate.load_tasks +end diff --git a/lib/tasks/testing.rake b/lib/tasks/testing.rake index 3d933a3aa..924698c7f 100644 --- a/lib/tasks/testing.rake +++ b/lib/tasks/testing.rake @@ -1,6 +1,10 @@ +task "test" do + Rails::TestUnit::Runner.rake_run(["test/system"]) +end + namespace :test do task "lib" => "test:prepare" do $LOAD_PATH << "test" - Minitest.rake_run(["test/lib"]) + Rails::TestUnit::Runner.rake_run(["test/lib"]) end end diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb new file mode 100644 index 000000000..18d5ec2f7 --- /dev/null +++ b/test/application_system_test_case.rb @@ -0,0 +1,14 @@ +require "test_helper" +require "capybara/poltergeist" + +WebMock.disable_net_connect!(:allow_localhost => true) + +class ApplicationSystemTestCase < ActionDispatch::SystemTestCase + driven_by :poltergeist, :screen_size => [1400, 1400] + + def initialize(*args) + stub_request(:get, "http://api.hostip.info/country.php?ip=127.0.0.1") + .to_return(:status => 404) + super(*args) + end +end diff --git a/test/controllers/changeset_controller_test.rb b/test/controllers/changeset_controller_test.rb index 9bf3a4b8e..a0f7960c3 100644 --- a/test/controllers/changeset_controller_test.rb +++ b/test/controllers/changeset_controller_test.rb @@ -98,16 +98,16 @@ class ChangesetControllerTest < ActionController::TestCase def test_create basic_authorization create(:user, :data_public => false).email, "test" # Create the first user's changeset - content "" + - "" + + content "" \ + "" \ "" put :create assert_require_public_data basic_authorization create(:user).email, "test" # Create the first user's changeset - content "" + - "" + + content "" \ + "" \ "" put :create @@ -327,7 +327,7 @@ class ChangesetControllerTest < ActionController::TestCase # simple diff to change a node, way and relation by removing # their tags - diff = < @@ -343,7 +343,7 @@ class ChangesetControllerTest < ActionController::TestCase -EOF +CHANGESET # upload it content diff @@ -357,7 +357,7 @@ EOF # simple diff to change a node, way and relation by removing # their tags - diff = < @@ -373,7 +373,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -387,7 +387,7 @@ EOF # simple diff to change a node, way and relation by removing # their tags - diff = < @@ -403,7 +403,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -429,7 +429,7 @@ EOF basic_authorization user.email, "test" # simple diff to create a node way and relation using placeholders - diff = < @@ -448,7 +448,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -561,8 +561,8 @@ EOF basic_authorization create(:user).email, "test" # create a temporary changeset - content "" + - "" + + content "" \ + "" \ "" assert_difference "Changeset.count", 1 do put :create @@ -582,7 +582,7 @@ EOF # upload some widely-spaced nodes, spiralling positive and negative to cause # largest bbox over-expansion possible. - diff = < @@ -605,7 +605,7 @@ EOF -EOF +CHANGESET # upload it, which used to cause an error like "PGError: ERROR: # integer out of range" (bug #2152). but shouldn't any more. @@ -739,7 +739,7 @@ EOF basic_authorization changeset.user.email, "test" # simple diff to create a node way and relation using placeholders - diff = < @@ -747,7 +747,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -770,7 +770,7 @@ EOF basic_authorization changeset.user.email, "test" # simple diff to create a node way and relation using placeholders - diff = < @@ -790,7 +790,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -832,7 +832,7 @@ EOF basic_authorization changeset.user.email, "test" # simple diff to create a node way and relation using placeholders - diff = < @@ -854,7 +854,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -878,7 +878,7 @@ EOF # change the location of a node multiple times, each time referencing # the last version. doesn't this depend on version numbers being # sequential? - diff = < @@ -891,7 +891,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -914,14 +914,14 @@ EOF basic_authorization changeset.user.email, "test" - diff = < -EOF +CHANGESET # upload it content diff @@ -937,13 +937,13 @@ EOF basic_authorization changeset.user.email, "test" - diff = < -EOF +CHANGESET # upload it content diff @@ -959,13 +959,13 @@ EOF basic_authorization changeset.user.email, "test" - diff = < -EOF +CHANGESET content diff post :upload, :params => { :id => changeset.id } assert_response :bad_request, "Shouldn't be able to upload a diff with the action ping" @@ -985,7 +985,7 @@ EOF basic_authorization changeset.user.email, "test" - diff = < @@ -997,7 +997,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -1021,7 +1021,7 @@ EOF basic_authorization changeset.user.email, "test" - diff = < @@ -1035,7 +1035,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -1056,7 +1056,7 @@ EOF basic_authorization changeset.user.email, "test" - diff = < @@ -1064,7 +1064,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -1082,7 +1082,7 @@ EOF basic_authorization changeset.user.email, "test" - diff = < @@ -1096,7 +1096,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -1106,7 +1106,7 @@ EOF assert_equal "Placeholder node not found for reference -4 in way -1", @response.body # the same again, but this time use an existing way - diff = < @@ -1120,7 +1120,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -1139,7 +1139,7 @@ EOF basic_authorization changeset.user.email, "test" - diff = < @@ -1153,7 +1153,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -1163,7 +1163,7 @@ EOF assert_equal "Placeholder Node not found for reference -4 in relation -1.", @response.body # the same again, but this time use an existing relation - diff = < @@ -1177,7 +1177,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -1193,8 +1193,8 @@ EOF def test_upload_node_move basic_authorization create(:user).email, "test" - content "" + - "" + + content "" \ + "" \ "" put :create assert_response :success @@ -1231,8 +1231,8 @@ EOF def test_upload_way_extend basic_authorization create(:user).email, "test" - content "" + - "" + + content "" \ + "" \ "" put :create assert_response :success @@ -1280,7 +1280,7 @@ EOF # upload it content diff post :upload, :params => { :id => changeset.id } - assert_response(:success, "should be able to upload " + + assert_response(:success, "should be able to upload " \ "empty changeset: " + diff) end end @@ -1324,8 +1324,8 @@ EOF basic_authorization create(:user, :data_public => false).email, "test" # create a temporary changeset - content "" + - "" + + content "" \ + "" \ "" put :create assert_response :forbidden @@ -1334,15 +1334,15 @@ EOF basic_authorization create(:user).email, "test" # create a temporary changeset - content "" + - "" + + content "" \ + "" \ "" put :create assert_response :success changeset_id = @response.body.to_i # add a diff to it - diff = < @@ -1355,7 +1355,7 @@ EOF -EOF +CHANGESET # upload it content diff @@ -1380,8 +1380,8 @@ EOF basic_authorization create(:user).email, "test" # create a temporary changeset - content "" + - "" + + content "" \ + "" \ "" put :create assert_response :success @@ -1442,15 +1442,15 @@ OSMFILE basic_authorization create(:user).email, "test" # create a temporary changeset - content "" + - "" + + content "" \ + "" \ "" put :create assert_response :success changeset_id = @response.body.to_i # add a diff to it - diff = < @@ -1470,7 +1470,7 @@ OSMFILE -EOF +CHANGESET # upload it content diff @@ -1880,7 +1880,7 @@ EOF # check that the changeset is now closed as well assert(!changeset.is_open?, - "changeset should have been auto-closed by exceeding " + + "changeset should have been auto-closed by exceeding " \ "element limit.") end @@ -2060,6 +2060,8 @@ EOF # This should display the last 20 non-empty changesets def test_feed changeset = create(:changeset, :num_changes => 1) + create(:changeset_tag, :changeset => changeset) + create(:changeset_tag, :changeset => changeset, :k => "website", :v => "http://example.com/") closed_changeset = create(:changeset, :closed, :num_changes => 1) _empty_changeset = create(:changeset, :num_changes => 0) @@ -2075,6 +2077,8 @@ EOF # This should display the last 20 changesets closed in a specific area def test_feed_bbox changeset = create(:changeset, :num_changes => 1, :min_lat => 5 * GeoRecord::SCALE, :min_lon => 5 * GeoRecord::SCALE, :max_lat => 5 * GeoRecord::SCALE, :max_lon => 5 * GeoRecord::SCALE) + create(:changeset_tag, :changeset => changeset) + create(:changeset_tag, :changeset => changeset, :k => "website", :v => "http://example.com/") closed_changeset = create(:changeset, :closed, :num_changes => 1, :min_lat => 5 * GeoRecord::SCALE, :min_lon => 5 * GeoRecord::SCALE, :max_lat => 5 * GeoRecord::SCALE, :max_lon => 5 * GeoRecord::SCALE) _elsewhere_changeset = create(:changeset, :num_changes => 1, :min_lat => -5 * GeoRecord::SCALE, :min_lon => -5 * GeoRecord::SCALE, :max_lat => -5 * GeoRecord::SCALE, :max_lon => -5 * GeoRecord::SCALE) _empty_changeset = create(:changeset, :num_changes => 0, :min_lat => -5 * GeoRecord::SCALE, :min_lon => -5 * GeoRecord::SCALE, :max_lat => -5 * GeoRecord::SCALE, :max_lon => -5 * GeoRecord::SCALE) @@ -2092,6 +2096,8 @@ EOF def test_feed_user user = create(:user) changesets = create_list(:changeset, 3, :user => user, :num_changes => 4) + create(:changeset_tag, :changeset => changesets[1]) + create(:changeset_tag, :changeset => changesets[1], :k => "website", :v => "http://example.com/") _other_changeset = create(:changeset) get :feed, :params => { :format => :atom, :display_name => user.display_name } diff --git a/test/controllers/diary_entry_controller_test.rb b/test/controllers/diary_entry_controller_test.rb index fcd93eb2a..f95c57d7c 100644 --- a/test/controllers/diary_entry_controller_test.rb +++ b/test/controllers/diary_entry_controller_test.rb @@ -254,7 +254,7 @@ class DiaryEntryControllerTest < ActionController::TestCase get :edit, :params => { :display_name => entry.user.display_name, :id => entry.id } assert_response :redirect - assert_redirected_to :controller => :user, :action => :login, :referer => "/user/#{URI.encode(entry.user.display_name)}/diary/#{entry.id}/edit" + assert_redirected_to :controller => :user, :action => :login, :referer => "/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}/edit" # Verify that you get a not found error, when you pass a bogus id get :edit, @@ -284,7 +284,7 @@ class DiaryEntryControllerTest < ActionController::TestCase assert_select "h1", :text => /Edit diary entry/, :count => 1 end assert_select "div#content", :count => 1 do - assert_select "form[action='/user/#{URI.encode(entry.user.display_name)}/diary/#{entry.id}/edit'][method=post]", :count => 1 do + assert_select "form[action='/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}/edit'][method=post]", :count => 1 do assert_select "input#diary_entry_title[name='diary_entry[title]'][value='#{entry.title}']", :count => 1 assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :text => entry.body, :count => 1 assert_select "select#diary_entry_language_code", :count => 1 @@ -329,7 +329,7 @@ class DiaryEntryControllerTest < ActionController::TestCase assert_select "abbr[class='geo'][title='#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}']", :count => 1 # As we're not logged in, check that you cannot edit # print @response.body - assert_select "a[href='/user/#{URI.encode(entry.user.display_name)}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1 + assert_select "a[href='/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1 end # and when not logged in as the user who wrote the entry @@ -350,7 +350,7 @@ class DiaryEntryControllerTest < ActionController::TestCase assert_select "abbr[class=geo][title='#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}']", :count => 1 # As we're not logged in, check that you cannot edit assert_select "li[class='hidden show_if_user_#{entry.user.id}']", :count => 1 do - assert_select "a[href='/user/#{URI.encode(entry.user.display_name)}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1 + assert_select "a[href='/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1 end end end @@ -430,7 +430,7 @@ class DiaryEntryControllerTest < ActionController::TestCase assert_response :success assert_select ".diary-comment", :count => 1 do assert_select "#comment#{comment.id}", :count => 1 do - assert_select "a[href='/user/#{URI.encode(other_user.display_name)}']", :text => other_user.display_name, :count => 1 + assert_select "a[href='/user/#{ERB::Util.u(other_user.display_name)}']", :text => other_user.display_name, :count => 1 end assert_select ".richtext", :text => /New comment/, :count => 1 end @@ -890,7 +890,7 @@ class DiaryEntryControllerTest < ActionController::TestCase assert_select "div.diary_post", entries.count entries.each do |entry| - assert_select "a[href=?]", "/user/#{URI.encode(entry.user.display_name)}/diary/#{entry.id}" + assert_select "a[href=?]", "/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}" end end end diff --git a/test/controllers/geocoder_controller_test.rb b/test/controllers/geocoder_controller_test.rb index ecddf96aa..ee8991d48 100644 --- a/test/controllers/geocoder_controller_test.rb +++ b/test/controllers/geocoder_controller_test.rb @@ -1,4 +1,3 @@ -# coding: utf-8 require "test_helper" require "geocoder_controller" @@ -15,10 +14,6 @@ class GeocoderControllerTest < ActionController::TestCase { :path => "/geocoder/search_latlon", :method => :get }, { :controller => "geocoder", :action => "search_latlon" } ) - assert_routing( - { :path => "/geocoder/search_us_postcode", :method => :get }, - { :controller => "geocoder", :action => "search_us_postcode" } - ) assert_routing( { :path => "/geocoder/search_uk_postcode", :method => :get }, { :controller => "geocoder", :action => "search_uk_postcode" } @@ -253,7 +248,7 @@ class GeocoderControllerTest < ActionController::TestCase ].each do |code| post :search, :params => { :query => code } assert_response :success - assert_equal %w[us_postcode osm_nominatim], assigns(:sources) + assert_equal %w[osm_nominatim], assigns(:sources) end end @@ -304,25 +299,6 @@ class GeocoderControllerTest < ActionController::TestCase results_check_error "Longitude 180.23 out of range" end - ## - # Test the US postcode search - def test_search_us_postcode - with_http_stubs "geocoder_us" do - get :search_us_postcode, :xhr => true, - :params => { :query => "90210", :zoom => 10, - :minlon => -0.559, :minlat => 51.217, - :maxlon => 0.836, :maxlat => 51.766 } - results_check :prefix => "Beverly Hills, CA,", :name => "90210", - :lat => 34.088808, :lon => -118.40612 - - get :search_us_postcode, :xhr => true, - :params => { :query => "00000", :zoom => 10, - :minlon => -0.559, :minlat => 51.217, - :maxlon => 0.836, :maxlat => 51.766 } - results_check - end - end - ## # Test the UK postcode search def test_search_uk_postcode diff --git a/test/controllers/message_controller_test.rb b/test/controllers/message_controller_test.rb index 8a7ae70de..930341f29 100644 --- a/test/controllers/message_controller_test.rb +++ b/test/controllers/message_controller_test.rb @@ -63,7 +63,7 @@ class MessageControllerTest < ActionController::TestCase get :new, :params => { :display_name => recipient_user.display_name } assert_response :success assert_template "new" - assert_select "title", "OpenStreetMap | Send message" + assert_select "title", "Send message | OpenStreetMap" assert_select "form[action='#{new_message_path(:display_name => recipient_user.display_name)}']", :count => 1 do assert_select "input#message_title", :count => 1 assert_select "textarea#message_body", :count => 1 @@ -89,7 +89,7 @@ class MessageControllerTest < ActionController::TestCase end assert_response :success assert_template "new" - assert_select "title", "OpenStreetMap | Send message" + assert_select "title", "Send message | OpenStreetMap" assert_select "form[action='#{new_message_path(:display_name => recipient_user.display_name)}']", :count => 1 do assert_select "input#message_title", :count => 1 do assert_select "[value='Test Message']" @@ -117,7 +117,7 @@ class MessageControllerTest < ActionController::TestCase end assert_response :success assert_template "new" - assert_select "title", "OpenStreetMap | Send message" + assert_select "title", "Send message | OpenStreetMap" assert_select "form[action='#{new_message_path(:display_name => recipient_user.display_name)}']", :count => 1 do assert_select "input#message_title", :count => 1 do assert_select "[value='Test Message']" @@ -145,7 +145,7 @@ class MessageControllerTest < ActionController::TestCase end assert_response :success assert_template "new" - assert_select "title", "OpenStreetMap | Send message" + assert_select "title", "Send message | OpenStreetMap" assert_select "form[action='#{new_message_path(:display_name => recipient_user.display_name)}']", :count => 1 do assert_select "input#message_title", :count => 1 do assert_select "[value='']" @@ -244,7 +244,7 @@ class MessageControllerTest < ActionController::TestCase get :reply, :params => { :message_id => unread_message.id } assert_response :success assert_template "new" - assert_select "title", "OpenStreetMap | Re: #{unread_message.title}" + assert_select "title", "Re: #{unread_message.title} | OpenStreetMap" assert_select "form[action='#{new_message_path(:display_name => user.display_name)}']", :count => 1 do assert_select "input#message_title[value='Re: #{unread_message.title}']", :count => 1 assert_select "textarea#message_body", :count => 1 diff --git a/test/controllers/node_controller_test.rb b/test/controllers/node_controller_test.rb index f2ef39dff..1fdb3f907 100644 --- a/test/controllers/node_controller_test.rb +++ b/test/controllers/node_controller_test.rb @@ -496,8 +496,8 @@ class NodeControllerTest < ActionController::TestCase # try and put something into a string that the API might # use unquoted and therefore allow code injection... - content "" + - '' + + content "" \ + '' \ "" put :create assert_require_public_data "Shouldn't be able to create with non-public user" @@ -507,8 +507,8 @@ class NodeControllerTest < ActionController::TestCase # try and put something into a string that the API might # use unquoted and therefore allow code injection... - content "" + - '' + + content "" \ + '' \ "" put :create assert_response :success diff --git a/test/controllers/old_node_controller_test.rb b/test/controllers/old_node_controller_test.rb index a05326e1e..e08fbb65e 100644 --- a/test/controllers/old_node_controller_test.rb +++ b/test/controllers/old_node_controller_test.rb @@ -137,7 +137,7 @@ class OldNodeControllerTest < ActionController::TestCase end # check all the versions - versions.keys.each do |key| + versions.each_key do |key| get :version, :params => { :id => nodeid, :version => key.to_i } assert_response :success, diff --git a/test/controllers/relation_controller_test.rb b/test/controllers/relation_controller_test.rb index 4b41cbc22..f90b6b58e 100644 --- a/test/controllers/relation_controller_test.rb +++ b/test/controllers/relation_controller_test.rb @@ -216,8 +216,8 @@ class RelationControllerTest < ActionController::TestCase ### # create an relation with a node as member # This time try with a role attribute in the relation - content "" + - "" + + content "" \ + "" \ "" put :create # hope for forbidden due to user @@ -227,7 +227,7 @@ class RelationControllerTest < ActionController::TestCase ### # create an relation with a node as member, this time test that we don't # need a role attribute to be included - content "" + + content "" \ "" + "" put :create # hope for forbidden due to user @@ -236,9 +236,9 @@ class RelationControllerTest < ActionController::TestCase ### # create an relation with a way and a node as members - content "" + - "" + - "" + + content "" \ + "" \ + "" \ "" put :create # hope for forbidden, due to user @@ -277,8 +277,8 @@ class RelationControllerTest < ActionController::TestCase ### # create an relation with a node as member # This time try with a role attribute in the relation - content "" + - "" + + content "" \ + "" \ "" put :create # hope for success @@ -308,7 +308,7 @@ class RelationControllerTest < ActionController::TestCase ### # create an relation with a node as member, this time test that we don't # need a role attribute to be included - content "" + + content "" \ "" + "" put :create # hope for success @@ -337,9 +337,9 @@ class RelationControllerTest < ActionController::TestCase ### # create an relation with a way and a node as members - content "" + - "" + - "" + + content "" \ + "" \ + "" \ "" put :create # hope for success @@ -461,8 +461,8 @@ class RelationControllerTest < ActionController::TestCase basic_authorization user.email, "test" # create a relation with non-existing node as member - content "" + - "" + + content "" \ + "" \ "" put :create # expect failure @@ -482,8 +482,8 @@ class RelationControllerTest < ActionController::TestCase basic_authorization user.email, "test" # create some xml that should return an error - content "" + - "" + + content "" \ + "" \ "" put :create # expect failure @@ -1063,7 +1063,7 @@ OSM assert_equal a_tags.keys, b_tags.keys, "Tag keys should be identical." a_tags.each do |k, v| assert_equal v, b_tags[k], - "Tags which were not altered should be the same. " + + "Tags which were not altered should be the same. " \ "#{a_tags.inspect} != #{b_tags.inspect}" end end diff --git a/test/controllers/trace_controller_test.rb b/test/controllers/trace_controller_test.rb index 4610852fb..182fe8c02 100644 --- a/test/controllers/trace_controller_test.rb +++ b/test/controllers/trace_controller_test.rb @@ -1,4 +1,5 @@ require "test_helper" +require "digest" require "minitest/mock" class TraceControllerTest < ActionController::TestCase @@ -355,15 +356,15 @@ class TraceControllerTest < ActionController::TestCase # First with no auth, which should work since the trace is public get :data, :params => { :display_name => public_trace_file.user.display_name, :id => public_trace_file.id } - check_trace_data public_trace_file + check_trace_data public_trace_file, "848caa72f2f456d1bd6a0fdf228aa1b9" # Now with some other user, which should work since the trace is public get :data, :params => { :display_name => public_trace_file.user.display_name, :id => public_trace_file.id }, :session => { :user => create(:user) } - check_trace_data public_trace_file + check_trace_data public_trace_file, "848caa72f2f456d1bd6a0fdf228aa1b9" # And finally we should be able to do it with the owner of the trace get :data, :params => { :display_name => public_trace_file.user.display_name, :id => public_trace_file.id }, :session => { :user => public_trace_file.user } - check_trace_data public_trace_file + check_trace_data public_trace_file, "848caa72f2f456d1bd6a0fdf228aa1b9" end # Test downloading a compressed trace @@ -372,15 +373,15 @@ class TraceControllerTest < ActionController::TestCase # First get the data as is get :data, :params => { :display_name => identifiable_trace_file.user.display_name, :id => identifiable_trace_file.id } - check_trace_data identifiable_trace_file, "application/x-gzip", "gpx.gz" + check_trace_data identifiable_trace_file, "c6422a3d8750faae49ed70e7e8a51b93", "application/x-gzip", "gpx.gz" # Now ask explicitly for XML format get :data, :params => { :display_name => identifiable_trace_file.user.display_name, :id => identifiable_trace_file.id, :format => "xml" } - check_trace_data identifiable_trace_file, "application/xml", "xml" + check_trace_data identifiable_trace_file, "abd6675fdf3024a84fc0a1deac147c0d", "application/xml", "xml" # Now ask explicitly for GPX format get :data, :params => { :display_name => identifiable_trace_file.user.display_name, :id => identifiable_trace_file.id, :format => "gpx" } - check_trace_data identifiable_trace_file + check_trace_data identifiable_trace_file, "abd6675fdf3024a84fc0a1deac147c0d" end # Check an anonymous trace can't be downloaded by another user @@ -397,7 +398,7 @@ class TraceControllerTest < ActionController::TestCase # And finally we should be able to do it with the owner of the trace get :data, :params => { :display_name => anon_trace_file.user.display_name, :id => anon_trace_file.id }, :session => { :user => anon_trace_file.user } - check_trace_data anon_trace_file + check_trace_data anon_trace_file, "66179ca44f1e93d8df62e2b88cbea732" end # Test downloading a trace that doesn't exist @@ -751,12 +752,12 @@ class TraceControllerTest < ActionController::TestCase # Now with some other user, which should work since the trace is public basic_authorization create(:user).display_name, "test" get :api_data, :params => { :id => public_trace_file.id } - check_trace_data public_trace_file + check_trace_data public_trace_file, "848caa72f2f456d1bd6a0fdf228aa1b9" # And finally we should be able to do it with the owner of the trace basic_authorization public_trace_file.user.display_name, "test" get :api_data, :params => { :id => public_trace_file.id } - check_trace_data public_trace_file + check_trace_data public_trace_file, "848caa72f2f456d1bd6a0fdf228aa1b9" end # Test downloading a compressed trace through the api @@ -768,15 +769,15 @@ class TraceControllerTest < ActionController::TestCase # First get the data as is get :api_data, :params => { :id => identifiable_trace_file.id } - check_trace_data identifiable_trace_file, "application/x-gzip", "gpx.gz" + check_trace_data identifiable_trace_file, "c6422a3d8750faae49ed70e7e8a51b93", "application/x-gzip", "gpx.gz" # Now ask explicitly for XML format get :api_data, :params => { :id => identifiable_trace_file.id, :format => "xml" } - check_trace_data identifiable_trace_file, "application/xml", "xml" + check_trace_data identifiable_trace_file, "abd6675fdf3024a84fc0a1deac147c0d", "application/xml", "xml" # Now ask explicitly for GPX format get :api_data, :params => { :id => identifiable_trace_file.id, :format => "gpx" } - check_trace_data identifiable_trace_file + check_trace_data identifiable_trace_file, "abd6675fdf3024a84fc0a1deac147c0d" end # Check an anonymous trace can't be downloaded by another user through the api @@ -795,7 +796,7 @@ class TraceControllerTest < ActionController::TestCase # And finally we should be able to do it with the owner of the trace basic_authorization anon_trace_file.user.display_name, "test" get :api_data, :params => { :id => anon_trace_file.id } - check_trace_data anon_trace_file + check_trace_data anon_trace_file, "66179ca44f1e93d8df62e2b88cbea732" end # Test downloading a trace that doesn't exist through the api @@ -931,6 +932,23 @@ class TraceControllerTest < ActionController::TestCase assert_equal nt.visibility, t.visibility end + # Test that updating a trace doesn't duplicate the tags + def test_api_update_tags + tracetag = create(:tracetag) + trace = tracetag.trace + basic_authorization trace.user.display_name, "test" + + content trace.to_xml + put :api_update, :params => { :id => trace.id } + assert_response :success + + updated = Trace.find(trace.id) + # Ensure there's only one tag in the database after updating + assert_equal Tracetag.count, 1 + # The new tag object might have a different id, so check the string representation + assert_equal trace.tagstring, updated.tagstring + end + # Check deleting a trace through the api def test_api_delete public_trace_file = create(:trace, :visibility => "public") @@ -1017,8 +1035,9 @@ class TraceControllerTest < ActionController::TestCase end end - def check_trace_data(trace, content_type = "application/gpx+xml", extension = "gpx") + def check_trace_data(trace, digest, content_type = "application/gpx+xml", extension = "gpx") assert_response :success + assert_equal digest, Digest::MD5.hexdigest(response.body) assert_equal content_type, response.content_type assert_equal "attachment; filename=\"#{trace.id}.#{extension}\"", @response.header["Content-Disposition"] end diff --git a/test/controllers/user_controller_test.rb b/test/controllers/user_controller_test.rb index 4dcb1108a..e149b83c7 100644 --- a/test/controllers/user_controller_test.rb +++ b/test/controllers/user_controller_test.rb @@ -749,6 +749,12 @@ class UserControllerTest < ActionController::TestCase assert_response :success assert_template :reset_password + # Test that errors are reported for erroneous submissions + post :reset_password, :params => { :token => token.token, :user => { :pass_crypt => "new_password", :pass_crypt_confirmation => "different_password" } } + assert_response :success + assert_template :reset_password + assert_select "div#errorExplanation" + # Test setting a new password post :reset_password, :params => { :token => token.token, :user => { :pass_crypt => "new_password", :pass_crypt_confirmation => "new_password" } } assert_response :redirect @@ -772,7 +778,7 @@ class UserControllerTest < ActionController::TestCase # you are not logged in get :account, :params => { :display_name => user.display_name } assert_response :redirect - assert_redirected_to :controller => :user, :action => "login", :referer => "/user/#{URI.encode(user.display_name)}/account" + assert_redirected_to :controller => :user, :action => "login", :referer => "/user/#{ERB::Util.u(user.display_name)}/account" # Make sure that you are blocked when not logged in as the right user get :account, :params => { :display_name => user.display_name }, :session => { :user => create(:user) } @@ -784,7 +790,8 @@ class UserControllerTest < ActionController::TestCase assert_template :account assert_select "form#accountForm" do |form| assert_equal "post", form.attr("method").to_s - assert_equal "/user/#{URI.encode(user.display_name)}/account", form.attr("action").to_s + assert_select "input[name='_method']", false + assert_equal "/user/#{ERB::Util.u(user.display_name)}/account", form.attr("action").to_s end # Updating the description should work @@ -852,7 +859,7 @@ class UserControllerTest < ActionController::TestCase # Adding external authentication should redirect to the auth provider post :account, :params => { :display_name => user.display_name, :user => user.attributes.merge(:auth_provider => "openid", :auth_uid => "gmail.com") }, :session => { :user => user } assert_response :redirect - assert_redirected_to auth_path(:provider => "openid", :openid_url => "https://www.google.com/accounts/o8/id", :origin => "/user/#{URI.encode(user.display_name)}/account") + assert_redirected_to auth_path(:provider => "openid", :openid_url => "https://www.google.com/accounts/o8/id", :origin => "/user/#{ERB::Util.u(user.display_name)}/account") # Changing name to one that exists should fail new_attributes = user.attributes.dup.merge(:display_name => create(:user).display_name) @@ -934,14 +941,14 @@ class UserControllerTest < ActionController::TestCase get :view, :params => { :display_name => user.display_name } assert_response :success assert_select "div#userinformation" do - assert_select "a[href^='/user/#{URI.encode(user.display_name)}/history']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/traces']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/diary']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/diary/comments']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/account']", 0 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/blocks']", 0 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/blocks_by']", 0 - assert_select "a[href='/blocks/new/#{URI.encode(user.display_name)}']", 0 + assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/traces']", 1 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary/comments']", 1 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/account']", 0 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0 + assert_select "a[href='/blocks/new/#{ERB::Util.u(user.display_name)}']", 0 end # Test a user who has been blocked @@ -950,14 +957,14 @@ class UserControllerTest < ActionController::TestCase get :view, :params => { :display_name => blocked_user.display_name } assert_response :success assert_select "div#userinformation" do - assert_select "a[href^='/user/#{URI.encode(blocked_user.display_name)}/history']", 1 - assert_select "a[href='/user/#{URI.encode(blocked_user.display_name)}/traces']", 1 - assert_select "a[href='/user/#{URI.encode(blocked_user.display_name)}/diary']", 1 - assert_select "a[href='/user/#{URI.encode(blocked_user.display_name)}/diary/comments']", 1 - assert_select "a[href='/user/#{URI.encode(blocked_user.display_name)}/account']", 0 - assert_select "a[href='/user/#{URI.encode(blocked_user.display_name)}/blocks']", 1 - assert_select "a[href='/user/#{URI.encode(blocked_user.display_name)}/blocks_by']", 0 - assert_select "a[href='/blocks/new/#{URI.encode(blocked_user.display_name)}']", 0 + assert_select "a[href^='/user/#{ERB::Util.u(blocked_user.display_name)}/history']", 1 + assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/traces']", 1 + assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/diary']", 1 + assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/diary/comments']", 1 + assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/account']", 0 + assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/blocks']", 1 + assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/blocks_by']", 0 + assert_select "a[href='/blocks/new/#{ERB::Util.u(blocked_user.display_name)}']", 0 end # Test a moderator who has applied blocks @@ -966,14 +973,14 @@ class UserControllerTest < ActionController::TestCase get :view, :params => { :display_name => moderator_user.display_name } assert_response :success assert_select "div#userinformation" do - assert_select "a[href^='/user/#{URI.encode(moderator_user.display_name)}/history']", 1 - assert_select "a[href='/user/#{URI.encode(moderator_user.display_name)}/traces']", 1 - assert_select "a[href='/user/#{URI.encode(moderator_user.display_name)}/diary']", 1 - assert_select "a[href='/user/#{URI.encode(moderator_user.display_name)}/diary/comments']", 1 - assert_select "a[href='/user/#{URI.encode(moderator_user.display_name)}/account']", 0 - assert_select "a[href='/user/#{URI.encode(moderator_user.display_name)}/blocks']", 0 - assert_select "a[href='/user/#{URI.encode(moderator_user.display_name)}/blocks_by']", 1 - assert_select "a[href='/blocks/new/#{URI.encode(moderator_user.display_name)}']", 0 + assert_select "a[href^='/user/#{ERB::Util.u(moderator_user.display_name)}/history']", 1 + assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/traces']", 1 + assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/diary']", 1 + assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/diary/comments']", 1 + assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/account']", 0 + assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/blocks']", 0 + assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/blocks_by']", 1 + assert_select "a[href='/blocks/new/#{ERB::Util.u(moderator_user.display_name)}']", 0 end # Login as a normal user @@ -983,14 +990,14 @@ class UserControllerTest < ActionController::TestCase get :view, :params => { :display_name => user.display_name } assert_response :success assert_select "div#userinformation" do - assert_select "a[href^='/user/#{URI.encode(user.display_name)}/history']", 1 + assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1 assert_select "a[href='/traces/mine']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/diary']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/diary/comments']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/account']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/blocks']", 0 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/blocks_by']", 0 - assert_select "a[href='/blocks/new/#{URI.encode(user.display_name)}']", 0 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary/comments']", 1 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/account']", 1 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0 + assert_select "a[href='/blocks/new/#{ERB::Util.u(user.display_name)}']", 0 end # Login as a moderator @@ -1000,14 +1007,14 @@ class UserControllerTest < ActionController::TestCase get :view, :params => { :display_name => user.display_name } assert_response :success assert_select "div#userinformation" do - assert_select "a[href^='/user/#{URI.encode(user.display_name)}/history']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/traces']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/diary']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/diary/comments']", 1 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/account']", 0 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/blocks']", 0 - assert_select "a[href='/user/#{URI.encode(user.display_name)}/blocks_by']", 0 - assert_select "a[href='/blocks/new/#{URI.encode(user.display_name)}']", 1 + assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/traces']", 1 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary/comments']", 1 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/account']", 0 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0 + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0 + assert_select "a[href='/blocks/new/#{ERB::Util.u(user.display_name)}']", 1 end end diff --git a/test/controllers/way_controller_test.rb b/test/controllers/way_controller_test.rb index 415033b48..285efe269 100644 --- a/test/controllers/way_controller_test.rb +++ b/test/controllers/way_controller_test.rb @@ -128,8 +128,8 @@ class WayControllerTest < ActionController::TestCase changeset_id = private_changeset.id # create a way with pre-existing nodes - content "" + - "" + + content "" \ + "" \ "" put :create # hope for failure @@ -143,8 +143,8 @@ class WayControllerTest < ActionController::TestCase changeset_id = changeset.id # create a way with pre-existing nodes - content "" + - "" + + content "" \ + "" \ "" put :create # hope for success @@ -188,7 +188,7 @@ class WayControllerTest < ActionController::TestCase # use the first user's open changeset # create a way with non-existing node - content "" + + content "" \ "" put :create # expect failure @@ -196,7 +196,7 @@ class WayControllerTest < ActionController::TestCase "way upload with invalid node using a private user did not return 'forbidden'" # create a way with no nodes - content "" + + content "" \ "" put :create # expect failure @@ -204,7 +204,7 @@ class WayControllerTest < ActionController::TestCase "way upload with no node using a private userdid not return 'forbidden'" # create a way inside a closed changeset - content "" + + content "" \ "" put :create # expect failure @@ -216,7 +216,7 @@ class WayControllerTest < ActionController::TestCase # use the first user's open changeset # create a way with non-existing node - content "" + + content "" \ "" put :create # expect failure @@ -225,7 +225,7 @@ class WayControllerTest < ActionController::TestCase assert_equal "Precondition failed: Way requires the nodes with id in (0), which either do not exist, or are not visible.", @response.body # create a way with no nodes - content "" + + content "" \ "" put :create # expect failure @@ -234,7 +234,7 @@ class WayControllerTest < ActionController::TestCase assert_equal "Precondition failed: Cannot create way: data is invalid.", @response.body # create a way inside a closed changeset - content "" + + content "" \ "" put :create # expect failure @@ -242,9 +242,9 @@ class WayControllerTest < ActionController::TestCase "way upload to closed changeset did not return 'conflict'" # create a way with a tag which is too long - content "" + - "" + - "" + + content "" \ + "" \ + "" \ "" put :create # expect failure diff --git a/test/factories/acls.rb b/test/factories/acls.rb index 3f91df3ab..384fea9c1 100644 --- a/test/factories/acls.rb +++ b/test/factories/acls.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :acl do sequence(:k) { |n| "Key #{n}" } end diff --git a/test/factories/changeset_comments.rb b/test/factories/changeset_comments.rb index 04644580f..fb3eef895 100644 --- a/test/factories/changeset_comments.rb +++ b/test/factories/changeset_comments.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :changeset_comment do sequence(:body) { |n| "Changeset comment #{n}" } visible true diff --git a/test/factories/changeset_tags.rb b/test/factories/changeset_tags.rb index d80f29c7a..633dd0005 100644 --- a/test/factories/changeset_tags.rb +++ b/test/factories/changeset_tags.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :changeset_tag do sequence(:k) { |n| "Key #{n}" } sequence(:v) { |n| "Value #{n}" } diff --git a/test/factories/changesets.rb b/test/factories/changesets.rb index 01d357198..f42242e78 100644 --- a/test/factories/changesets.rb +++ b/test/factories/changesets.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :changeset do created_at Time.now.utc closed_at Time.now.utc + 1.day diff --git a/test/factories/client_applications.rb b/test/factories/client_applications.rb index 5535ee2e7..c2dbf7fa2 100644 --- a/test/factories/client_applications.rb +++ b/test/factories/client_applications.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :client_application do sequence(:name) { |n| "Client application #{n}" } sequence(:url) { |n| "http://example.com/app/#{n}" } diff --git a/test/factories/diary_comments.rb b/test/factories/diary_comments.rb index 2d54f273e..cb5f8eebd 100644 --- a/test/factories/diary_comments.rb +++ b/test/factories/diary_comments.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :diary_comment do sequence(:body) { |n| "This is diary comment #{n}" } diff --git a/test/factories/diary_entries.rb b/test/factories/diary_entries.rb index 666a37ee8..4319f2a63 100644 --- a/test/factories/diary_entries.rb +++ b/test/factories/diary_entries.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :diary_entry do sequence(:title) { |n| "Diary entry #{n}" } sequence(:body) { |n| "This is diary entry #{n}" } diff --git a/test/factories/friends.rb b/test/factories/friends.rb index 749846edb..15317ee0c 100644 --- a/test/factories/friends.rb +++ b/test/factories/friends.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :friend do association :befriender, :factory => :user association :befriendee, :factory => :user diff --git a/test/factories/languages.rb b/test/factories/languages.rb index 0887c9129..ddf4588e9 100644 --- a/test/factories/languages.rb +++ b/test/factories/languages.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :language do code "en" english_name "English" diff --git a/test/factories/messages.rb b/test/factories/messages.rb index 9d9c30a48..ece10ae72 100644 --- a/test/factories/messages.rb +++ b/test/factories/messages.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :message do sequence(:title) { |n| "Message #{n}" } sequence(:body) { |n| "Body text for message #{n}" } diff --git a/test/factories/node.rb b/test/factories/node.rb index bcc1fdbe8..d849755cd 100644 --- a/test/factories/node.rb +++ b/test/factories/node.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :node do latitude 1 * GeoRecord::SCALE longitude 1 * GeoRecord::SCALE diff --git a/test/factories/node_tags.rb b/test/factories/node_tags.rb index 0a10fc65d..359af8631 100644 --- a/test/factories/node_tags.rb +++ b/test/factories/node_tags.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :node_tag do sequence(:k) { |n| "Key #{n}" } sequence(:v) { |n| "Value #{n}" } diff --git a/test/factories/note_comments.rb b/test/factories/note_comments.rb index b06dc378a..d3fb3ce96 100644 --- a/test/factories/note_comments.rb +++ b/test/factories/note_comments.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :note_comment do sequence(:body) { |n| "This is note comment #{n}" } visible true diff --git a/test/factories/notes.rb b/test/factories/notes.rb index 9dbcdf58c..56a9541dc 100644 --- a/test/factories/notes.rb +++ b/test/factories/notes.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :note do latitude 1 * GeoRecord::SCALE longitude 1 * GeoRecord::SCALE diff --git a/test/factories/old_node.rb b/test/factories/old_node.rb index 3eda91a53..089363397 100644 --- a/test/factories/old_node.rb +++ b/test/factories/old_node.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :old_node do latitude 1 * GeoRecord::SCALE longitude 1 * GeoRecord::SCALE diff --git a/test/factories/old_node_tags.rb b/test/factories/old_node_tags.rb index f74e80702..37e755ec2 100644 --- a/test/factories/old_node_tags.rb +++ b/test/factories/old_node_tags.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :old_node_tag do sequence(:k) { |n| "Key #{n}" } sequence(:v) { |n| "Value #{n}" } diff --git a/test/factories/old_relation.rb b/test/factories/old_relation.rb index c4b29fad4..a6e87a38b 100644 --- a/test/factories/old_relation.rb +++ b/test/factories/old_relation.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :old_relation do timestamp Time.now visible true diff --git a/test/factories/old_relation_member.rb b/test/factories/old_relation_member.rb index ad7eeb078..524a71074 100644 --- a/test/factories/old_relation_member.rb +++ b/test/factories/old_relation_member.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :old_relation_member do member_role "" diff --git a/test/factories/old_relation_tags.rb b/test/factories/old_relation_tags.rb index 0a83cc6d7..4a3a1c01c 100644 --- a/test/factories/old_relation_tags.rb +++ b/test/factories/old_relation_tags.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :old_relation_tag do sequence(:k) { |n| "Key #{n}" } sequence(:v) { |n| "Value #{n}" } diff --git a/test/factories/old_way.rb b/test/factories/old_way.rb index a7d5bdbe8..a57ccb713 100644 --- a/test/factories/old_way.rb +++ b/test/factories/old_way.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :old_way do timestamp Time.now visible true diff --git a/test/factories/old_way_node.rb b/test/factories/old_way_node.rb index ac6546293..0a544aaf7 100644 --- a/test/factories/old_way_node.rb +++ b/test/factories/old_way_node.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :old_way_node do sequence_id 1 diff --git a/test/factories/old_way_tags.rb b/test/factories/old_way_tags.rb index 6b3e6cf47..2e5138b6b 100644 --- a/test/factories/old_way_tags.rb +++ b/test/factories/old_way_tags.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :old_way_tag do sequence(:k) { |n| "Key #{n}" } sequence(:v) { |n| "Value #{n}" } diff --git a/test/factories/redaction.rb b/test/factories/redaction.rb index 0ee5f1963..3304af899 100644 --- a/test/factories/redaction.rb +++ b/test/factories/redaction.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :redaction do sequence(:title) { |n| "Redaction #{n}" } sequence(:description) { |n| "Description of redaction #{n}" } diff --git a/test/factories/relation.rb b/test/factories/relation.rb index 44f18f491..c4c947a4f 100644 --- a/test/factories/relation.rb +++ b/test/factories/relation.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :relation do timestamp Time.now visible true diff --git a/test/factories/relation_member.rb b/test/factories/relation_member.rb index b3f69e3e9..4357f3de7 100644 --- a/test/factories/relation_member.rb +++ b/test/factories/relation_member.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :relation_member do member_role "" diff --git a/test/factories/relation_tags.rb b/test/factories/relation_tags.rb index 7fe71448d..074ab93f4 100644 --- a/test/factories/relation_tags.rb +++ b/test/factories/relation_tags.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :relation_tag do sequence(:k) { |n| "Key #{n}" } sequence(:v) { |n| "Value #{n}" } diff --git a/test/factories/tracepoints.rb b/test/factories/tracepoints.rb index c47b7932d..ad520ea1f 100644 --- a/test/factories/tracepoints.rb +++ b/test/factories/tracepoints.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :tracepoint do trackid 1 latitude 1 * GeoRecord::SCALE diff --git a/test/factories/traces.rb b/test/factories/traces.rb index 76fd90590..efc1180cd 100644 --- a/test/factories/traces.rb +++ b/test/factories/traces.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :trace do sequence(:name) { |n| "Trace #{n}.gpx" } sequence(:description) { |n| "This is trace #{n}" } diff --git a/test/factories/tracetags.rb b/test/factories/tracetags.rb index 3dbeeb877..2db07c3b7 100644 --- a/test/factories/tracetags.rb +++ b/test/factories/tracetags.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :tracetag do sequence(:tag) { |n| "Tag #{n}" } diff --git a/test/factories/user.rb b/test/factories/user.rb index 8fe768410..d6ee1fa8c 100644 --- a/test/factories/user.rb +++ b/test/factories/user.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :user do sequence(:email) { |n| "user#{n}@example.com" } sequence(:display_name) { |n| "User #{n}" } diff --git a/test/factories/user_blocks.rb b/test/factories/user_blocks.rb index f1ef5b65b..d206511b4 100644 --- a/test/factories/user_blocks.rb +++ b/test/factories/user_blocks.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :user_block do sequence(:reason) { |n| "User Block #{n}" } ends_at Time.now + 1.day diff --git a/test/factories/user_preferences.rb b/test/factories/user_preferences.rb index e6f0d6b87..6d33e8caa 100644 --- a/test/factories/user_preferences.rb +++ b/test/factories/user_preferences.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :user_preference do sequence(:k) { |n| "Key #{n}" } sequence(:v) { |n| "Value #{n}" } diff --git a/test/factories/user_role.rb b/test/factories/user_role.rb index 0eea25cee..6523342f7 100644 --- a/test/factories/user_role.rb +++ b/test/factories/user_role.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :user_role do user association :granter, :factory => :user diff --git a/test/factories/way.rb b/test/factories/way.rb index 1c31de3d0..68826e919 100644 --- a/test/factories/way.rb +++ b/test/factories/way.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :way do timestamp Time.now visible true diff --git a/test/factories/way_node.rb b/test/factories/way_node.rb index 203c055a7..770de02d9 100644 --- a/test/factories/way_node.rb +++ b/test/factories/way_node.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :way_node do sequence_id 1 diff --git a/test/factories/way_tags.rb b/test/factories/way_tags.rb index 7a60aeea6..8345ec698 100644 --- a/test/factories/way_tags.rb +++ b/test/factories/way_tags.rb @@ -1,4 +1,4 @@ -FactoryGirl.define do +FactoryBot.define do factory :way_tag do sequence(:k) { |n| "Key #{n}" } sequence(:v) { |n| "Value #{n}" } diff --git a/test/helpers/browse_helper_test.rb b/test/helpers/browse_helper_test.rb index 277433356..13f65c976 100644 --- a/test/helpers/browse_helper_test.rb +++ b/test/helpers/browse_helper_test.rb @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - require "test_helper" class BrowseHelperTest < ActionView::TestCase diff --git a/test/helpers/changeset_helper_test.rb b/test/helpers/changeset_helper_test.rb index 9c45b62dc..d932138f8 100644 --- a/test/helpers/changeset_helper_test.rb +++ b/test/helpers/changeset_helper_test.rb @@ -3,7 +3,7 @@ require "test_helper" class ChangesetHelperTest < ActionView::TestCase def test_changeset_user_link changeset = create(:changeset) - assert_equal %(
    #{changeset.user.display_name}), changeset_user_link(changeset) + assert_equal %(#{changeset.user.display_name}), changeset_user_link(changeset) changeset = create(:changeset, :user => create(:user, :data_public => false)) assert_equal "anonymous", changeset_user_link(changeset) @@ -20,7 +20,7 @@ class ChangesetHelperTest < ActionView::TestCase assert_match %r{^Created .* by anonymous$}, changeset_details(changeset) changeset = create(:changeset, :created_at => Time.utc(2007, 1, 1, 0, 0, 0), :closed_at => Time.utc(2007, 1, 2, 0, 0, 0)) - user_link = %(#{changeset.user.display_name}) + user_link = %(#{changeset.user.display_name}) assert_match %r{^Closed .* by #{user_link}$}, changeset_details(changeset) end diff --git a/test/helpers/note_helper_test.rb b/test/helpers/note_helper_test.rb index 5857af6bc..408236879 100644 --- a/test/helpers/note_helper_test.rb +++ b/test/helpers/note_helper_test.rb @@ -9,7 +9,7 @@ class NoteHelperTest < ActionView::TestCase user = create(:user) assert_match %r{^Created by anonymous .* ago$}, note_event("open", date, nil) - assert_match %r{^Resolved by #{user.display_name} .* ago$}, note_event("closed", date, user) + assert_match %r{^Resolved by #{user.display_name} .* ago$}, note_event("closed", date, user) end def test_note_author @@ -18,7 +18,7 @@ class NoteHelperTest < ActionView::TestCase assert_equal "", note_author(nil) assert_equal "deleted", note_author(deleted_user) - assert_equal "#{user.display_name}", note_author(user) - assert_equal "#{user.display_name}", note_author(user, :only_path => false) + assert_equal "#{user.display_name}", note_author(user) + assert_equal "#{user.display_name}", note_author(user, :only_path => false) end end diff --git a/test/helpers/title_helper_test.rb b/test/helpers/title_helper_test.rb index 7d8355430..c30f793d3 100644 --- a/test/helpers/title_helper_test.rb +++ b/test/helpers/title_helper_test.rb @@ -1,4 +1,3 @@ -# coding: utf-8 require "test_helper" @@ -13,15 +12,15 @@ class TitleHelperTest < ActionView::TestCase assert_nil @title set_title("Test Title") - assert_equal "OpenStreetMap%20%7C%20Test%20Title", response.header["X-Page-Title"] + assert_equal "Test%20Title%20%7C%20OpenStreetMap", response.header["X-Page-Title"] assert_equal "Test Title", @title set_title("Test & Title") - assert_equal "OpenStreetMap%20%7C%20Test%20&%20Title", response.header["X-Page-Title"] + assert_equal "Test%20%26%20Title%20%7C%20OpenStreetMap", response.header["X-Page-Title"] assert_equal "Test & Title", @title set_title("Tést & Tïtlè") - assert_equal "OpenStreetMap%20%7C%20T%C3%A9st%20&%20T%C3%AFtl%C3%A8", response.header["X-Page-Title"] + assert_equal "T%C3%A9st%20%26%20T%C3%AFtl%C3%A8%20%7C%20OpenStreetMap", response.header["X-Page-Title"] assert_equal "Tést & Tïtlè", @title end end diff --git a/test/helpers/user_helper_test.rb b/test/helpers/user_helper_test.rb index ea3464052..eedc8775c 100644 --- a/test/helpers/user_helper_test.rb +++ b/test/helpers/user_helper_test.rb @@ -55,11 +55,11 @@ class UserHelperTest < ActionView::TestCase end def test_user_image_url - user = create(:user) + user = create(:user, :image_file_name => "test.jpg", :image_fingerprint => "d41d8cd98f00b204e9800998ecf8427e") gravatar_user = create(:user, :image_use_gravatar => true) url = user_image_url(user) - assert_match %r{^/users/images/original.png$}, url + assert_match %r{^/attachments/users/images/\d{3}/\d{3}/\d{3}/original/d41d8cd98f00b204e9800998ecf8427e.jpg$}, url url = user_image_url(gravatar_user) assert_match %r{^http://www.gravatar.com/avatar/}, url diff --git a/test/helpers/user_roles_helper_test.rb b/test/helpers/user_roles_helper_test.rb index 3ffc9fbff..058d6abd4 100644 --- a/test/helpers/user_roles_helper_test.rb +++ b/test/helpers/user_roles_helper_test.rb @@ -18,11 +18,11 @@ class UserRolesHelperTest < ActionView::TestCase user = create(:user) icon = role_icon(user, "moderator") - assert_dom_equal %(Grant moderator access), icon + assert_dom_equal %(Grant moderator access), icon moderator_user = create(:moderator_user) icon = role_icon(moderator_user, "moderator") - assert_dom_equal %(Revoke moderator access), icon + assert_dom_equal %(Revoke moderator access), icon end def test_role_icons_normal @@ -43,14 +43,14 @@ class UserRolesHelperTest < ActionView::TestCase user = create(:user) icons = role_icons(user) - assert_dom_equal %( Grant administrator access Grant moderator access), icons + assert_dom_equal %( Grant administrator access Grant moderator access), icons moderator_user = create(:moderator_user) icons = role_icons(moderator_user) - assert_dom_equal %( Grant administrator access Revoke moderator access), icons + assert_dom_equal %( Grant administrator access Revoke moderator access), icons super_user = create(:super_user) icons = role_icons(super_user) - assert_dom_equal %( Revoke administrator access Revoke moderator access), icons + assert_dom_equal %( Revoke administrator access Revoke moderator access), icons end end diff --git a/test/http/geocoder_us.yml b/test/http/geocoder_us.yml deleted file mode 100644 index de54aa306..000000000 --- a/test/http/geocoder_us.yml +++ /dev/null @@ -1,6 +0,0 @@ -/service/csv?zip=90210: - code: 200 - body: "34.088808, -118.40612, Beverly Hills, CA, 90210" -/service/csv?zip=00000: - code: 200 - body: "1: couldn't find this zip code: 00000! sorry" diff --git a/test/integration/client_applications_test.rb b/test/integration/client_applications_test.rb index 8c5e70784..59f234c41 100644 --- a/test/integration/client_applications_test.rb +++ b/test/integration/client_applications_test.rb @@ -12,35 +12,35 @@ class ClientApplicationsTest < ActionDispatch::IntegrationTest assert_redirected_to "controller" => "user", "action" => "login", "cookie_test" => "true" follow_redirect! assert_response :success - post "/login", :params => { "username" => user.email, "password" => "test", :referer => "/user/#{URI.encode(user.display_name)}" } + post "/login", :params => { "username" => user.email, "password" => "test", :referer => "/user/#{ERB::Util.u(user.display_name)}" } assert_response :redirect follow_redirect! assert_response :success assert_template "user/view" - get "/user/#{URI.encode(user.display_name)}/account" + get "/user/#{ERB::Util.u(user.display_name)}/account" assert_response :success assert_template "user/account" # check that the form to allow new client application creations exists assert_in_heading do - assert_select "ul.secondary-actions li a[href='/user/#{URI.encode(user.display_name)}/oauth_clients']" + assert_select "ul.secondary-actions li a[href='/user/#{ERB::Util.u(user.display_name)}/oauth_clients']" end # now we follow the link to the oauth client list - get "/user/#{URI.encode(user.display_name)}/oauth_clients" + get "/user/#{ERB::Util.u(user.display_name)}/oauth_clients" assert_response :success assert_in_body do - assert_select "a[href='/user/#{URI.encode(user.display_name)}/oauth_clients/new']" + assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/oauth_clients/new']" end # now we follow the link to the new oauth client page - get "/user/#{URI.encode(user.display_name)}/oauth_clients/new" + get "/user/#{ERB::Util.u(user.display_name)}/oauth_clients/new" assert_response :success assert_in_heading do assert_select "h1", "Register a new application" end assert_in_body do - assert_select "form[action='/user/#{URI.encode(user.display_name)}/oauth_clients']" do + assert_select "form[action='/user/#{ERB::Util.u(user.display_name)}/oauth_clients']" do [:name, :url, :callback_url, :support_url].each do |inp| assert_select "input[name=?]", "client_application[#{inp}]" end @@ -50,7 +50,7 @@ class ClientApplicationsTest < ActionDispatch::IntegrationTest end end - post "/user/#{URI.encode(user.display_name)}/oauth_clients", + post "/user/#{ERB::Util.u(user.display_name)}/oauth_clients", :params => { "client_application[name]" => "My New App", "client_application[url]" => "http://my.new.app.org/", "client_application[callback_url]" => "http://my.new.app.org/callback", @@ -62,7 +62,7 @@ class ClientApplicationsTest < ActionDispatch::IntegrationTest assert_equal "Registered the information successfully", flash[:notice] # now go back to the account page and check its listed under this user - get "/user/#{URI.encode(user.display_name)}/oauth_clients" + get "/user/#{ERB::Util.u(user.display_name)}/oauth_clients" assert_response :success assert_template "oauth_clients/index" assert_in_body { assert_select "div>a", "My New App" } diff --git a/test/integration/user_roles_test.rb b/test/integration/user_roles_test.rb index 3f6c24248..000ea0316 100644 --- a/test/integration/user_roles_test.rb +++ b/test/integration/user_roles_test.rb @@ -32,7 +32,7 @@ class UserRolesTest < ActionDispatch::IntegrationTest assert_response :success target_user = create(:user) - post "/user/#{URI.encode(target_user.display_name)}/role/#{role}/#{action}" + post "/user/#{ERB::Util.u(target_user.display_name)}/role/#{role}/#{action}" assert_redirected_to :controller => "user", :action => "view", :display_name => target_user.display_name reset! @@ -50,7 +50,7 @@ class UserRolesTest < ActionDispatch::IntegrationTest assert_response :success target_user = create(:user) - post "/user/#{URI.encode(target_user.display_name)}/role/#{role}/#{action}" + post "/user/#{ERB::Util.u(target_user.display_name)}/role/#{role}/#{action}" assert_redirected_to :controller => "user", :action => "view", :display_name => target_user.display_name reset! diff --git a/test/lib/bounding_box_test.rb b/test/lib/bounding_box_test.rb index 53095307d..3e0c5490b 100644 --- a/test/lib/bounding_box_test.rb +++ b/test/lib/bounding_box_test.rb @@ -306,7 +306,7 @@ class BoundingBoxTest < ActiveSupport::TestCase def check_expand(bbox, array_string, margin = 0, result = nil) array = array_string.split(",").collect(&:to_f) - result = array unless result + result ||= array bbox.expand!(BoundingBox.new(array[0], array[1], array[2], array[3]), margin) check_bbox(bbox, result) end diff --git a/test/lib/i18n_test.rb b/test/lib/i18n_test.rb index 3ead036eb..689f65097 100644 --- a/test/lib/i18n_test.rb +++ b/test/lib/i18n_test.rb @@ -13,7 +13,7 @@ class I18nTest < ActiveSupport::TestCase if default_value.is_a?(Hash) variables.push("count") - default_value.each do |_subkey, subvalue| + default_value.each_value do |subvalue| subvalue.scan(/%\{(\w+)\}/) do variables.push(Regexp.last_match(1)) end diff --git a/test/lib/utf8_test.rb b/test/lib/utf8_test.rb index 5762a83eb..4ad6f0c9e 100644 --- a/test/lib/utf8_test.rb +++ b/test/lib/utf8_test.rb @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- require "test_helper" class UTF8Test < ActiveSupport::TestCase diff --git a/test/models/changeset_comment_test.rb b/test/models/changeset_comment_test.rb index a7eafbef5..8e8d0cd70 100644 --- a/test/models/changeset_comment_test.rb +++ b/test/models/changeset_comment_test.rb @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- require "test_helper" class ChangesetCommentTest < ActiveSupport::TestCase diff --git a/test/models/language_test.rb b/test/models/language_test.rb index f6a6e3234..5ba558907 100644 --- a/test/models/language_test.rb +++ b/test/models/language_test.rb @@ -1,5 +1,3 @@ -# coding: utf-8 - require "test_helper" class LanguageTest < ActiveSupport::TestCase diff --git a/test/models/message_test.rb b/test/models/message_test.rb index 0c0f0e3eb..285222f1e 100644 --- a/test/models/message_test.rb +++ b/test/models/message_test.rb @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- require "test_helper" class MessageTest < ActiveSupport::TestCase diff --git a/test/models/note_comment_test.rb b/test/models/note_comment_test.rb index 6bda0ee7d..21d67dc67 100644 --- a/test/models/note_comment_test.rb +++ b/test/models/note_comment_test.rb @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- require "test_helper" class NoteCommentTest < ActiveSupport::TestCase diff --git a/test/models/note_test.rb b/test/models/note_test.rb index 77ed7f1b2..369ff1083 100644 --- a/test/models/note_test.rb +++ b/test/models/note_test.rb @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- require "test_helper" class NoteTest < ActiveSupport::TestCase diff --git a/test/models/user_test.rb b/test/models/user_test.rb index 57c136475..8af701ca0 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- require "test_helper" class UserTest < ActiveSupport::TestCase diff --git a/test/system/site_test.rb b/test/system/site_test.rb new file mode 100644 index 000000000..2ecc7f5a9 --- /dev/null +++ b/test/system/site_test.rb @@ -0,0 +1,9 @@ +require "application_system_test_case" + +class SiteTest < ApplicationSystemTestCase + test "visiting the index" do + visit "/" + + assert_selector "h1", :text => "OpenStreetMap" + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 0e06c3c9e..552bda7d5 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -9,7 +9,7 @@ require "minitest/rails/capybara" module ActiveSupport class TestCase - include FactoryGirl::Syntax::Methods + include FactoryBot::Syntax::Methods ## # takes a block which is executed in the context of a different diff --git a/vendor/assets/iD/iD.css.erb b/vendor/assets/iD/iD.css.erb index 5066b7ab2..7473e0eb7 100644 --- a/vendor/assets/iD/iD.css.erb +++ b/vendor/assets/iD/iD.css.erb @@ -1493,11 +1493,15 @@ path.stroke.tag-railway-subway { /* railway platforms - like sidewalks */ +.preset-icon .icon.highway-footway.tag-railway-platform { + color: #ae8681; + fill: #dcd9b9; +} path.shadow.tag-railway-platform { stroke-width: 16; } path.casing.tag-railway-platform { - stroke: #fff; + stroke: #dcd9b9; stroke-width: 5; stroke-linecap: round; stroke-dasharray: none; @@ -1535,6 +1539,7 @@ g.midpoint.tag-railway-platform .fill { } .preset-icon .icon.category-water, .preset-icon .icon.tag-route-ferry, +.preset-icon .icon.tag-type-waterway, .preset-icon .icon.tag-waterway { color: #77d3de; fill: #fff; @@ -1936,123 +1941,240 @@ path.fill.tag-amenity-shelter { .turn rect, .turn circle { - cursor: pointer; /* Opera */ - cursor: url(<%= asset_path("iD/img/cursor-pointer.png") %>) 6 1, pointer; /* FF */ + cursor: pointer; +} +/* photo viewer div */ +#photoviewer { + position: absolute; + bottom: 30px; + width: 330px; + height: 250px; + padding: 5px; + background-color: #fff; } -/* Mapillary Image Layer */ -.layer-mapillary-images { - pointer-events: none; +#photoviewer button.thumb-hide { + border-radius: 0; + padding: 5px; + position: absolute; + right: 0; + top: 0; + z-index: 500; +} + +.photo-wrapper, +.photo-wrapper img { + width: 100%; + height: 100%; + overflow: hidden; +} + +.photo-wrapper .photo-attribution { + width: 100%; + font-size: 10px; + text-align: right; + position: absolute; + bottom: 0; + right: 0; + padding: 4px 2px; + z-index: 10; +} + +.photo-attribution a, +.photo-attribution a:visited, +.photo-attribution span { + padding: 4px 2px; + color: #fff; } -.layer-mapillary-images .viewfield-group { +/* markers and sequences */ +.viewfield-group { pointer-events: visible; - cursor: pointer; /* Opera */ - cursor: url(<%= asset_path("iD/img/cursor-select-mapillary.png") %>) 6 1, pointer; /* FF */ + cursor: pointer; } -.layer-mapillary-images .viewfield-group * { - stroke-width: 1; - stroke: #444; - fill: #ffc600; - z-index: 50; +.viewfield-group.selected * { + fill: #ffee00 !important; +} +.viewfield-group.hovered * { + fill: #eebb00 !important; } -.layer-mapillary-images .viewfield-group:hover * { +.viewfield-group circle { + stroke: #555; stroke-width: 1; - stroke: #333; - fill: #ff9900; - z-index: 60; + stroke-opacity: 0.4; + fill-opacity: 0.4; } - -.layer-mapillary-images .viewfield-group.selected * { +.viewfield-group.highlighted circle { + stroke: #222; + stroke-opacity: 0.9; + fill-opacity: 0.9; +} +.viewfield-group.highlighted.hovered circle { + stroke: #222; stroke-width: 2; + stroke-opacity: 0.9; + fill-opacity: 0.9; +} +.viewfield-group.highlighted.selected circle { stroke: #222; - fill: #ff5800; - z-index: 60; + stroke-width: 2; + stroke-opacity: 1; + fill-opacity: 1; } -.layer-mapillary-images .viewfield-group:hover path.viewfield, -.layer-mapillary-images .viewfield-group.selected path.viewfield, -.layer-mapillary-images .viewfield-group path.viewfield { +.viewfield-group .viewfield { stroke-width: 0; - fill-opacity: 0.6; + stroke: #222; + fill-opacity: 0.4; +} +.viewfield-group.highlighted .viewfield { + stroke-width: 1; + fill-opacity: 0.8; +} +.viewfield-group.highlighted.hovered .viewfield { + stroke-width: 1; + fill-opacity: 0.8; +} +.viewfield-group.highlighted.selected .viewfield { + stroke-width: 1; + fill-opacity: 0.9; } -/* Mapillary Sign Layer */ +.viewfield-group.selected .viewfield-scale { + transform: scale(2,2); +} -.layer-mapillary-signs { +.sequence { + fill: none; + stroke-width: 2; + stroke-opacity: 0.4; +} +.sequence.highlighted, +.sequence.selected { + stroke-width: 4; + stroke-opacity: 1; +} + + +/* Mapillary Image Layer */ +.layer-mapillary-images { pointer-events: none; } +.layer-mapillary-images .viewfield-group * { + fill: #55ff22; +} +.layer-mapillary-images .sequence { + stroke: #55ff22; +} + +/* Mapillary Sign Layer */ +.layer-mapillary-signs { + pointer-events: none; +} .layer-mapillary-signs .icon-sign .icon-sign-body { min-width: 20px; height: 24px; width: 24px; outline: 2px solid transparent; pointer-events: visible; - cursor: pointer; /* Opera */ - cursor: url(<%= asset_path("iD/img/cursor-select-mapillary.png") %>) 6 1, pointer; /* FF */ - z-index: 70; + cursor: pointer; + z-index: 30; overflow: visible; } - .layer-mapillary-signs .icon-sign:hover .icon-sign-body { - outline: 2px solid rgba(255,198,0,0.8); - z-index: 80; + outline: 5px solid #eebb00; + background-color: #eebb00; + z-index: 70; } - .layer-mapillary-signs .icon-sign.selected .icon-sign-body { - outline: 2px solid rgba(255,0,0,0.8); - z-index: 80; + outline: 5px solid #ffee00; + background-color: #ffee00; + z-index: 40; +} + + +/* OpenStreetCam Image Layer */ +.layer-openstreetcam-images { + pointer-events: none; +} +.layer-openstreetcam-images .viewfield-group * { + fill: #77ddff; +} +.layer-openstreetcam-images .sequence { + stroke: #77ddff; } /* Mapillary viewer */ #mly .domRenderer .TagSymbol { font-size: 10px; - background-color: rgba(0, 0, 0, 0.4); + background-color: rgba(0,0,0,0.4); padding: 0 4px; border-radius: 4px; - transform: translate(-50%, -120%) !important; + top: -25px; } - #mly .domRenderer .Attribution { - width: 100%; - font-size: 10px; - text-align: right; + /* we will roll our own to avoid async update issues like #4526 */ + display: none; } -.mapillary-wrap { - position: absolute; - bottom: 30px; - width: 330px; - height: 250px; - padding: 5px; - background-color: #fff; +.mly-wrapper .photo-attribution a:active, +.mly-wrapper .photo-attribution a:hover { + color: #35af6d; } -.mapillary-wrap.hidden { - visibility: hidden; +.mly-wrapper .mapillary-js-dom { + z-index: 9; } -.mapillary-wrap button.thumb-hide { - border-radius: 0; - padding: 5px; - position: absolute; - right: 0; - top: 0; - z-index: 500; +/* OpenStreetCam viewer */ +.osc-wrapper { + position: relative; + background-color: #000; + background-image: url(<%= asset_path("iD/img/loader-black.gif") %>); + background-position: center; + background-repeat: no-repeat; } -.mly-wrapper { - visibility: hidden; +.osc-wrapper .photo-attribution a:active, +.osc-wrapper .photo-attribution a:hover { + color: #77ddff; +} + +.osc-controls-wrap { + text-align: center; + position: absolute; + top: 10px; width: 100%; - height: 100%; + z-index: 10; } -.mly-wrapper.active { - visibility: visible; +.osc-controls { + display: inline-block; + z-index: 10; +} + +.osc-controls button { + height: 18px; + width: 18px; + background: rgba(0,0,0,0.65); + color: #eee; + border-radius: 0; +} +.osc-controls button:first-of-type { + border-radius: 3px 0 0 3px; +} +.osc-controls button:last-of-type { + border-radius: 0 3px 3px 0; +} +.osc-controls button:hover, +.osc-controls button:active, +.osc-controls button:focus { + background: rgba(0,0,0,0.85); + color: #fff; } /* Fill Styles */ @@ -2173,6 +2295,22 @@ body { transition-duration: 200ms; } +/* Firefox has its own ideas about fixed positioning when a css filter is active - #4348 */ +/* https://stackoverflow.com/questions/37949942/firefox-position-bug-by-parent-with-filter */ +@-moz-document url-prefix() { + #content > #bar { + width: 100vw; + } + #content.inactive > #bar > .spacer.col4 { + width: 0px; + } + #content.active > #bar > .spacer.col4 { + width: 33.3333%; + transition-duration: 200ms; + transition-timing-function: step-end; + } +} + #defs { /* Can't be display: none or the clippaths are ignored. */ position: absolute; @@ -2233,8 +2371,7 @@ button, .checkselect label:hover, .opacity-options li, .radial-menu-item { - cursor: pointer; /* Opera */ - cursor: url(<%= asset_path("iD/img/cursor-pointer.png") %>) 6 1, pointer; /* FF */ + cursor: pointer; } h2 { @@ -2342,6 +2479,12 @@ input[type="radio"] { margin-right: 5px; margin-top: 3px; } +[dir='rtl'] input[type="checkbox"], +[dir='rtl'] input[type="radio"] { + float: right; + margin-left: 5px; + margin-right: 0; +} /* remove bottom border radius when combobox is open */ .combobox + * textarea:focus, @@ -2570,23 +2713,37 @@ button.minor:hover { .button-wrap:last-of-type { padding-right: 0; } +[dir='rtl'] .button-wrap:last-of-type { + padding-left: 0; + padding-right: 10px; +} .joined button { border-radius:0; border-right: 1px solid rgba(0,0,0,.5); } +[dir='rtl'] .joined button { + border-left: 1px solid rgba(0,0,0,.5); + border-right: none; +} .fillL .joined button { border-right: 1px solid white; } .joined button:first-child { - border-radius:4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +[dir='rtl'] .joined button:first-child { + border-radius: 0 4px 4px 0; } .joined button:last-child { border-right-width: 0; - border-radius:0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +[dir='rtl'] .joined button:last-child { + border-radius: 4px 0 0 4px; } button.action { @@ -2633,6 +2790,10 @@ button.save.has-count .count { margin: auto; margin-left: 9.3333%; } +[dir='rtl'] button.save.has-count .count { + margin-left: auto; + margin-right: 8%; +} button.save.has-count .count::before { content: ""; @@ -2649,6 +2810,12 @@ button.save.has-count .count::before { border-right-style: solid; border-right-color: inherit; } +[dir='rtl'] button.save.has-count .count::before { + border-left: 6px solid rgba(255,255,255,.5); + border-right: none; + left: auto; + right: -6px; +} /* Icons */ @@ -2668,6 +2835,10 @@ button.save.has-count .count::before { .icon.pre-text { margin-right: 5px; } +[dir='rtl'] .icon.pre-text { + margin-left: 5px; + margin-right: 0; +} .icon.light { color: #fff; @@ -2700,14 +2871,20 @@ button.save.has-count .count::before { #bar { position: fixed; padding: 10px 0; - left:0; - top:0; - right:0; - height:60px; + left: 0; + top: 0; + right: 0; + height: 60px; z-index: 9; min-width: 768px; } +[dir='rtl'] #bar .spacer, +[dir='rtl'] #bar .button-wrap, +[dir='rtl'] #bar .button-wrap button { + float: right; +} + /* Header for modals / panes ------------------------------------------------------- */ @@ -2726,6 +2903,10 @@ button.save.has-count .count::before { overflow: hidden; padding: 20px 20px 20px 40px; } +[dir='rtl'] .header h3 { + text-align: right; + padding: 20px 40px 20px 20px; +} .header button, .modal > button { @@ -2746,12 +2927,21 @@ button.save.has-count .count::before { right: 0; top: 0; } +[dir='rtl'] .entity-editor-pane .header button.preset-close, +[dir='rtl'] .preset-list-pane .header button.preset-choose { + left: 0; + right: auto; +} .entity-editor-pane .header button.preset-choose { position: absolute; left: 0; top: 0; } +[dir='rtl'] .entity-editor-pane .header button.preset-choose { + left: auto; + right: 0; +} .preset-choose { font-size: 16px; @@ -2766,6 +2956,10 @@ button.save.has-count .count::before { height: 60px; z-index: 50; } +[dir='rtl'] .modal > button { + left: 0; + right: unset; +} .footer { position: absolute; @@ -2797,6 +2991,9 @@ button.save.has-count .count::before { background: #f6f6f6; -ms-user-select: element; } +[dir='rtl'] #sidebar { + float: right; +} .sidebar-component { position: absolute; @@ -2853,6 +3050,10 @@ button.save.has-count .count::before { top: 80px; pointer-events: none; } +[dir='rtl'] #sidebar .search-header .icon { + left: auto; + right: 10px; +} #sidebar .search-header input { position: absolute; @@ -2906,6 +3107,9 @@ button.save.has-count .count::before { overflow: hidden; border-left: 1px solid rgba(0, 0, 0, .1); } +[dir='rtl'] .feature-list-item .label { + text-align: right; +} .feature-list-item .label .icon { opacity: .5; @@ -2933,6 +3137,11 @@ button.save.has-count .count::before { color: #666; padding-left: 10px; } +[dir='rtl'] .feature-list-item .entity-name { + padding-left: 0; + padding-right: 10px; +} + /* Presets ------------------------------------------------------- */ @@ -2982,6 +3191,7 @@ button.save.has-count .count::before { border: 1.5px solid #333; border-radius: 20px; background-color: #efefef; + backface-visibility: hidden; } [dir='rtl'] .preset-icon-fill-vertex, @@ -3056,6 +3266,19 @@ button.save.has-count .count::before { height: 24px; } +[dir='rtl'] .preset-list-button-wrap .preset-icon { + left: auto; + right: auto; +} + +[dir='rtl'] .preset-list-button-wrap .preset-icon-28 { + right: 16px; +} + +[dir='rtl'] .preset-list-button-wrap .preset-icon-24 { + right: 18px; +} + .preset-list-button .label { background-color: #f6f6f6; text-align: left; @@ -3071,7 +3294,15 @@ button.save.has-count .count::before { overflow: hidden; border-left: 1px solid rgba(0, 0, 0, .1); border-radius: 0 3px 3px 0; - } +} +[dir='rtl'] .preset-list-button .label { + text-align: right; + left: 0; + right: 60px; + border-left: none; + border-right: 1px solid rgba(0, 0, 0, .1); + border-radius: 3px 0 0 3px; +} .preset-list-button:hover .label { background-color: #ececec; @@ -3084,9 +3315,14 @@ button.save.has-count .count::before { position: absolute; top: 0; right: 0; - width: 10%; + width: 32px; background: #fafafa; } +[dir='rtl'] .preset-list-item button.tag-reference-button { + left: 0; + right: auto; + border-radius: 3px 0 0 3px; +} .preset-list-item button.tag-reference-button:hover { background: #f1f1f1; @@ -3140,21 +3376,25 @@ button.save.has-count .count::before { /* preset form basics */ -.inspector-preset { +.preset-editor { overflow: hidden; padding-bottom: 10px; } -.inspector-preset a.hide-toggle { +.preset-editor a.hide-toggle { margin: 0 20px 10px 20px; } -.inspector-preset .preset-form { +.preset-editor .form-fields-container { padding: 10px; margin: 0 10px 10px 10px; border-radius: 8px; } +.preset-editor .form-fields-container:empty { + display: none; +} + .entity-editor-pane .preset-list-item .preset-list-button-wrap { margin-bottom: 0; } @@ -3168,7 +3408,8 @@ button.save.has-count .count::before { transition: margin-bottom 200ms; } -.form-field:last-child { +.form-field.nowrap, +.wrap-form-field:last-child .form-field { margin-bottom: 0; } @@ -3209,7 +3450,7 @@ button.save.has-count .count::before { .form-label button { border-left: 1px solid #ccc; - width: 10%; + width: 32px; height: 100%; border-radius: 0; background: #f6f6f6; @@ -3218,6 +3459,7 @@ button.save.has-count .count::before { border-left: none; border-right: 1px solid #CCC; border-radius: 4px 0 0 0; + width: 31px; } .form-label button:hover { background: #f1f1f1; @@ -3258,6 +3500,7 @@ button.save.has-count .count::before { .inspector-hover .form-field-multicombo, .inspector-hover .structure-extras-wrap, .inspector-hover input, +.inspector-hover textarea, .inspector-hover label { background: #ececec; } @@ -3381,6 +3624,9 @@ button.save.has-count .count::before { padding: 0 20px 20px 20px; font-weight: bold; } +.changeset-editor .more-fields { + padding: 15px 20px 0 20px; +} .more-fields label { display: flex; @@ -3404,17 +3650,21 @@ button.save.has-count .count::before { padding: 5px 10px; } +[dir='rtl'] .preset-input-wrap .col6 { + float: right; +} /* preset form access */ /* preset form cycleway */ +/* preset form structure extras */ -.form-field-structure .structure-extras-wrap li, +.structure-extras-wrap li, .form-field-cycleway .preset-input-wrap li, .form-field-access .preset-input-wrap li { border-bottom: 1px solid #ccc; } -.form-field-structure .structure-extras-wrap li:last-child, +.structure-extras-wrap li:last-child, .form-field-cycleway .preset-input-wrap li:last-child, .form-field-access .preset-input-wrap li:last-child { border-bottom: 0; @@ -3447,6 +3697,34 @@ button.save.has-count .count::before { border: 1px solid #ccc; border-radius: 4px; } +.structure-extras-wrap li:first-child span { + border-top-left-radius: 4px; +} +.structure-extras-wrap li:first-child input { + border-top-right-radius: 4px; +} +.structure-extras-wrap li:last-child span { + border-bottom-left-radius: 4px; +} +.structure-extras-wrap li:last-child input { + border-bottom-right-radius: 4px; +} +[dir='rtl'] .structure-extras-wrap li:first-child span { + border-top-left-radius: 0; + border-top-right-radius: 4px; +} +[dir='rtl'] .structure-extras-wrap li:first-child input { + border-top-right-radius: 0; + border-top-left-radius: 4px; +} +[dir='rtl'] .structure-extras-wrap li:last-child span { + border-bottom-left-radius: 0; + border-bottom-right-radius: 4px; +} +[dir='rtl'] .structure-extras-wrap li:last-child input { + border-bottom-right-radius: 0; + border-bottom-left-radius: 4px; +} /* preset form multicombo */ @@ -3471,14 +3749,15 @@ button.save.has-count .count::before { } .form-field-multicombo li { + display: inline-flex; + flex-flow: row nowrap; + align-items: center; background-color: #eff2f7; border: 1px solid #ccd5e3; border-radius: 4px; line-height: 25px; - display: inline-block; padding: 2px 5px; margin: 3px; - height: 30px; } .form-field-multicombo a { @@ -3496,6 +3775,7 @@ button.save.has-count .count::before { border: 1px solid #ddd; width: 100px; margin: 3px; + height: 31px; } .form-field-multicombo .combobox-caret { @@ -3515,28 +3795,43 @@ input[type=number] { } .spin-control { - width: 20%; - height: 29px; + width: 64px; + height: 30px; display: inline-block; - margin-left: -20%; + margin-left: -64px; margin-bottom: -11px; position: relative; } +[dir='rtl'] .spin-control{ + margin-left: 0; + margin-right: -64px; +} .spin-control button { right: 1px; position: relative; float: left; height: 100%; - width: 50%; + width: 32px; border-left: 1px solid #CCC; border-radius: 0; background: rgba(0, 0, 0, 0); } +[dir='rtl'] .spin-control button{ + border-left: 0; + border-right: 1px solid #CCC; +} .spin-control button.decrement { border-bottom-right-radius: 3px; } +[dir='rtl'] .spin-control button.decrement { + border-bottom-right-radius: 0; +} +[dir='rtl'] .spin-control button.increment { + border-bottom-left-radius: 3px; + right: 0; +} .spin-control button.decrement::after, .spin-control button.increment::after { @@ -3559,6 +3854,7 @@ input[type=number] { border-right: 5px solid transparent; } + /* preset form checkbox */ .checkselect label:last-of-type { @@ -3642,11 +3938,11 @@ input[type=number] { } .form-field .wiki-title ~ .combobox-caret { - right: 10%; + right: 32px; } [dir='rtl'] .form-field .wiki-title ~ .combobox-caret { right: auto; - left: 10%; + left: 32px; } /* Localized field */ @@ -3661,8 +3957,8 @@ input[type=number] { .form-field .button-input-action { position: relative; right: 1px; - width: 10%; - margin-left: -10%; + width: 32px; + margin-left: -32px; border: 1px solid #CCC; border-top-width: 0; border-right-width: 0; @@ -3672,7 +3968,7 @@ input[type=number] { } [dir='rtl'] .form-field .button-input-action { margin-left: 0; - margin-right: -10%; + margin-right: -32px; border-right-width: 1px; border-radius: 0 0 0 4px; } @@ -3818,6 +4114,10 @@ div.combobox { margin-left: -30px; vertical-align: top; } +[dir='rtl'] .combobox-caret { + margin-left: 0; + margin-right: -30px; +} .combobox-caret::after { content:""; @@ -3990,18 +4290,17 @@ button.minor.tag-reference-loading { clear: both; } -.tag-reference-body p, -.tag-reference-body img { - margin-top: 20px; -} - -.tag-reference-body p:last-child { - padding-bottom: 10px; +.tag-reference-body .tag-reference-description { + margin: 10px 5px 0 5px; } .tag-reference-body a { display: block; - padding-bottom: 10px; +} + +.tag-reference-body .tag-reference-description:last-child, +.tag-reference-body a:last-child { + margin-bottom: 15px; } .preset-list .tag-reference-body { @@ -4009,41 +4308,35 @@ button.minor.tag-reference-loading { width: 100%; } -.preset-list .tag-reference-body a { - padding-bottom: 20px; -} - -.preset-list .tag-reference-body p, -.preset-list .tag-reference-body img { - margin-top: 10px; -} - .raw-tag-editor .tag-reference-body { - border-bottom: 1px solid #ccc; float: left; width: 100%; } -.raw-tag-editor .tag-reference-body p:last-child { - padding-bottom: 20px; +.raw-tag-editor .tag-row.readonly .tag-reference-body { + background: #f6f6f6; + color: #333; +} + +.raw-tag-editor .tag-row:not(:last-child) .tag-reference-body { + border-bottom: 1px solid #ccc; } -.raw-tag-editor .tag-reference-body a { - padding-bottom: 20px; +.raw-tag-editor .tag-row.readonly .tag-reference-body.expanded { + border-top: 1px solid #ccc; } -img.wiki-image { +img.tag-reference-wiki-image { float: right; width: 33.3333%; width: -webkit-calc(33.3333% - 10px); width: calc(33.3333% - 10px); - margin-left: 20px; - margin-right: 10px; border-radius: 4px; max-height: 200px; - margin-bottom: 20px; + margin: 10px 5px 15px 20px; } + /* Raw relation membership editor */ .raw-member-editor .member-list li:first-child, @@ -4121,6 +4414,10 @@ div.full-screen > button:hover { position: fixed; z-index: 100; } +[dir='rtl'] .map-controls { + left: 0; + right: auto; +} .map-control > button { width: 40px; @@ -4142,6 +4439,9 @@ div.full-screen > button:hover { .zoombuttons button.zoom-in { border-radius: 4px 0 0 0; } +[dir='rtl'] .zoombuttons button.zoom-in { + border-radius: 0 4px 0 0; +} /* Background / Map Data Settings */ @@ -4152,6 +4452,9 @@ div.full-screen > button:hover { .background-control button { border-radius: 4px 0 0 0; } +[dir='rtl'] .background-control button { + border-radius: 0 4px 0 0; +} .map-data-control, .background-control { @@ -4215,6 +4518,10 @@ div.full-screen > button:hover { float: right; } +[dir='rtl'] .list-item-gpx-browse svg { + transform: rotateY(180deg); +} + /* make sure tooltip fits in map-control panel */ /* if too wide, placement will be wrong the first time it displays */ .layer-list li.best .tooltip-inner { @@ -4252,9 +4559,13 @@ div.full-screen > button:hover { .hide-toggle { display: block; - padding-left:12px; + padding-left: 12px; position: relative; } +[dir='rtl'] .hide-toggle { + padding-left: 0; + padding-right: 12px; +} .hide-toggle:before { content: ''; @@ -4268,6 +4579,12 @@ div.full-screen > button:hover { border-bottom: 4px solid transparent; border-left: 8px solid #7092ff; } +[dir='rtl'] .hide-toggle:before { + left: auto; + right: 0; + border-left: none; + border-right: 8px solid #7092ff; +} .hide-toggle.expanded:before { border-top: 8px solid #7092ff; @@ -4275,6 +4592,11 @@ div.full-screen > button:hover { border-right: 4px solid transparent; border-left: 4px solid transparent; } +[dir='rtl'] .hide-toggle.expanded:before { + border-left: 4px solid transparent; + border-right: 4px solid transparent; +} + /* Adjust Alignment controls */ @@ -4405,13 +4727,17 @@ div.full-screen > button:hover { .opacity-options { background: url(<%= asset_path("iD/img/background-pattern-opacity.png") %>) 0 0 repeat; - height:20px; - width:82px; + height: 20px; + width: 82px; position: absolute; right: 50px; top: 20px; border: 1px solid #ccc; } +[dir='rtl'] .opacity-options { + left: 50px; + right: auto; +} .opacity-options li { height: 100%; @@ -4421,8 +4747,8 @@ div.full-screen > button:hover { .opacity-options li .select-box{ position: absolute; - width:20px; - height:18px; + width: 20px; + height: 18px; z-index: 9999; } @@ -4457,6 +4783,12 @@ div.full-screen > button:hover { border-left: 1px solid #CCC; border-radius: 0; } +[dir='rtl'] .map-data-control .layer-list button, +[dir='rtl'] .background-control .layer-list button { + float: left; + border-left: none; + border-right: 1px solid #CCC; +} .map-data-control .layer-list button .icon, .background-control .layer-list button .icon { @@ -4467,6 +4799,10 @@ div.full-screen > button:hover { .background-control .layer-list button:first-of-type { border-radius: 0 3px 3px 0; } +[dir='rtl'] .map-data-control .layer-list button:first-of-type, +[dir='rtl'] .background-control .layer-list button:first-of-type { + border-radius: 3px 0 0 3px; +} .map-data-control .map-overlay, .background-control .map-overlay, @@ -4474,7 +4810,6 @@ div.full-screen > button:hover { z-index: -1; } - /* Geolocator */ .geolocate-control { @@ -4484,6 +4819,9 @@ div.full-screen > button:hover { .geolocate-control button { border-radius: 0 0 0 4px; } +[dir='rtl'] .geolocate-control button { + border-radius: 0 0 4px 0; +} .map-overlay.content { position: fixed; @@ -4493,12 +4831,20 @@ div.full-screen > button:hover { right: 0; overflow: auto; } +[dir='rtl'] .map-overlay.content { + padding: 20px 20px 20px 50px; + left: 0; + right: auto !important; +} /* Help */ .help-control button { border-radius: 0 0 0 4px; } +[dir='rtl'] .help-control button { + border-radius: 0 0 4px 0; +} .help-wrap p { font-size: 15px; @@ -4820,6 +5166,9 @@ img.tile-removing { background: none; color: #ddd; } +[dir='rtl'] .panel-title button.close { + float: left; +} .panel-title button.close:hover { color: #fff; @@ -4841,8 +5190,13 @@ img.tile-removing { border-radius: 2px; padding: 0 4px; margin-top: 10px; + margin-right: 10px; color: white; } +[dir='rtl'] .panel-content .button { + margin-right: auto; + margin-left: 10px; +} .panel-content-history .links a { margin-left: 10px; @@ -5409,32 +5763,55 @@ img.tile-removing { float: left; height: 12px; min-width: 12px; - font-size:12px; + font-size: 12px; line-height: 12px; - border-radius:24px; - padding:5px; - background:#7092ff; - color:#fff; + border-radius: 24px; + padding: 5px; + background: #7092ff; + color: #fff; +} + +.mode-save .field-warning { + background: #ffb; + border: 1px solid #ccc; + border-radius: 4px; + padding: 10px; +} + +.mode-save .field-warning:empty { + display: none; } +.mode-save .field-warning, +.mode-save .changeset-info, +.mode-save .request-review, .mode-save .commit-info { margin-bottom: 10px; } +.mode-save .request-review label { + cursor: pointer; +} + .mode-save .changeset-list { - border:1px solid #ccc; + border: 1px solid #ccc; border-radius: 4px; - background:#fff; + background: #fff; + margin-bottom: 10px; +} + +.mode-save .warning-section { + background: #ffb; } .mode-save .warning-section .changeset-list button { - border-left: 1px solid #CCC; + border-left: 1px solid #ccc; } .mode-save .changeset-list li { position: relative; - border-top:1px solid #ccc; - padding:5px 10px; + border-top: 1px solid #ccc; + padding: 5px 10px; cursor: pointer; } @@ -5447,8 +5824,8 @@ img.tile-removing { } .changeset-list li span.count { - font-size:10px; - color:#555; + font-size: 10px; + color: #555; } .mode-save .commit-section .changeset-list button { @@ -5516,31 +5893,33 @@ img.tile-removing { .notice { position: absolute; - top: 0; - bottom: 0; + top: 45px; left: 0; right: 0; text-align: center; - background: #fff; } .notice .zoom-to { margin: auto; - width: 80%; - height: 100px; - border-radius: 5px; - line-height: 40px; - color: #000; - opacity: 0.9; + width: 300px; + height: 70px; + font-size: 150%; + border-radius: 8px; } .notice .zoom-to:hover { - background: #d8e1ff; + background: rgba(0,0,0,0.6); } .notice .zoom-to .icon { - margin-top:10px; - margin-right:10px; + width: 30px; + height: 30px; + vertical-align: middle; + margin-right: 10px; +} +[dir='rtl'] .notice .zoom-to .icon { + margin-left: 10px; + margin-right: 0; } /* Tooltips @@ -5752,6 +6131,10 @@ img.tile-removing { .add-point .tooltip { left: 33.3333% !important; } +[dir='rtl'] .add-point .tooltip { + left: inherit !important; +} + .add-point .tooltip .tooltip-arrow { left: 60px; } @@ -6083,222 +6466,3 @@ li.hide + li.version .badge .tooltip .tooltip-arrow { width: 100px; color: #7092FF; } - - -/* Right-to-left localization settings */ - -[dir='rtl'] #sidebar { - float: right; -} - -[dir='rtl'] #sidebar .search-header .icon { - left: auto; - right: 10px; -} - -/* header */ -[dir='rtl'] .header h3 { - text-align: right; - padding: 20px 40px 20px 20px; -} - -[dir='rtl'] .entity-editor-pane .header button.preset-choose { - left: auto; - right: 0; -} - -[dir='rtl'] .entity-editor-pane .header button.preset-close, [dir='rtl'] .preset-list-pane .header button.preset-choose { - left: 0; - right: auto; -} - -[dir='rtl'] .map-data-control .layer-list button, [dir='rtl'] .background-control .layer-list button { - float: left; - border-left: none; - border-right: 1px solid #CCC; -} - -[dir='rtl'] .map-data-control .layer-list button:first-of-type, [dir='rtl'] .background-control .layer-list button:first-of-type { - border-radius: 3px 0 0 3px; -} - -/* search */ -[dir='rtl'] .feature-list-item .label { - text-align: right; -} - -[dir='rtl'] .feature-list-item .entity-name { - padding-left: 0; - padding-right: 10px; -} - -/* preset form */ - -[dir='rtl'] .combobox-caret { - margin-left: 0; - margin-right: -30px; -} - -[dir='rtl'] .icon.pre-text { - margin-left: 5px; - margin-right: 0; -} - -[dir='rtl'] .notice .zoom-to .icon { - margin-left: 10px; - margin-right: 0; -} - -[dir='rtl'] .preset-list-button .label { - text-align: right; - left: 0; - right: 60px; - border-left: none; - border-right: 1px solid rgba(0, 0, 0, .1); - border-radius: 3px 0 0 3px; -} - -[dir='rtl'] .preset-list-item button.tag-reference-button { - left: 0; - right: auto; - border-radius: 3px 0 0 3px; -} - -[dir='rtl'] .preset-list-button-wrap .preset-icon { - left: auto; - right: auto; -} - -[dir='rtl'] .preset-list-button-wrap .preset-icon-28 { - right: 16px; -} - -[dir='rtl'] .preset-list-button-wrap .preset-icon-24 { - right: 18px; -} - -[dir='rtl'] input[type="checkbox"], [dir='rtl'] input[type="radio"] { - float: right; - margin-left: 5px; - margin-right: 0; -} - -[dir='rtl'] .preset-input-wrap .col6 { - float: right; -} - -/* map control buttons */ -[dir='rtl'] .map-controls { - left: 0; - right: auto; -} - -[dir='rtl'] .background-control button, -[dir='rtl'] .zoombuttons button.zoom-in { - border-radius: 0 4px 0 0; -} - -[dir='rtl'] .help-control button, -[dir='rtl'] .geolocate-control button { - border-radius: 0 0 4px 0; -} - -[dir='rtl'] .list-item-gpx-browse svg { - transform: rotateY(180deg); -} - -/* map control button overlays */ -[dir='rtl'] .map-overlay { - padding: 20px 20px 20px 50px; - left: 0; - right: auto !important; -} - -[dir='rtl'] .opacity-options { - left: 50px; - right: auto; -} - -[dir='rtl'] .hide-toggle { - padding-left: 0; - padding-right: 12px; -} - -[dir='rtl'] .hide-toggle:before { - left: auto; - right: 0; - border-left: none; - border-right: 8px solid #7092ff; -} - -[dir='rtl'] .hide-toggle.expanded:before { - border-left: 4px solid transparent; - border-right: 4px solid transparent; -} - -/* navbar */ -[dir='rtl'] #bar .spacer, -[dir='rtl'] #bar .button-wrap, -[dir='rtl'] #bar .button-wrap button { - float: right; -} - -[dir='rtl'] .add-point .tooltip { - left: inherit !important; -} - -[dir='rtl'] .button-wrap:last-of-type { - padding-left: 0; - padding-right: 10px; -} - -[dir='rtl'] button.save.has-count .count { - margin-left: auto; - margin-right: 8%; -} - -[dir='rtl'] button.save.has-count .count::before { - border-left: 6px solid rgba(255,255,255,.5); - border-right: none; - left: auto; - right: -6px; -} - -[dir='rtl'] .joined button { - border-left: 1px solid rgba(0,0,0,.5); - border-right: none; -} - -[dir='rtl'] .joined button:first-child { - border-radius: 0 4px 4px 0; -} - -[dir='rtl'] .joined button:last-child { - border-radius: 4px 0 0 4px; -} - - -/* increment / decrement control - code by Naoufel Razouane */ - -[dir='rtl'] .spin-control{ - margin-left: 0; - margin-right: -20%; -} -[dir='rtl'] .spin-control button{ - border-left: 0; - border-right: 1px solid #CCC; -} -[dir='rtl'] .spin-control button.decrement{ - border-bottom-right-radius: 0; -} -[dir='rtl'] .spin-control button.increment{ - border-bottom-left-radius: 3px; -} -/* modal */ -[dir='rtl'] .modal > button { - position: absolute; - left: 0; - right: unset; - top: 0; -} - diff --git a/vendor/assets/iD/iD.js b/vendor/assets/iD/iD.js index 8aa803c09..a9e9863d4 100644 --- a/vendor/assets/iD/iD.js +++ b/vendor/assets/iD/iD.js @@ -1,36186 +1,23996 @@ (function () { -function actionAddEntity(way) { - return function(graph) { - return graph.replace(way); - }; -} +var version = "4.11.0"; -var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; +var d3_ascending = function(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; +}; +var d3_bisector = function(compare) { + if (compare.length === 1) compare = ascendingComparator(compare); + return { + left: function(a, x, lo, hi) { + if (lo == null) lo = 0; + if (hi == null) hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (compare(a[mid], x) < 0) lo = mid + 1; + else hi = mid; + } + return lo; + }, + right: function(a, x, lo, hi) { + if (lo == null) lo = 0; + if (hi == null) hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (compare(a[mid], x) > 0) hi = mid; + else lo = mid + 1; + } + return lo; + } + }; +}; +function ascendingComparator(f) { + return function(d, x) { + return d3_ascending(f(d), x); + }; +} +var ascendingBisect = d3_bisector(d3_ascending); +var bisectRight = ascendingBisect.right; +var bisectLeft = ascendingBisect.left; +var pairs = function(array, f) { + if (f == null) f = pair; + var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n); + while (i < n) pairs[i] = f(p, p = array[++i]); + return pairs; +}; -function createCommonjsModule(fn, module) { - return module = { exports: {} }, fn(module, module.exports), module.exports; +function pair(a, b) { + return [a, b]; } -var lodash = createCommonjsModule(function (module, exports) { -/** - * @license - * Lodash - * Copyright JS Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */ -(function() { +var cross = function(values0, values1, reduce) { + var n0 = values0.length, + n1 = values1.length, + values = new Array(n0 * n1), + i0, + i1, + i, + value0; - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined; - - /** Used as the semantic version number. */ - var VERSION = '4.17.4'; - - /** Used as the size to enable large array optimizations. */ - var LARGE_ARRAY_SIZE = 200; - - /** Error message constants. */ - var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.', - FUNC_ERROR_TEXT = 'Expected a function'; - - /** Used to stand-in for `undefined` hash values. */ - var HASH_UNDEFINED = '__lodash_hash_undefined__'; - - /** Used as the maximum memoize cache size. */ - var MAX_MEMOIZE_SIZE = 500; - - /** Used as the internal argument placeholder. */ - var PLACEHOLDER = '__lodash_placeholder__'; - - /** Used to compose bitmasks for cloning. */ - var CLONE_DEEP_FLAG = 1, - CLONE_FLAT_FLAG = 2, - CLONE_SYMBOLS_FLAG = 4; - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - - /** Used to compose bitmasks for function metadata. */ - var WRAP_BIND_FLAG = 1, - WRAP_BIND_KEY_FLAG = 2, - WRAP_CURRY_BOUND_FLAG = 4, - WRAP_CURRY_FLAG = 8, - WRAP_CURRY_RIGHT_FLAG = 16, - WRAP_PARTIAL_FLAG = 32, - WRAP_PARTIAL_RIGHT_FLAG = 64, - WRAP_ARY_FLAG = 128, - WRAP_REARG_FLAG = 256, - WRAP_FLIP_FLAG = 512; - - /** Used as default options for `_.truncate`. */ - var DEFAULT_TRUNC_LENGTH = 30, - DEFAULT_TRUNC_OMISSION = '...'; - - /** Used to detect hot functions by number of calls within a span of milliseconds. */ - var HOT_COUNT = 800, - HOT_SPAN = 16; - - /** Used to indicate the type of lazy iteratees. */ - var LAZY_FILTER_FLAG = 1, - LAZY_MAP_FLAG = 2, - LAZY_WHILE_FLAG = 3; - - /** Used as references for various `Number` constants. */ - var INFINITY = 1 / 0, - MAX_SAFE_INTEGER = 9007199254740991, - MAX_INTEGER = 1.7976931348623157e+308, - NAN = 0 / 0; - - /** Used as references for the maximum length and index of an array. */ - var MAX_ARRAY_LENGTH = 4294967295, - MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, - HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; - - /** Used to associate wrap methods with their bit flags. */ - var wrapFlags = [ - ['ary', WRAP_ARY_FLAG], - ['bind', WRAP_BIND_FLAG], - ['bindKey', WRAP_BIND_KEY_FLAG], - ['curry', WRAP_CURRY_FLAG], - ['curryRight', WRAP_CURRY_RIGHT_FLAG], - ['flip', WRAP_FLIP_FLAG], - ['partial', WRAP_PARTIAL_FLAG], - ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], - ['rearg', WRAP_REARG_FLAG] - ]; + if (reduce == null) reduce = pair; - /** `Object#toString` result references. */ - var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - asyncTag = '[object AsyncFunction]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - domExcTag = '[object DOMException]', - errorTag = '[object Error]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - mapTag = '[object Map]', - numberTag = '[object Number]', - nullTag = '[object Null]', - objectTag = '[object Object]', - promiseTag = '[object Promise]', - proxyTag = '[object Proxy]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]', - undefinedTag = '[object Undefined]', - weakMapTag = '[object WeakMap]', - weakSetTag = '[object WeakSet]'; - - var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - - /** Used to match empty string literals in compiled template source. */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** Used to match HTML entities and HTML characters. */ - var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, - reUnescapedHtml = /[&<>"']/g, - reHasEscapedHtml = RegExp(reEscapedHtml.source), - reHasUnescapedHtml = RegExp(reUnescapedHtml.source); - - /** Used to match template delimiters. */ - var reEscape = /<%-([\s\S]+?)%>/g, - reEvaluate = /<%([\s\S]+?)%>/g, - reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to match property names within property paths. */ - var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/, - reLeadingDot = /^\./, - rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + for (i0 = i = 0; i0 < n0; ++i0) { + for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) { + values[i] = reduce(value0, values1[i1]); + } + } - /** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ - var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, - reHasRegExpChar = RegExp(reRegExpChar.source); + return values; +}; - /** Used to match leading and trailing whitespace. */ - var reTrim = /^\s+|\s+$/g, - reTrimStart = /^\s+/, - reTrimEnd = /\s+$/; +var d3_descending = function(a, b) { + return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; +}; - /** Used to match wrap detail comments. */ - var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, - reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, - reSplitDetails = /,? & /; +var number = function(x) { + return x === null ? NaN : +x; +}; - /** Used to match words composed of alphanumeric characters. */ - var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; +var variance = function(values, valueof) { + var n = values.length, + m = 0, + i = -1, + mean = 0, + value, + delta, + sum = 0; - /** Used to match backslashes in property paths. */ - var reEscapeChar = /\\(\\)?/g; + if (valueof == null) { + while (++i < n) { + if (!isNaN(value = number(values[i]))) { + delta = value - mean; + mean += delta / ++m; + sum += delta * (value - mean); + } + } + } - /** - * Used to match - * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match `RegExp` flags from their coerced string values. */ - var reFlags = /\w*$/; - - /** Used to detect bad signed hexadecimal string values. */ - var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; - - /** Used to detect binary string values. */ - var reIsBinary = /^0b[01]+$/i; - - /** Used to detect host constructors (Safari). */ - var reIsHostCtor = /^\[object .+?Constructor\]$/; - - /** Used to detect octal string values. */ - var reIsOctal = /^0o[0-7]+$/i; - - /** Used to detect unsigned integer values. */ - var reIsUint = /^(?:0|[1-9]\d*)$/; - - /** Used to match Latin Unicode letters (excluding mathematical operators). */ - var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; - - /** Used to ensure capturing order of template delimiters. */ - var reNoMatch = /($^)/; - - /** Used to match unescaped characters in compiled string literals. */ - var reUnescapedString = /['\n\r\u2028\u2029\\]/g; - - /** Used to compose unicode character classes. */ - var rsAstralRange = '\\ud800-\\udfff', - rsComboMarksRange = '\\u0300-\\u036f', - reComboHalfMarksRange = '\\ufe20-\\ufe2f', - rsComboSymbolsRange = '\\u20d0-\\u20ff', - rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, - rsDingbatRange = '\\u2700-\\u27bf', - rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', - rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', - rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', - rsPunctuationRange = '\\u2000-\\u206f', - rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', - rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', - rsVarRange = '\\ufe0e\\ufe0f', - rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; - - /** Used to compose unicode capture groups. */ - var rsApos = "['\u2019]", - rsAstral = '[' + rsAstralRange + ']', - rsBreak = '[' + rsBreakRange + ']', - rsCombo = '[' + rsComboRange + ']', - rsDigits = '\\d+', - rsDingbat = '[' + rsDingbatRange + ']', - rsLower = '[' + rsLowerRange + ']', - rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', - rsFitz = '\\ud83c[\\udffb-\\udfff]', - rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', - rsNonAstral = '[^' + rsAstralRange + ']', - rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', - rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', - rsUpper = '[' + rsUpperRange + ']', - rsZWJ = '\\u200d'; - - /** Used to compose unicode regexes. */ - var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')', - rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')', - rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', - rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', - reOptMod = rsModifier + '?', - rsOptVar = '[' + rsVarRange + ']?', - rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', - rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)', - rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)', - rsSeq = rsOptVar + reOptMod + rsOptJoin, - rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, - rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; - - /** Used to match apostrophes. */ - var reApos = RegExp(rsApos, 'g'); + else { + while (++i < n) { + if (!isNaN(value = number(valueof(values[i], i, values)))) { + delta = value - mean; + mean += delta / ++m; + sum += delta * (value - mean); + } + } + } - /** - * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and - * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). - */ - var reComboMark = RegExp(rsCombo, 'g'); - - /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ - var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); - - /** Used to match complex or compound words. */ - var reUnicodeWord = RegExp([ - rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', - rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')', - rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower, - rsUpper + '+' + rsOptContrUpper, - rsOrdUpper, - rsOrdLower, - rsDigits, - rsEmoji - ].join('|'), 'g'); - - /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ - var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); - - /** Used to detect strings that need a more robust regexp to match words. */ - var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; - - /** Used to assign default `context` object properties. */ - var contextProps = [ - 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', - 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', - 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', - 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', - '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' - ]; + if (m > 1) return sum / (m - 1); +}; - /** Used to make template sourceURLs easier to identify. */ - var templateCounter = -1; - - /** Used to identify `toStringTag` values of typed arrays. */ - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = - typedArrayTags[errorTag] = typedArrayTags[funcTag] = - typedArrayTags[mapTag] = typedArrayTags[numberTag] = - typedArrayTags[objectTag] = typedArrayTags[regexpTag] = - typedArrayTags[setTag] = typedArrayTags[stringTag] = - typedArrayTags[weakMapTag] = false; - - /** Used to identify `toStringTag` values supported by `_.clone`. */ - var cloneableTags = {}; - cloneableTags[argsTag] = cloneableTags[arrayTag] = - cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = - cloneableTags[boolTag] = cloneableTags[dateTag] = - cloneableTags[float32Tag] = cloneableTags[float64Tag] = - cloneableTags[int8Tag] = cloneableTags[int16Tag] = - cloneableTags[int32Tag] = cloneableTags[mapTag] = - cloneableTags[numberTag] = cloneableTags[objectTag] = - cloneableTags[regexpTag] = cloneableTags[setTag] = - cloneableTags[stringTag] = cloneableTags[symbolTag] = - cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = - cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; - cloneableTags[errorTag] = cloneableTags[funcTag] = - cloneableTags[weakMapTag] = false; - - /** Used to map Latin Unicode letters to basic Latin letters. */ - var deburredLetters = { - // Latin-1 Supplement block. - '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', - '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', - '\xc7': 'C', '\xe7': 'c', - '\xd0': 'D', '\xf0': 'd', - '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', - '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', - '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', - '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', - '\xd1': 'N', '\xf1': 'n', - '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', - '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', - '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', - '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', - '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', - '\xc6': 'Ae', '\xe6': 'ae', - '\xde': 'Th', '\xfe': 'th', - '\xdf': 'ss', - // Latin Extended-A block. - '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', - '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', - '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', - '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', - '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', - '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', - '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', - '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', - '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', - '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', - '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', - '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', - '\u0134': 'J', '\u0135': 'j', - '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', - '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', - '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', - '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', - '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', - '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', - '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', - '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', - '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', - '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', - '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', - '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', - '\u0163': 't', '\u0165': 't', '\u0167': 't', - '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', - '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', - '\u0174': 'W', '\u0175': 'w', - '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', - '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', - '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', - '\u0132': 'IJ', '\u0133': 'ij', - '\u0152': 'Oe', '\u0153': 'oe', - '\u0149': "'n", '\u017f': 's' - }; +var deviation = function(array, f) { + var v = variance(array, f); + return v ? Math.sqrt(v) : v; +}; - /** Used to map characters to HTML entities. */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; +var extent = function(values, valueof) { + var n = values.length, + i = -1, + value, + min, + max; - /** Used to map HTML entities to characters. */ - var htmlUnescapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - ''': "'" - }; + if (valueof == null) { + while (++i < n) { // Find the first comparable value. + if ((value = values[i]) != null && value >= value) { + min = max = value; + while (++i < n) { // Compare the remaining values. + if ((value = values[i]) != null) { + if (min > value) min = value; + if (max < value) max = value; + } + } + } + } + } - /** Used to escape characters for inclusion in compiled string literals. */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; + else { + while (++i < n) { // Find the first comparable value. + if ((value = valueof(values[i], i, values)) != null && value >= value) { + min = max = value; + while (++i < n) { // Compare the remaining values. + if ((value = valueof(values[i], i, values)) != null) { + if (min > value) min = value; + if (max < value) max = value; + } + } + } + } + } - /** Built-in method references without a dependency on `root`. */ - var freeParseFloat = parseFloat, - freeParseInt = parseInt; + return [min, max]; +}; - /** Detect free variable `global` from Node.js. */ - var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; +var array = Array.prototype; - /** Detect free variable `self`. */ - var freeSelf = typeof self == 'object' && self && self.Object === Object && self; +var slice = array.slice; +var map = array.map; - /** Used as a reference to the global object. */ - var root = freeGlobal || freeSelf || Function('return this')(); +var constant = function(x) { + return function() { + return x; + }; +}; - /** Detect free variable `exports`. */ - var freeExports = 'object' == 'object' && exports && !exports.nodeType && exports; +var identity = function(x) { + return x; +}; - /** Detect free variable `module`. */ - var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; +var d3_range = function(start, stop, step) { + start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports; + var i = -1, + n = Math.max(0, Math.ceil((stop - start) / step)) | 0, + range = new Array(n); - /** Detect free variable `process` from Node.js. */ - var freeProcess = moduleExports && freeGlobal.process; + while (++i < n) { + range[i] = start + i * step; + } - /** Used to access faster Node.js helpers. */ - var nodeUtil = (function() { - try { - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) {} - }()); + return range; +}; - /* Node.js helper references. */ - var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, - nodeIsDate = nodeUtil && nodeUtil.isDate, - nodeIsMap = nodeUtil && nodeUtil.isMap, - nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, - nodeIsSet = nodeUtil && nodeUtil.isSet, - nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; +var e10 = Math.sqrt(50); +var e5 = Math.sqrt(10); +var e2 = Math.sqrt(2); - /*--------------------------------------------------------------------------*/ +var ticks = function(start, stop, count) { + var reverse, + i = -1, + n, + ticks, + step; - /** - * Adds the key-value `pair` to `map`. - * - * @private - * @param {Object} map The map to modify. - * @param {Array} pair The key-value pair to add. - * @returns {Object} Returns `map`. - */ - function addMapEntry(map, pair) { - // Don't return `map.set` because it's not chainable in IE 11. - map.set(pair[0], pair[1]); - return map; - } + stop = +stop, start = +start, count = +count; + if (start === stop && count > 0) return [start]; + if (reverse = stop < start) n = start, start = stop, stop = n; + if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return []; - /** - * Adds `value` to `set`. - * - * @private - * @param {Object} set The set to modify. - * @param {*} value The value to add. - * @returns {Object} Returns `set`. - */ - function addSetEntry(set, value) { - // Don't return `set.add` because it's not chainable in IE 11. - set.add(value); - return set; + if (step > 0) { + start = Math.ceil(start / step); + stop = Math.floor(stop / step); + ticks = new Array(n = Math.ceil(stop - start + 1)); + while (++i < n) ticks[i] = (start + i) * step; + } else { + start = Math.floor(start * step); + stop = Math.ceil(stop * step); + ticks = new Array(n = Math.ceil(start - stop + 1)); + while (++i < n) ticks[i] = (start - i) / step; } - /** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ - function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); - } + if (reverse) ticks.reverse(); - /** - * A specialized version of `baseAggregator` for arrays. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ - function arrayAggregator(array, setter, iteratee, accumulator) { - var index = -1, - length = array == null ? 0 : array.length; + return ticks; +}; - while (++index < length) { - var value = array[index]; - setter(accumulator, value, iteratee(value), array); - } - return accumulator; - } +function tickIncrement(start, stop, count) { + var step = (stop - start) / Math.max(0, count), + power = Math.floor(Math.log(step) / Math.LN10), + error = step / Math.pow(10, power); + return power >= 0 + ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) + : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); +} - /** - * A specialized version of `_.forEach` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEach(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length; +function tickStep(start, stop, count) { + var step0 = Math.abs(stop - start) / Math.max(0, count), + step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), + error = step0 / step1; + if (error >= e10) step1 *= 10; + else if (error >= e5) step1 *= 5; + else if (error >= e2) step1 *= 2; + return stop < start ? -step1 : step1; +} - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; - } +var sturges = function(values) { + return Math.ceil(Math.log(values.length) / Math.LN2) + 1; +}; - /** - * A specialized version of `_.forEachRight` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEachRight(array, iteratee) { - var length = array == null ? 0 : array.length; +var histogram = function() { + var value = identity, + domain = extent, + threshold = sturges; - while (length--) { - if (iteratee(array[length], length, array) === false) { - break; - } + function histogram(data) { + var i, + n = data.length, + x, + values = new Array(n); + + for (i = 0; i < n; ++i) { + values[i] = value(data[i], i, data); } - return array; - } - /** - * A specialized version of `_.every` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - */ - function arrayEvery(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; + var xz = domain(values), + x0 = xz[0], + x1 = xz[1], + tz = threshold(values, x0, x1); - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } + // Convert number of thresholds into uniform thresholds. + if (!Array.isArray(tz)) { + tz = tickStep(x0, x1, tz); + tz = d3_range(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive } - return true; - } - /** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; + // Remove any thresholds outside the domain. + var m = tz.length; + while (tz[0] <= x0) tz.shift(), --m; + while (tz[m - 1] > x1) tz.pop(), --m; - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[resIndex++] = value; + var bins = new Array(m + 1), + bin; + + // Initialize bins. + for (i = 0; i <= m; ++i) { + bin = bins[i] = []; + bin.x0 = i > 0 ? tz[i - 1] : x0; + bin.x1 = i < m ? tz[i] : x1; + } + + // Assign data to bins by value, ignoring any outside the domain. + for (i = 0; i < n; ++i) { + x = values[i]; + if (x0 <= x && x <= x1) { + bins[bisectRight(tz, x, 0, m)].push(data[i]); } } - return result; - } - /** - * A specialized version of `_.includes` for arrays without support for - * specifying an index to search from. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ - function arrayIncludes(array, value) { - var length = array == null ? 0 : array.length; - return !!length && baseIndexOf(array, value, 0) > -1; + return bins; } - /** - * This function is like `arrayIncludes` except that it accepts a comparator. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @param {Function} comparator The comparator invoked per element. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ - function arrayIncludesWith(array, value, comparator) { - var index = -1, - length = array == null ? 0 : array.length; + histogram.value = function(_) { + return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value; + }; - while (++index < length) { - if (comparator(value, array[index])) { - return true; - } - } - return false; - } + histogram.domain = function(_) { + return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain; + }; - /** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + histogram.thresholds = function(_) { + return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold; + }; - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } + return histogram; +}; - /** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ - function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; +var threshold = function(values, p, valueof) { + if (valueof == null) valueof = number; + if (!(n = values.length)) return; + if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values); + if (p >= 1) return +valueof(values[n - 1], n - 1, values); + var n, + i = (n - 1) * p, + i0 = Math.floor(i), + value0 = +valueof(values[i0], i0, values), + value1 = +valueof(values[i0 + 1], i0 + 1, values); + return value0 + (value1 - value0) * (i - i0); +}; - while (++index < length) { - array[offset + index] = values[index]; - } - return array; - } +var freedmanDiaconis = function(values, min, max) { + values = map.call(values, number).sort(d3_ascending); + return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3))); +}; - /** - * A specialized version of `_.reduce` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initAccum] Specify using the first element of `array` as - * the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduce(array, iteratee, accumulator, initAccum) { - var index = -1, - length = array == null ? 0 : array.length; +var scott = function(values, min, max) { + return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3))); +}; - if (initAccum && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; - } +var max = function(values, valueof) { + var n = values.length, + i = -1, + value, + max; - /** - * A specialized version of `_.reduceRight` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initAccum] Specify using the last element of `array` as - * the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduceRight(array, iteratee, accumulator, initAccum) { - var length = array == null ? 0 : array.length; - if (initAccum && length) { - accumulator = array[--length]; - } - while (length--) { - accumulator = iteratee(accumulator, array[length], length, array); + if (valueof == null) { + while (++i < n) { // Find the first comparable value. + if ((value = values[i]) != null && value >= value) { + max = value; + while (++i < n) { // Compare the remaining values. + if ((value = values[i]) != null && value > max) { + max = value; + } + } + } } - return accumulator; } - /** - * A specialized version of `_.some` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function arraySome(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; + else { + while (++i < n) { // Find the first comparable value. + if ((value = valueof(values[i], i, values)) != null && value >= value) { + max = value; + while (++i < n) { // Compare the remaining values. + if ((value = valueof(values[i], i, values)) != null && value > max) { + max = value; + } + } } } - return false; } - /** - * Gets the size of an ASCII `string`. - * - * @private - * @param {string} string The string inspect. - * @returns {number} Returns the string size. - */ - var asciiSize = baseProperty('length'); + return max; +}; - /** - * Converts an ASCII `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function asciiToArray(string) { - return string.split(''); - } +var mean = function(values, valueof) { + var n = values.length, + m = n, + i = -1, + value, + sum = 0; - /** - * Splits an ASCII `string` into an array of its words. - * - * @private - * @param {string} The string to inspect. - * @returns {Array} Returns the words of `string`. - */ - function asciiWords(string) { - return string.match(reAsciiWord) || []; + if (valueof == null) { + while (++i < n) { + if (!isNaN(value = number(values[i]))) sum += value; + else --m; + } } - /** - * The base implementation of methods like `_.findKey` and `_.findLastKey`, - * without support for iteratee shorthands, which iterates over `collection` - * using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the found element or its key, else `undefined`. - */ - function baseFindKey(collection, predicate, eachFunc) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = key; - return false; - } - }); - return result; + else { + while (++i < n) { + if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value; + else --m; + } } - /** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); + if (m) return sum / m; +}; - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; +var d3_median = function(values, valueof) { + var n = values.length, + i = -1, + value, + numbers = []; + + if (valueof == null) { + while (++i < n) { + if (!isNaN(value = number(values[i]))) { + numbers.push(value); } } - return -1; - } - - /** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - return value === value - ? strictIndexOf(array, value, fromIndex) - : baseFindIndex(array, baseIsNaN, fromIndex); } - /** - * This function is like `baseIndexOf` except that it accepts a comparator. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @param {Function} comparator The comparator invoked per element. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOfWith(array, value, fromIndex, comparator) { - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (comparator(array[index], value)) { - return index; + else { + while (++i < n) { + if (!isNaN(value = number(valueof(values[i], i, values)))) { + numbers.push(value); } } - return -1; } - /** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ - function baseIsNaN(value) { - return value !== value; - } + return threshold(numbers.sort(d3_ascending), 0.5); +}; - /** - * The base implementation of `_.mean` and `_.meanBy` without support for - * iteratee shorthands. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the mean. - */ - function baseMean(array, iteratee) { - var length = array == null ? 0 : array.length; - return length ? (baseSum(array, iteratee) / length) : NAN; - } +var merge = function(arrays) { + var n = arrays.length, + m, + i = -1, + j = 0, + merged, + array; - /** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; - } + while (++i < n) j += arrays[i].length; + merged = new Array(j); - /** - * The base implementation of `_.propertyOf` without support for deep paths. - * - * @private - * @param {Object} object The object to query. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyOf(object) { - return function(key) { - return object == null ? undefined : object[key]; - }; + while (--n >= 0) { + array = arrays[n]; + m = array.length; + while (--m >= 0) { + merged[--j] = array[m]; + } } - /** - * The base implementation of `_.reduce` and `_.reduceRight`, without support - * for iteratee shorthands, which iterates over `collection` using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} accumulator The initial value. - * @param {boolean} initAccum Specify using the first or last element of - * `collection` as the initial value. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the accumulated value. - */ - function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { - eachFunc(collection, function(value, index, collection) { - accumulator = initAccum - ? (initAccum = false, value) - : iteratee(accumulator, value, index, collection); - }); - return accumulator; - } + return merged; +}; - /** - * The base implementation of `_.sortBy` which uses `comparer` to define the - * sort order of `array` and replaces criteria objects with their corresponding - * values. - * - * @private - * @param {Array} array The array to sort. - * @param {Function} comparer The function to define sort order. - * @returns {Array} Returns `array`. - */ - function baseSortBy(array, comparer) { - var length = array.length; +var min = function(values, valueof) { + var n = values.length, + i = -1, + value, + min; - array.sort(comparer); - while (length--) { - array[length] = array[length].value; + if (valueof == null) { + while (++i < n) { // Find the first comparable value. + if ((value = values[i]) != null && value >= value) { + min = value; + while (++i < n) { // Compare the remaining values. + if ((value = values[i]) != null && min > value) { + min = value; + } + } + } } - return array; } - /** - * The base implementation of `_.sum` and `_.sumBy` without support for - * iteratee shorthands. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. - */ - function baseSum(array, iteratee) { - var result, - index = -1, - length = array.length; - - while (++index < length) { - var current = iteratee(array[index]); - if (current !== undefined) { - result = result === undefined ? current : (result + current); - } + else { + while (++i < n) { // Find the first comparable value. + if ((value = valueof(values[i], i, values)) != null && value >= value) { + min = value; + while (++i < n) { // Compare the remaining values. + if ((value = valueof(values[i], i, values)) != null && min > value) { + min = value; + } + } + } } - return result; } - /** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ - function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); + return min; +}; - while (++index < n) { - result[index] = iteratee(index); +var permute = function(array, indexes) { + var i = indexes.length, permutes = new Array(i); + while (i--) permutes[i] = array[indexes[i]]; + return permutes; +}; + +var scan = function(values, compare) { + if (!(n = values.length)) return; + var n, + i = 0, + j = 0, + xi, + xj = values[j]; + + if (compare == null) compare = d3_ascending; + + while (++i < n) { + if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) { + xj = xi, j = i; } - return result; } - /** - * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array - * of key-value pairs for `object` corresponding to the property names of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the key-value pairs. - */ - function baseToPairs(object, props) { - return arrayMap(props, function(key) { - return [key, object[key]]; - }); - } + if (compare(xj, xj) === 0) return j; +}; - /** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ - function baseUnary(func) { - return function(value) { - return func(value); - }; - } +var shuffle = function(array, i0, i1) { + var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0), + t, + i; - /** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the array of property values. - */ - function baseValues(object, props) { - return arrayMap(props, function(key) { - return object[key]; - }); + while (m) { + i = Math.random() * m-- | 0; + t = array[m + i0]; + array[m + i0] = array[i + i0]; + array[i + i0] = t; } - /** - * Checks if a `cache` value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function cacheHas(cache, key) { - return cache.has(key); - } + return array; +}; - /** - * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the first unmatched string symbol. - */ - function charsStartIndex(strSymbols, chrSymbols) { - var index = -1, - length = strSymbols.length; +var sum = function(values, valueof) { + var n = values.length, + i = -1, + value, + sum = 0; - while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; + if (valueof == null) { + while (++i < n) { + if (value = +values[i]) sum += value; // Note: zero and null are equivalent. + } } - /** - * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the last unmatched string symbol. - */ - function charsEndIndex(strSymbols, chrSymbols) { - var index = strSymbols.length; - - while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; + else { + while (++i < n) { + if (value = +valueof(values[i], i, values)) sum += value; + } } - /** - * Gets the number of `placeholder` occurrences in `array`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} placeholder The placeholder to search for. - * @returns {number} Returns the placeholder count. - */ - function countHolders(array, placeholder) { - var length = array.length, - result = 0; + return sum; +}; - while (length--) { - if (array[length] === placeholder) { - ++result; - } +var transpose = function(matrix) { + if (!(n = matrix.length)) return []; + for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) { + for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) { + row[j] = matrix[j][i]; } - return result; } + return transpose; +}; - /** - * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A - * letters to basic Latin letters. - * - * @private - * @param {string} letter The matched letter to deburr. - * @returns {string} Returns the deburred letter. - */ - var deburrLetter = basePropertyOf(deburredLetters); +function length(d) { + return d.length; +} - /** - * Used by `_.escape` to convert characters to HTML entities. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - var escapeHtmlChar = basePropertyOf(htmlEscapes); +var zip = function() { + return transpose(arguments); +}; - /** - * Used by `_.template` to escape characters for inclusion in compiled string literals. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(chr) { - return '\\' + stringEscapes[chr]; - } +var slice$1 = Array.prototype.slice; - /** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ - function getValue(object, key) { - return object == null ? undefined : object[key]; - } +var identity$1 = function(x) { + return x; +}; - /** - * Checks if `string` contains Unicode symbols. - * - * @private - * @param {string} string The string to inspect. - * @returns {boolean} Returns `true` if a symbol is found, else `false`. - */ - function hasUnicode(string) { - return reHasUnicode.test(string); - } +var top = 1; +var right = 2; +var bottom = 3; +var left = 4; +var epsilon = 1e-6; - /** - * Checks if `string` contains a word composed of Unicode symbols. - * - * @private - * @param {string} string The string to inspect. - * @returns {boolean} Returns `true` if a word is found, else `false`. - */ - function hasUnicodeWord(string) { - return reHasUnicodeWord.test(string); - } +function translateX(x) { + return "translate(" + (x + 0.5) + ",0)"; +} - /** - * Converts `iterator` to an array. - * - * @private - * @param {Object} iterator The iterator to convert. - * @returns {Array} Returns the converted array. - */ - function iteratorToArray(iterator) { - var data, - result = []; +function translateY(y) { + return "translate(0," + (y + 0.5) + ")"; +} - while (!(data = iterator.next()).done) { - result.push(data.value); - } - return result; - } +function number$1(scale) { + return function(d) { + return +scale(d); + }; +} - /** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ - function mapToArray(map) { - var index = -1, - result = Array(map.size); +function center(scale) { + var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset. + if (scale.round()) offset = Math.round(offset); + return function(d) { + return +scale(d) + offset; + }; +} - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; - } +function entering() { + return !this.__axis; +} - /** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ - function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; - } +function axis(orient, scale) { + var tickArguments = [], + tickValues = null, + tickFormat = null, + tickSizeInner = 6, + tickSizeOuter = 6, + tickPadding = 3, + k = orient === top || orient === left ? -1 : 1, + x = orient === left || orient === right ? "x" : "y", + transform = orient === top || orient === bottom ? translateX : translateY; - /** - * Replaces all `placeholder` elements in `array` with an internal placeholder - * and returns an array of their indexes. - * - * @private - * @param {Array} array The array to modify. - * @param {*} placeholder The placeholder to replace. - * @returns {Array} Returns the new array of placeholder indexes. - */ - function replaceHolders(array, placeholder) { - var index = -1, - length = array.length, - resIndex = 0, - result = []; + function axis(context) { + var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues, + format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat, + spacing = Math.max(tickSizeInner, 0) + tickPadding, + range = scale.range(), + range0 = +range[0] + 0.5, + range1 = +range[range.length - 1] + 0.5, + position = (scale.bandwidth ? center : number$1)(scale.copy()), + selection = context.selection ? context.selection() : context, + path = selection.selectAll(".domain").data([null]), + tick = selection.selectAll(".tick").data(values, scale).order(), + tickExit = tick.exit(), + tickEnter = tick.enter().append("g").attr("class", "tick"), + line = tick.select("line"), + text = tick.select("text"); - while (++index < length) { - var value = array[index]; - if (value === placeholder || value === PLACEHOLDER) { - array[index] = PLACEHOLDER; - result[resIndex++] = index; - } - } - return result; - } + path = path.merge(path.enter().insert("path", ".tick") + .attr("class", "domain") + .attr("stroke", "#000")); - /** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ - function setToArray(set) { - var index = -1, - result = Array(set.size); + tick = tick.merge(tickEnter); - set.forEach(function(value) { - result[++index] = value; - }); - return result; - } + line = line.merge(tickEnter.append("line") + .attr("stroke", "#000") + .attr(x + "2", k * tickSizeInner)); - /** - * Converts `set` to its value-value pairs. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the value-value pairs. - */ - function setToPairs(set) { - var index = -1, - result = Array(set.size); + text = text.merge(tickEnter.append("text") + .attr("fill", "#000") + .attr(x, k * spacing) + .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em")); - set.forEach(function(value) { - result[++index] = [value, value]; - }); - return result; - } + if (context !== selection) { + path = path.transition(context); + tick = tick.transition(context); + line = line.transition(context); + text = text.transition(context); - /** - * A specialized version of `_.indexOf` which performs strict equality - * comparisons of values, i.e. `===`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function strictIndexOf(array, value, fromIndex) { - var index = fromIndex - 1, - length = array.length; + tickExit = tickExit.transition(context) + .attr("opacity", epsilon) + .attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); }); - while (++index < length) { - if (array[index] === value) { - return index; - } + tickEnter + .attr("opacity", epsilon) + .attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); }); } - return -1; - } - /** - * A specialized version of `_.lastIndexOf` which performs strict equality - * comparisons of values, i.e. `===`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function strictLastIndexOf(array, value, fromIndex) { - var index = fromIndex + 1; - while (index--) { - if (array[index] === value) { - return index; - } - } - return index; - } + tickExit.remove(); - /** - * Gets the number of symbols in `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the string size. - */ - function stringSize(string) { - return hasUnicode(string) - ? unicodeSize(string) - : asciiSize(string); - } + path + .attr("d", orient === left || orient == right + ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter + : "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter); - /** - * Converts `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function stringToArray(string) { - return hasUnicode(string) - ? unicodeToArray(string) - : asciiToArray(string); - } + tick + .attr("opacity", 1) + .attr("transform", function(d) { return transform(position(d)); }); - /** - * Used by `_.unescape` to convert HTML entities to characters. - * - * @private - * @param {string} chr The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - var unescapeHtmlChar = basePropertyOf(htmlUnescapes); + line + .attr(x + "2", k * tickSizeInner); - /** - * Gets the size of a Unicode `string`. - * - * @private - * @param {string} string The string inspect. - * @returns {number} Returns the string size. - */ - function unicodeSize(string) { - var result = reUnicode.lastIndex = 0; - while (reUnicode.test(string)) { - ++result; - } - return result; - } + text + .attr(x, k * spacing) + .text(format); - /** - * Converts a Unicode `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function unicodeToArray(string) { - return string.match(reUnicode) || []; - } + selection.filter(entering) + .attr("fill", "none") + .attr("font-size", 10) + .attr("font-family", "sans-serif") + .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle"); - /** - * Splits a Unicode `string` into an array of its words. - * - * @private - * @param {string} The string to inspect. - * @returns {Array} Returns the words of `string`. - */ - function unicodeWords(string) { - return string.match(reUnicodeWord) || []; + selection + .each(function() { this.__axis = position; }); } - /*--------------------------------------------------------------------------*/ - - /** - * Create a new pristine `lodash` function using the `context` object. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Util - * @param {Object} [context=root] The context object. - * @returns {Function} Returns a new `lodash` function. - * @example - * - * _.mixin({ 'foo': _.constant('foo') }); - * - * var lodash = _.runInContext(); - * lodash.mixin({ 'bar': lodash.constant('bar') }); - * - * _.isFunction(_.foo); - * // => true - * _.isFunction(_.bar); - * // => false - * - * lodash.isFunction(lodash.foo); - * // => false - * lodash.isFunction(lodash.bar); - * // => true - * - * // Create a suped-up `defer` in Node.js. - * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; - */ - var runInContext = (function runInContext(context) { - context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps)); - - /** Built-in constructor references. */ - var Array = context.Array, - Date = context.Date, - Error = context.Error, - Function = context.Function, - Math = context.Math, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; - - /** Used for built-in method references. */ - var arrayProto = Array.prototype, - funcProto = Function.prototype, - objectProto = Object.prototype; - - /** Used to detect overreaching core-js shims. */ - var coreJsData = context['__core-js_shared__']; - - /** Used to resolve the decompiled source of functions. */ - var funcToString = funcProto.toString; - - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to generate unique IDs. */ - var idCounter = 0; - - /** Used to detect methods masquerading as native. */ - var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; - }()); + axis.scale = function(_) { + return arguments.length ? (scale = _, axis) : scale; + }; - /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ - var nativeObjectToString = objectProto.toString; + axis.ticks = function() { + return tickArguments = slice$1.call(arguments), axis; + }; - /** Used to infer the `Object` constructor. */ - var objectCtorString = funcToString.call(Object); + axis.tickArguments = function(_) { + return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice(); + }; - /** Used to restore the original `_` reference in `_.noConflict`. */ - var oldDash = root._; + axis.tickValues = function(_) { + return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice(); + }; - /** Used to detect if a method is native. */ - var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); + axis.tickFormat = function(_) { + return arguments.length ? (tickFormat = _, axis) : tickFormat; + }; - /** Built-in value references. */ - var Buffer = moduleExports ? context.Buffer : undefined, - Symbol = context.Symbol, - Uint8Array = context.Uint8Array, - allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, - getPrototype = overArg(Object.getPrototypeOf, Object), - objectCreate = Object.create, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - splice = arrayProto.splice, - spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined, - symIterator = Symbol ? Symbol.iterator : undefined, - symToStringTag = Symbol ? Symbol.toStringTag : undefined; - - var defineProperty = (function() { - try { - var func = getNative(Object, 'defineProperty'); - func({}, '', {}); - return func; - } catch (e) {} - }()); - - /** Mocked built-ins. */ - var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, - ctxNow = Date && Date.now !== root.Date.now && Date.now, - ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeCeil = Math.ceil, - nativeFloor = Math.floor, - nativeGetSymbols = Object.getOwnPropertySymbols, - nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, - nativeIsFinite = context.isFinite, - nativeJoin = arrayProto.join, - nativeKeys = overArg(Object.keys, Object), - nativeMax = Math.max, - nativeMin = Math.min, - nativeNow = Date.now, - nativeParseInt = context.parseInt, - nativeRandom = Math.random, - nativeReverse = arrayProto.reverse; - - /* Built-in method references that are verified to be native. */ - var DataView = getNative(context, 'DataView'), - Map = getNative(context, 'Map'), - Promise = getNative(context, 'Promise'), - Set = getNative(context, 'Set'), - WeakMap = getNative(context, 'WeakMap'), - nativeCreate = getNative(Object, 'create'); - - /** Used to store function metadata. */ - var metaMap = WeakMap && new WeakMap; - - /** Used to lookup unminified function names. */ - var realNames = {}; - - /** Used to detect maps, sets, and weakmaps. */ - var dataViewCtorString = toSource(DataView), - mapCtorString = toSource(Map), - promiseCtorString = toSource(Promise), - setCtorString = toSource(Set), - weakMapCtorString = toSource(WeakMap); - - /** Used to convert symbols to primitives and strings. */ - var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; - - /*------------------------------------------------------------------------*/ + axis.tickSize = function(_) { + return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner; + }; - /** - * Creates a `lodash` object which wraps `value` to enable implicit method - * chain sequences. Methods that operate on and return arrays, collections, - * and functions can be chained together. Methods that retrieve a single value - * or may return a primitive value will automatically end the chain sequence - * and return the unwrapped value. Otherwise, the value must be unwrapped - * with `_#value`. - * - * Explicit chain sequences, which must be unwrapped with `_#value`, may be - * enabled using `_.chain`. - * - * The execution of chained methods is lazy, that is, it's deferred until - * `_#value` is implicitly or explicitly called. - * - * Lazy evaluation allows several methods to support shortcut fusion. - * Shortcut fusion is an optimization to merge iteratee calls; this avoids - * the creation of intermediate arrays and can greatly reduce the number of - * iteratee executions. Sections of a chain sequence qualify for shortcut - * fusion if the section is applied to an array and iteratees accept only - * one argument. The heuristic for whether a section qualifies for shortcut - * fusion is subject to change. - * - * Chaining is supported in custom builds as long as the `_#value` method is - * directly or indirectly included in the build. - * - * In addition to lodash methods, wrappers have `Array` and `String` methods. - * - * The wrapper `Array` methods are: - * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` - * - * The wrapper `String` methods are: - * `replace` and `split` - * - * The wrapper methods that support shortcut fusion are: - * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, - * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, - * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` - * - * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, - * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, - * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, - * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, - * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, - * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, - * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, - * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, - * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, - * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, - * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, - * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, - * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, - * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, - * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, - * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, - * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, - * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, - * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, - * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, - * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, - * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, - * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, - * `zipObject`, `zipObjectDeep`, and `zipWith` - * - * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, - * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, - * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, - * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, - * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, - * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, - * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, - * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, - * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, - * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, - * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, - * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, - * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, - * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, - * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, - * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, - * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, - * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, - * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, - * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, - * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, - * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, - * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, - * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, - * `upperFirst`, `value`, and `words` - * - * @name _ - * @constructor - * @category Seq - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var wrapped = _([1, 2, 3]); - * - * // Returns an unwrapped value. - * wrapped.reduce(_.add); - * // => 6 - * - * // Returns a wrapped value. - * var squares = wrapped.map(square); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { - if (value instanceof LodashWrapper) { - return value; - } - if (hasOwnProperty.call(value, '__wrapped__')) { - return wrapperClone(value); - } - } - return new LodashWrapper(value); - } + axis.tickSizeInner = function(_) { + return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner; + }; - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} proto The object to inherit from. - * @returns {Object} Returns the new object. - */ - var baseCreate = (function() { - function object() {} - return function(proto) { - if (!isObject(proto)) { - return {}; - } - if (objectCreate) { - return objectCreate(proto); - } - object.prototype = proto; - var result = new object; - object.prototype = undefined; - return result; - }; - }()); + axis.tickSizeOuter = function(_) { + return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter; + }; - /** - * The function whose prototype chain sequence wrappers inherit from. - * - * @private - */ - function baseLodash() { - // No operation performed. - } + axis.tickPadding = function(_) { + return arguments.length ? (tickPadding = +_, axis) : tickPadding; + }; - /** - * The base constructor for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap. - * @param {boolean} [chainAll] Enable explicit method chain sequences. - */ - function LodashWrapper(value, chainAll) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__chain__ = !!chainAll; - this.__index__ = 0; - this.__values__ = undefined; - } + return axis; +} - /** - * By default, the template delimiters used by lodash are like those in - * embedded Ruby (ERB) as well as ES2015 template strings. Change the - * following template settings to use alternative delimiters. - * - * @static - * @memberOf _ - * @type {Object} - */ - lodash.templateSettings = { +function axisTop(scale) { + return axis(top, scale); +} - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'escape': reEscape, +function axisRight(scale) { + return axis(right, scale); +} - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'evaluate': reEvaluate, +function axisBottom(scale) { + return axis(bottom, scale); +} - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'interpolate': reInterpolate, +function axisLeft(scale) { + return axis(left, scale); +} - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type {string} - */ - 'variable': '', +var noop = {value: function() {}}; - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type {Object} - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type {Function} - */ - '_': lodash - } - }; +function dispatch() { + for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { + if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t); + _[t] = []; + } + return new Dispatch(_); +} - // Ensure wrappers are instances of `baseLodash`. - lodash.prototype = baseLodash.prototype; - lodash.prototype.constructor = lodash; +function Dispatch(_) { + this._ = _; +} - LodashWrapper.prototype = baseCreate(baseLodash.prototype); - LodashWrapper.prototype.constructor = LodashWrapper; +function parseTypenames(typenames, types) { + return typenames.trim().split(/^|\s+/).map(function(t) { + var name = "", i = t.indexOf("."); + if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); + if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); + return {type: t, name: name}; + }); +} - /*------------------------------------------------------------------------*/ +Dispatch.prototype = dispatch.prototype = { + constructor: Dispatch, + on: function(typename, callback) { + var _ = this._, + T = parseTypenames(typename + "", _), + t, + i = -1, + n = T.length; - /** - * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. - * - * @private - * @constructor - * @param {*} value The value to wrap. - */ - function LazyWrapper(value) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__dir__ = 1; - this.__filtered__ = false; - this.__iteratees__ = []; - this.__takeCount__ = MAX_ARRAY_LENGTH; - this.__views__ = []; + // If no callback was specified, return the callback of the given type and name. + if (arguments.length < 2) { + while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t; + return; } - /** - * Creates a clone of the lazy wrapper object. - * - * @private - * @name clone - * @memberOf LazyWrapper - * @returns {Object} Returns the cloned `LazyWrapper` object. - */ - function lazyClone() { - var result = new LazyWrapper(this.__wrapped__); - result.__actions__ = copyArray(this.__actions__); - result.__dir__ = this.__dir__; - result.__filtered__ = this.__filtered__; - result.__iteratees__ = copyArray(this.__iteratees__); - result.__takeCount__ = this.__takeCount__; - result.__views__ = copyArray(this.__views__); - return result; + // If a type was specified, set the callback for the given type and name. + // Otherwise, if a null callback was specified, remove callbacks of the given name. + if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); + while (++i < n) { + if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback); + else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null); } - /** - * Reverses the direction of lazy iteration. - * - * @private - * @name reverse - * @memberOf LazyWrapper - * @returns {Object} Returns the new reversed `LazyWrapper` object. - */ - function lazyReverse() { - if (this.__filtered__) { - var result = new LazyWrapper(this); - result.__dir__ = -1; - result.__filtered__ = true; - } else { - result = this.clone(); - result.__dir__ *= -1; - } - return result; + return this; + }, + copy: function() { + var copy = {}, _ = this._; + for (var t in _) copy[t] = _[t].slice(); + return new Dispatch(copy); + }, + call: function(type, that) { + if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; + if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); + for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); + }, + apply: function(type, that, args) { + if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); + for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); + } +}; + +function get(type, name) { + for (var i = 0, n = type.length, c; i < n; ++i) { + if ((c = type[i]).name === name) { + return c.value; } + } +} - /** - * Extracts the unwrapped value from its lazy wrapper. - * - * @private - * @name value - * @memberOf LazyWrapper - * @returns {*} Returns the unwrapped value. - */ - function lazyValue() { - var array = this.__wrapped__.value(), - dir = this.__dir__, - isArr = isArray(array), - isRight = dir < 0, - arrLength = isArr ? array.length : 0, - view = getView(0, arrLength, this.__views__), - start = view.start, - end = view.end, - length = end - start, - index = isRight ? end : (start - 1), - iteratees = this.__iteratees__, - iterLength = iteratees.length, - resIndex = 0, - takeCount = nativeMin(length, this.__takeCount__); - - if (!isArr || (!isRight && arrLength == length && takeCount == length)) { - return baseWrapperValue(array, this.__actions__); - } - var result = []; - - outer: - while (length-- && resIndex < takeCount) { - index += dir; - - var iterIndex = -1, - value = array[index]; - - while (++iterIndex < iterLength) { - var data = iteratees[iterIndex], - iteratee = data.iteratee, - type = data.type, - computed = iteratee(value); - - if (type == LAZY_MAP_FLAG) { - value = computed; - } else if (!computed) { - if (type == LAZY_FILTER_FLAG) { - continue outer; - } else { - break outer; - } - } - } - result[resIndex++] = value; - } - return result; +function set(type, name, callback) { + for (var i = 0, n = type.length; i < n; ++i) { + if (type[i].name === name) { + type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); + break; } + } + if (callback != null) type.push({name: name, value: callback}); + return type; +} - // Ensure `LazyWrapper` is an instance of `baseLodash`. - LazyWrapper.prototype = baseCreate(baseLodash.prototype); - LazyWrapper.prototype.constructor = LazyWrapper; +var xhtml = "http://www.w3.org/1999/xhtml"; - /*------------------------------------------------------------------------*/ +var namespaces = { + svg: "http://www.w3.org/2000/svg", + xhtml: xhtml, + xlink: "http://www.w3.org/1999/xlink", + xml: "http://www.w3.org/XML/1998/namespace", + xmlns: "http://www.w3.org/2000/xmlns/" +}; - /** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } +var namespace = function(name) { + var prefix = name += "", i = prefix.indexOf(":"); + if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); + return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; +}; - /** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ - function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; - } +function creatorInherit(name) { + return function() { + var document = this.ownerDocument, + uri = this.namespaceURI; + return uri === xhtml && document.documentElement.namespaceURI === xhtml + ? document.createElement(name) + : document.createElementNS(uri, name); + }; +} - /** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; - } +function creatorFixed(fullname) { + return function() { + return this.ownerDocument.createElementNS(fullname.space, fullname.local); + }; +} - /** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; - } +var creator = function(name) { + var fullname = namespace(name); + return (fullname.local + ? creatorFixed + : creatorInherit)(fullname); +}; - /** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); - } +var nextId = 0; - /** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ - function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; - } +function local$1() { + return new Local; +} - // Add methods to `Hash`. - Hash.prototype.clear = hashClear; - Hash.prototype['delete'] = hashDelete; - Hash.prototype.get = hashGet; - Hash.prototype.has = hashHas; - Hash.prototype.set = hashSet; +function Local() { + this._ = "@" + (++nextId).toString(36); +} - /*------------------------------------------------------------------------*/ +Local.prototype = local$1.prototype = { + constructor: Local, + get: function(node) { + var id = this._; + while (!(id in node)) if (!(node = node.parentNode)) return; + return node[id]; + }, + set: function(node, value) { + return node[this._] = value; + }, + remove: function(node) { + return this._ in node && delete node[this._]; + }, + toString: function() { + return this._; + } +}; - /** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } +var matcher = function(selector) { + return function() { + return this.matches(selector); + }; +}; - /** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ - function listCacheClear() { - this.__data__ = []; - this.size = 0; - } +if (typeof document !== "undefined") { + var element = document.documentElement; + if (!element.matches) { + var vendorMatches = element.webkitMatchesSelector + || element.msMatchesSelector + || element.mozMatchesSelector + || element.oMatchesSelector; + matcher = function(selector) { + return function() { + return vendorMatches.call(this, selector); + }; + }; + } +} - /** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); +var matcher$1 = matcher; - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; - } +var filterEvents = {}; - /** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); +var event = null; + +if (typeof document !== "undefined") { + var element$1 = document.documentElement; + if (!("onmouseenter" in element$1)) { + filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"}; + } +} - return index < 0 ? undefined : data[index][1]; +function filterContextListener(listener, index, group) { + listener = contextListener(listener, index, group); + return function(event) { + var related = event.relatedTarget; + if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) { + listener.call(this, event); } + }; +} - /** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; +function contextListener(listener, index, group) { + return function(event1) { + var event0 = event; // Events can be reentrant (e.g., focus). + event = event1; + try { + listener.call(this, this.__data__, index, group); + } finally { + event = event0; } + }; +} - /** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ - function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); +function parseTypenames$1(typenames) { + return typenames.trim().split(/^|\s+/).map(function(t) { + var name = "", i = t.indexOf("."); + if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); + return {type: t, name: name}; + }); +} - if (index < 0) { - ++this.size; - data.push([key, value]); +function onRemove(typename) { + return function() { + var on = this.__on; + if (!on) return; + for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { + if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { + this.removeEventListener(o.type, o.listener, o.capture); } else { - data[index][1] = value; + on[++i] = o; } - return this; } + if (++i) on.length = i; + else delete this.__on; + }; +} - // Add methods to `ListCache`. - ListCache.prototype.clear = listCacheClear; - ListCache.prototype['delete'] = listCacheDelete; - ListCache.prototype.get = listCacheGet; - ListCache.prototype.has = listCacheHas; - ListCache.prototype.set = listCacheSet; +function onAdd(typename, value, capture) { + var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener; + return function(d, i, group) { + var on = this.__on, o, listener = wrap(value, i, group); + if (on) for (var j = 0, m = on.length; j < m; ++j) { + if ((o = on[j]).type === typename.type && o.name === typename.name) { + this.removeEventListener(o.type, o.listener, o.capture); + this.addEventListener(o.type, o.listener = listener, o.capture = capture); + o.value = value; + return; + } + } + this.addEventListener(typename.type, listener, capture); + o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture}; + if (!on) this.__on = [o]; + else on.push(o); + }; +} - /*------------------------------------------------------------------------*/ +var selection_on = function(typename, value, capture) { + var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t; - /** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); + if (arguments.length < 2) { + var on = this.node().__on; + if (on) for (var j = 0, m = on.length, o; j < m; ++j) { + for (i = 0, o = on[j]; i < n; ++i) { + if ((t = typenames[i]).type === o.type && t.name === o.name) { + return o.value; + } } } + return; + } - /** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ - function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; - } + on = value ? onAdd : onRemove; + if (capture == null) capture = false; + for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture)); + return this; +}; - /** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; - } +function customEvent(event1, listener, that, args) { + var event0 = event; + event1.sourceEvent = event; + event = event1; + try { + return listener.apply(that, args); + } finally { + event = event0; + } +} - /** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function mapCacheGet(key) { - return getMapData(this, key).get(key); - } +var sourceEvent = function() { + var current = event, source; + while (source = current.sourceEvent) current = source; + return current; +}; - /** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function mapCacheHas(key) { - return getMapData(this, key).has(key); - } +var point = function(node, event) { + var svg = node.ownerSVGElement || node; - /** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ - function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + if (svg.createSVGPoint) { + var point = svg.createSVGPoint(); + point.x = event.clientX, point.y = event.clientY; + point = point.matrixTransform(node.getScreenCTM().inverse()); + return [point.x, point.y]; + } - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; - } + var rect = node.getBoundingClientRect(); + return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop]; +}; + +var d3_mouse = function(node) { + var event = sourceEvent(); + if (event.changedTouches) event = event.changedTouches[0]; + return point(node, event); +}; - // Add methods to `MapCache`. - MapCache.prototype.clear = mapCacheClear; - MapCache.prototype['delete'] = mapCacheDelete; - MapCache.prototype.get = mapCacheGet; - MapCache.prototype.has = mapCacheHas; - MapCache.prototype.set = mapCacheSet; +function none() {} - /*------------------------------------------------------------------------*/ +var selector = function(selector) { + return selector == null ? none : function() { + return this.querySelector(selector); + }; +}; - /** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ - function SetCache(values) { - var index = -1, - length = values == null ? 0 : values.length; +var selection_select = function(select) { + if (typeof select !== "function") select = selector(select); - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { + if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { + if ("__data__" in node) subnode.__data__ = node.__data__; + subgroup[i] = subnode; } } + } - /** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ - function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; - } + return new Selection(subgroups, this._parents); +}; - /** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ - function setCacheHas(value) { - return this.__data__.has(value); - } +function empty$1() { + return []; +} - // Add methods to `SetCache`. - SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; - SetCache.prototype.has = setCacheHas; +var selectorAll = function(selector) { + return selector == null ? empty$1 : function() { + return this.querySelectorAll(selector); + }; +}; - /*------------------------------------------------------------------------*/ +var selection_selectAll = function(select) { + if (typeof select !== "function") select = selectorAll(select); - /** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Stack(entries) { - var data = this.__data__ = new ListCache(entries); - this.size = data.size; + for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + subgroups.push(select.call(node, node.__data__, i, group)); + parents.push(node); + } } + } - /** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ - function stackClear() { - this.__data__ = new ListCache; - this.size = 0; - } + return new Selection(subgroups, parents); +}; - /** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function stackDelete(key) { - var data = this.__data__, - result = data['delete'](key); +var selection_filter = function(match) { + if (typeof match !== "function") match = matcher$1(match); - this.size = data.size; - return result; + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { + if ((node = group[i]) && match.call(node, node.__data__, i, group)) { + subgroup.push(node); + } } + } - /** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function stackGet(key) { - return this.__data__.get(key); - } + return new Selection(subgroups, this._parents); +}; - /** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function stackHas(key) { - return this.__data__.has(key); - } +var sparse = function(update) { + return new Array(update.length); +}; - /** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ - function stackSet(key, value) { - var data = this.__data__; - if (data instanceof ListCache) { - var pairs = data.__data__; - if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - this.size = ++data.size; - return this; - } - data = this.__data__ = new MapCache(pairs); - } - data.set(key, value); - this.size = data.size; - return this; - } +var selection_enter = function() { + return new Selection(this._enter || this._groups.map(sparse), this._parents); +}; - // Add methods to `Stack`. - Stack.prototype.clear = stackClear; - Stack.prototype['delete'] = stackDelete; - Stack.prototype.get = stackGet; - Stack.prototype.has = stackHas; - Stack.prototype.set = stackSet; +function EnterNode(parent, datum) { + this.ownerDocument = parent.ownerDocument; + this.namespaceURI = parent.namespaceURI; + this._next = null; + this._parent = parent; + this.__data__ = datum; +} - /*------------------------------------------------------------------------*/ +EnterNode.prototype = { + constructor: EnterNode, + appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, + insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, + querySelector: function(selector) { return this._parent.querySelector(selector); }, + querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } +}; - /** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ - function arrayLikeKeys(value, inherited) { - var isArr = isArray(value), - isArg = !isArr && isArguments(value), - isBuff = !isArr && !isArg && isBuffer(value), - isType = !isArr && !isArg && !isBuff && isTypedArray(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - isIndex(key, length) - ))) { - result.push(key); - } - } - return result; - } +var constant$1 = function(x) { + return function() { + return x; + }; +}; - /** - * A specialized version of `_.sample` for arrays. - * - * @private - * @param {Array} array The array to sample. - * @returns {*} Returns the random element. - */ - function arraySample(array) { - var length = array.length; - return length ? array[baseRandom(0, length - 1)] : undefined; - } +var keyPrefix = "$"; // Protect against keys like “__proto__”. - /** - * A specialized version of `_.sampleSize` for arrays. - * - * @private - * @param {Array} array The array to sample. - * @param {number} n The number of elements to sample. - * @returns {Array} Returns the random elements. - */ - function arraySampleSize(array, n) { - return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); - } +function bindIndex(parent, group, enter, update, exit, data) { + var i = 0, + node, + groupLength = group.length, + dataLength = data.length; - /** - * A specialized version of `_.shuffle` for arrays. - * - * @private - * @param {Array} array The array to shuffle. - * @returns {Array} Returns the new shuffled array. - */ - function arrayShuffle(array) { - return shuffleSelf(copyArray(array)); + // Put any non-null nodes that fit into update. + // Put any null nodes into enter. + // Put any remaining data into enter. + for (; i < dataLength; ++i) { + if (node = group[i]) { + node.__data__ = data[i]; + update[i] = node; + } else { + enter[i] = new EnterNode(parent, data[i]); } + } - /** - * This function is like `assignValue` except that it doesn't assign - * `undefined` values. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignMergeValue(object, key, value) { - if ((value !== undefined && !eq(object[key], value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } + // Put any non-null nodes that don’t fit into exit. + for (; i < groupLength; ++i) { + if (node = group[i]) { + exit[i] = node; } + } +} - /** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } - } +function bindKey(parent, group, enter, update, exit, data, key) { + var i, + node, + nodeByKeyValue = {}, + groupLength = group.length, + dataLength = data.length, + keyValues = new Array(groupLength), + keyValue; - /** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } + // Compute the key for each node. + // If multiple nodes have the same key, the duplicates are added to exit. + for (i = 0; i < groupLength; ++i) { + if (node = group[i]) { + keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group); + if (keyValue in nodeByKeyValue) { + exit[i] = node; + } else { + nodeByKeyValue[keyValue] = node; } - return -1; } + } - /** - * Aggregates elements of `collection` on `accumulator` with keys transformed - * by `iteratee` and values set by `setter`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ - function baseAggregator(collection, setter, iteratee, accumulator) { - baseEach(collection, function(value, key, collection) { - setter(accumulator, value, iteratee(value), collection); - }); - return accumulator; + // Compute the key for each datum. + // If there a node associated with this key, join and add it to update. + // If there is not (or the key is a duplicate), add it to enter. + for (i = 0; i < dataLength; ++i) { + keyValue = keyPrefix + key.call(parent, data[i], i, data); + if (node = nodeByKeyValue[keyValue]) { + update[i] = node; + node.__data__ = data[i]; + nodeByKeyValue[keyValue] = null; + } else { + enter[i] = new EnterNode(parent, data[i]); } + } - /** - * The base implementation of `_.assign` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ - function baseAssign(object, source) { - return object && copyObject(source, keys(source), object); + // Add any remaining nodes that were not bound to data to exit. + for (i = 0; i < groupLength; ++i) { + if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) { + exit[i] = node; } + } +} - /** - * The base implementation of `_.assignIn` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ - function baseAssignIn(object, source) { - return object && copyObject(source, keysIn(source), object); - } +var selection_data = function(value, key) { + if (!value) { + data = new Array(this.size()), j = -1; + this.each(function(d) { data[++j] = d; }); + return data; + } - /** - * The base implementation of `assignValue` and `assignMergeValue` without - * value checks. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function baseAssignValue(object, key, value) { - if (key == '__proto__' && defineProperty) { - defineProperty(object, key, { - 'configurable': true, - 'enumerable': true, - 'value': value, - 'writable': true - }); - } else { - object[key] = value; - } - } + var bind = key ? bindKey : bindIndex, + parents = this._parents, + groups = this._groups; - /** - * The base implementation of `_.at` without support for individual paths. - * - * @private - * @param {Object} object The object to iterate over. - * @param {string[]} paths The property paths to pick. - * @returns {Array} Returns the picked elements. - */ - function baseAt(object, paths) { - var index = -1, - length = paths.length, - result = Array(length), - skip = object == null; - - while (++index < length) { - result[index] = skip ? undefined : get(object, paths[index]); - } - return result; - } + if (typeof value !== "function") value = constant$1(value); - /** - * The base implementation of `_.clamp` which doesn't coerce arguments. - * - * @private - * @param {number} number The number to clamp. - * @param {number} [lower] The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the clamped number. - */ - function baseClamp(number, lower, upper) { - if (number === number) { - if (upper !== undefined) { - number = number <= upper ? number : upper; - } - if (lower !== undefined) { - number = number >= lower ? number : lower; - } + for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { + var parent = parents[j], + group = groups[j], + groupLength = group.length, + data = value.call(parent, parent && parent.__data__, j, parents), + dataLength = data.length, + enterGroup = enter[j] = new Array(dataLength), + updateGroup = update[j] = new Array(dataLength), + exitGroup = exit[j] = new Array(groupLength); + + bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); + + // Now connect the enter nodes to their following update node, such that + // appendChild can insert the materialized enter node before this node, + // rather than at the end of the parent node. + for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { + if (previous = enterGroup[i0]) { + if (i0 >= i1) i1 = i0 + 1; + while (!(next = updateGroup[i1]) && ++i1 < dataLength); + previous._next = next || null; } - return number; } + } - /** - * The base implementation of `_.clone` and `_.cloneDeep` which tracks - * traversed objects. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} bitmask The bitmask flags. - * 1 - Deep clone - * 2 - Flatten inherited properties - * 4 - Clone symbols - * @param {Function} [customizer] The function to customize cloning. - * @param {string} [key] The key of `value`. - * @param {Object} [object] The parent object of `value`. - * @param {Object} [stack] Tracks traversed objects and their clone counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, bitmask, customizer, key, object, stack) { - var result, - isDeep = bitmask & CLONE_DEEP_FLAG, - isFlat = bitmask & CLONE_FLAT_FLAG, - isFull = bitmask & CLONE_SYMBOLS_FLAG; + update = new Selection(update, parents); + update._enter = enter; + update._exit = exit; + return update; +}; - if (customizer) { - result = object ? customizer(value, key, object, stack) : customizer(value); - } - if (result !== undefined) { - return result; - } - if (!isObject(value)) { - return value; - } - var isArr = isArray(value); - if (isArr) { - result = initCloneArray(value); - if (!isDeep) { - return copyArray(value, result); - } - } else { - var tag = getTag(value), - isFunc = tag == funcTag || tag == genTag; - - if (isBuffer(value)) { - return cloneBuffer(value, isDeep); - } - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - result = (isFlat || isFunc) ? {} : initCloneObject(value); - if (!isDeep) { - return isFlat - ? copySymbolsIn(value, baseAssignIn(result, value)) - : copySymbols(value, baseAssign(result, value)); - } - } else { - if (!cloneableTags[tag]) { - return object ? value : {}; - } - result = initCloneByTag(value, tag, baseClone, isDeep); - } - } - // Check for circular references and return its corresponding clone. - stack || (stack = new Stack); - var stacked = stack.get(value); - if (stacked) { - return stacked; - } - stack.set(value, result); - - var keysFunc = isFull - ? (isFlat ? getAllKeysIn : getAllKeys) - : (isFlat ? keysIn : keys); +var selection_exit = function() { + return new Selection(this._exit || this._groups.map(sparse), this._parents); +}; - var props = isArr ? undefined : keysFunc(value); - arrayEach(props || value, function(subValue, key) { - if (props) { - key = subValue; - subValue = value[key]; - } - // Recursively populate clone (susceptible to call stack limits). - assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); - }); - return result; - } +var selection_merge = function(selection$$1) { - /** - * The base implementation of `_.conforms` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property predicates to conform to. - * @returns {Function} Returns the new spec function. - */ - function baseConforms(source) { - var props = keys(source); - return function(object) { - return baseConformsTo(object, source, props); - }; + for (var groups0 = this._groups, groups1 = selection$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { + for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { + if (node = group0[i] || group1[i]) { + merge[i] = node; + } } + } - /** - * The base implementation of `_.conformsTo` which accepts `props` to check. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property predicates to conform to. - * @returns {boolean} Returns `true` if `object` conforms, else `false`. - */ - function baseConformsTo(object, source, props) { - var length = props.length; - if (object == null) { - return !length; - } - object = Object(object); - while (length--) { - var key = props[length], - predicate = source[key], - value = object[key]; + for (; j < m0; ++j) { + merges[j] = groups0[j]; + } - if ((value === undefined && !(key in object)) || !predicate(value)) { - return false; - } - } - return true; - } + return new Selection(merges, this._parents); +}; - /** - * The base implementation of `_.delay` and `_.defer` which accepts `args` - * to provide to `func`. - * - * @private - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {Array} args The arguments to provide to `func`. - * @returns {number|Object} Returns the timer id or timeout object. - */ - function baseDelay(func, wait, args) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return setTimeout(function() { func.apply(undefined, args); }, wait); - } +var selection_order = function() { - /** - * The base implementation of methods like `_.difference` without support - * for excluding multiple arrays or iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Array} values The values to exclude. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - */ - function baseDifference(array, values, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - isCommon = true, - length = array.length, - result = [], - valuesLength = values.length; - - if (!length) { - return result; - } - if (iteratee) { - values = arrayMap(values, baseUnary(iteratee)); - } - if (comparator) { - includes = arrayIncludesWith; - isCommon = false; - } - else if (values.length >= LARGE_ARRAY_SIZE) { - includes = cacheHas; - isCommon = false; - values = new SetCache(values); - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee == null ? value : iteratee(value); - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var valuesIndex = valuesLength; - while (valuesIndex--) { - if (values[valuesIndex] === computed) { - continue outer; - } - } - result.push(value); - } - else if (!includes(values, computed, comparator)) { - result.push(value); - } + for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { + for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { + if (node = group[i]) { + if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); + next = node; } - return result; } + } - /** - * The base implementation of `_.forEach` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ - var baseEach = createBaseEach(baseForOwn); - - /** - * The base implementation of `_.forEachRight` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ - var baseEachRight = createBaseEach(baseForOwnRight, true); - - /** - * The base implementation of `_.every` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false` - */ - function baseEvery(collection, predicate) { - var result = true; - baseEach(collection, function(value, index, collection) { - result = !!predicate(value, index, collection); - return result; - }); - return result; - } + return this; +}; - /** - * The base implementation of methods like `_.max` and `_.min` which accepts a - * `comparator` to determine the extremum value. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The iteratee invoked per iteration. - * @param {Function} comparator The comparator used to compare values. - * @returns {*} Returns the extremum value. - */ - function baseExtremum(array, iteratee, comparator) { - var index = -1, - length = array.length; +var selection_sort = function(compare) { + if (!compare) compare = ascending; - while (++index < length) { - var value = array[index], - current = iteratee(value); + function compareNode(a, b) { + return a && b ? compare(a.__data__, b.__data__) : !a - !b; + } - if (current != null && (computed === undefined - ? (current === current && !isSymbol(current)) - : comparator(current, computed) - )) { - var computed = current, - result = value; - } + for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { + if (node = group[i]) { + sortgroup[i] = node; } - return result; } + sortgroup.sort(compareNode); + } - /** - * The base implementation of `_.fill` without an iteratee call guard. - * - * @private - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - */ - function baseFill(array, value, start, end) { - var length = array.length; - - start = toInteger(start); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (end === undefined || end > length) ? length : toInteger(end); - if (end < 0) { - end += length; - } - end = start > end ? 0 : toLength(end); - while (start < end) { - array[start++] = value; - } - return array; - } + return new Selection(sortgroups, this._parents).order(); +}; - /** - * The base implementation of `_.filter` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function baseFilter(collection, predicate) { - var result = []; - baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); - } - }); - return result; - } +function ascending(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; +} - /** - * The base implementation of `_.flatten` with support for restricting flattening. - * - * @private - * @param {Array} array The array to flatten. - * @param {number} depth The maximum recursion depth. - * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. - * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. - * @param {Array} [result=[]] The initial result value. - * @returns {Array} Returns the new flattened array. - */ - function baseFlatten(array, depth, predicate, isStrict, result) { - var index = -1, - length = array.length; - - predicate || (predicate = isFlattenable); - result || (result = []); - - while (++index < length) { - var value = array[index]; - if (depth > 0 && predicate(value)) { - if (depth > 1) { - // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, depth - 1, predicate, isStrict, result); - } else { - arrayPush(result, value); - } - } else if (!isStrict) { - result[result.length] = value; - } - } - return result; - } +var selection_call = function() { + var callback = arguments[0]; + arguments[0] = this; + callback.apply(null, arguments); + return this; +}; - /** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseFor = createBaseFor(); +var selection_nodes = function() { + var nodes = new Array(this.size()), i = -1; + this.each(function() { nodes[++i] = this; }); + return nodes; +}; - /** - * This function is like `baseFor` except that it iterates over properties - * in the opposite order. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseForRight = createBaseFor(true); +var selection_node = function() { - /** - * The base implementation of `_.forOwn` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwn(object, iteratee) { - return object && baseFor(object, iteratee, keys); + for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { + for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { + var node = group[i]; + if (node) return node; } + } - /** - * The base implementation of `_.forOwnRight` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwnRight(object, iteratee) { - return object && baseForRight(object, iteratee, keys); - } + return null; +}; - /** - * The base implementation of `_.functions` which creates an array of - * `object` function property names filtered from `props`. - * - * @private - * @param {Object} object The object to inspect. - * @param {Array} props The property names to filter. - * @returns {Array} Returns the function names. - */ - function baseFunctions(object, props) { - return arrayFilter(props, function(key) { - return isFunction(object[key]); - }); - } +var selection_size = function() { + var size = 0; + this.each(function() { ++size; }); + return size; +}; - /** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ - function baseGet(object, path) { - path = castPath(path, object); +var selection_empty = function() { + return !this.node(); +}; - var index = 0, - length = path.length; +var selection_each = function(callback) { - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; + for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { + for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { + if (node = group[i]) callback.call(node, node.__data__, i, group); } + } - /** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ - function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); - } + return this; +}; - /** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); - } +function attrRemove(name) { + return function() { + this.removeAttribute(name); + }; +} - /** - * The base implementation of `_.gt` which doesn't coerce arguments. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than `other`, - * else `false`. - */ - function baseGt(value, other) { - return value > other; - } +function attrRemoveNS(fullname) { + return function() { + this.removeAttributeNS(fullname.space, fullname.local); + }; +} - /** - * The base implementation of `_.has` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHas(object, key) { - return object != null && hasOwnProperty.call(object, key); - } +function attrConstant(name, value) { + return function() { + this.setAttribute(name, value); + }; +} - /** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHasIn(object, key) { - return object != null && key in Object(object); - } +function attrConstantNS(fullname, value) { + return function() { + this.setAttributeNS(fullname.space, fullname.local, value); + }; +} - /** - * The base implementation of `_.inRange` which doesn't coerce arguments. - * - * @private - * @param {number} number The number to check. - * @param {number} start The start of the range. - * @param {number} end The end of the range. - * @returns {boolean} Returns `true` if `number` is in the range, else `false`. - */ - function baseInRange(number, start, end) { - return number >= nativeMin(start, end) && number < nativeMax(start, end); - } +function attrFunction(name, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.removeAttribute(name); + else this.setAttribute(name, v); + }; +} - /** - * The base implementation of methods like `_.intersection`, without support - * for iteratee shorthands, that accepts an array of arrays to inspect. - * - * @private - * @param {Array} arrays The arrays to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of shared values. - */ - function baseIntersection(arrays, iteratee, comparator) { - var includes = comparator ? arrayIncludesWith : arrayIncludes, - length = arrays[0].length, - othLength = arrays.length, - othIndex = othLength, - caches = Array(othLength), - maxLength = Infinity, - result = []; - - while (othIndex--) { - var array = arrays[othIndex]; - if (othIndex && iteratee) { - array = arrayMap(array, baseUnary(iteratee)); - } - maxLength = nativeMin(array.length, maxLength); - caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) - ? new SetCache(othIndex && array) - : undefined; - } - array = arrays[0]; - - var index = -1, - seen = caches[0]; - - outer: - while (++index < length && result.length < maxLength) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (!(seen - ? cacheHas(seen, computed) - : includes(result, computed, comparator) - )) { - othIndex = othLength; - while (--othIndex) { - var cache = caches[othIndex]; - if (!(cache - ? cacheHas(cache, computed) - : includes(arrays[othIndex], computed, comparator)) - ) { - continue outer; - } - } - if (seen) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } +function attrFunctionNS(fullname, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.removeAttributeNS(fullname.space, fullname.local); + else this.setAttributeNS(fullname.space, fullname.local, v); + }; +} - /** - * The base implementation of `_.invert` and `_.invertBy` which inverts - * `object` with values transformed by `iteratee` and set by `setter`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform values. - * @param {Object} accumulator The initial inverted object. - * @returns {Function} Returns `accumulator`. - */ - function baseInverter(object, setter, iteratee, accumulator) { - baseForOwn(object, function(value, key, object) { - setter(accumulator, iteratee(value), key, object); - }); - return accumulator; - } +var selection_attr = function(name, value) { + var fullname = namespace(name); - /** - * The base implementation of `_.invoke` without support for individual - * method arguments. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {Array} args The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. - */ - function baseInvoke(object, path, args) { - path = castPath(path, object); - object = parent(object, path); - var func = object == null ? object : object[toKey(last(path))]; - return func == null ? undefined : apply(func, object, args); - } + if (arguments.length < 2) { + var node = this.node(); + return fullname.local + ? node.getAttributeNS(fullname.space, fullname.local) + : node.getAttribute(fullname); + } - /** - * The base implementation of `_.isArguments`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - */ - function baseIsArguments(value) { - return isObjectLike(value) && baseGetTag(value) == argsTag; - } + return this.each((value == null + ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function" + ? (fullname.local ? attrFunctionNS : attrFunction) + : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)); +}; - /** - * The base implementation of `_.isArrayBuffer` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. - */ - function baseIsArrayBuffer(value) { - return isObjectLike(value) && baseGetTag(value) == arrayBufferTag; - } +var defaultView = function(node) { + return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node + || (node.document && node) // node is a Window + || node.defaultView; // node is a Document +}; - /** - * The base implementation of `_.isDate` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a date object, else `false`. - */ - function baseIsDate(value) { - return isObjectLike(value) && baseGetTag(value) == dateTag; - } +function styleRemove(name) { + return function() { + this.style.removeProperty(name); + }; +} - /** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {boolean} bitmask The bitmask flags. - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Function} [customizer] The function to customize comparisons. - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(value, other, bitmask, customizer, stack) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); - } +function styleConstant(name, value, priority) { + return function() { + this.style.setProperty(name, value, priority); + }; +} - /** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = objIsArr ? arrayTag : getTag(object), - othTag = othIsArr ? arrayTag : getTag(other); +function styleFunction(name, value, priority) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.style.removeProperty(name); + else this.style.setProperty(name, v, priority); + }; +} - objTag = objTag == argsTag ? objectTag : objTag; - othTag = othTag == argsTag ? objectTag : othTag; +var selection_style = function(name, value, priority) { + return arguments.length > 1 + ? this.each((value == null + ? styleRemove : typeof value === "function" + ? styleFunction + : styleConstant)(name, value, priority == null ? "" : priority)) + : styleValue(this.node(), name); +}; - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; +function styleValue(node, name) { + return node.style.getPropertyValue(name) + || defaultView(node).getComputedStyle(node, null).getPropertyValue(name); +} - if (isSameTag && isBuffer(object)) { - if (!isBuffer(other)) { - return false; - } - objIsArr = true; - objIsObj = false; - } - if (isSameTag && !objIsObj) { - stack || (stack = new Stack); - return (objIsArr || isTypedArray(object)) - ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) - : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); - } - if (!(bitmask & COMPARE_PARTIAL_FLAG)) { - var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); +function propertyRemove(name) { + return function() { + delete this[name]; + }; +} - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; +function propertyConstant(name, value) { + return function() { + this[name] = value; + }; +} - stack || (stack = new Stack); - return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); - } - } - if (!isSameTag) { - return false; - } - stack || (stack = new Stack); - return equalObjects(object, other, bitmask, customizer, equalFunc, stack); - } +function propertyFunction(name, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) delete this[name]; + else this[name] = v; + }; +} - /** - * The base implementation of `_.isMap` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - */ - function baseIsMap(value) { - return isObjectLike(value) && getTag(value) == mapTag; - } +var selection_property = function(name, value) { + return arguments.length > 1 + ? this.each((value == null + ? propertyRemove : typeof value === "function" + ? propertyFunction + : propertyConstant)(name, value)) + : this.node()[name]; +}; - /** - * The base implementation of `_.isMatch` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ - function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; +function classArray(string) { + return string.trim().split(/^|\s+/); +} - if (object == null) { - return !length; - } - object = Object(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var stack = new Stack; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } - if (!(result === undefined - ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) - : result - )) { - return false; - } - } - } - return true; - } +function classList(node) { + return node.classList || new ClassList(node); +} - /** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ - function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); - } +function ClassList(node) { + this._node = node; + this._names = classArray(node.getAttribute("class") || ""); +} - /** - * The base implementation of `_.isRegExp` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. - */ - function baseIsRegExp(value) { - return isObjectLike(value) && baseGetTag(value) == regexpTag; +ClassList.prototype = { + add: function(name) { + var i = this._names.indexOf(name); + if (i < 0) { + this._names.push(name); + this._node.setAttribute("class", this._names.join(" ")); } - - /** - * The base implementation of `_.isSet` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - */ - function baseIsSet(value) { - return isObjectLike(value) && getTag(value) == setTag; + }, + remove: function(name) { + var i = this._names.indexOf(name); + if (i >= 0) { + this._names.splice(i, 1); + this._node.setAttribute("class", this._names.join(" ")); } + }, + contains: function(name) { + return this._names.indexOf(name) >= 0; + } +}; - /** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ - function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; - } +function classedAdd(node, names) { + var list = classList(node), i = -1, n = names.length; + while (++i < n) list.add(names[i]); +} - /** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ - function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; - } - if (value == null) { - return identity; - } - if (typeof value == 'object') { - return isArray(value) - ? baseMatchesProperty(value[0], value[1]) - : baseMatches(value); - } - return property(value); - } +function classedRemove(node, names) { + var list = classList(node), i = -1, n = names.length; + while (++i < n) list.remove(names[i]); +} - /** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; - } +function classedTrue(names) { + return function() { + classedAdd(this, names); + }; +} - /** - * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeysIn(object) { - if (!isObject(object)) { - return nativeKeysIn(object); - } - var isProto = isPrototype(object), - result = []; +function classedFalse(names) { + return function() { + classedRemove(this, names); + }; +} - for (var key in object) { - if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; - } +function classedFunction(names, value) { + return function() { + (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); + }; +} - /** - * The base implementation of `_.lt` which doesn't coerce arguments. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than `other`, - * else `false`. - */ - function baseLt(value, other) { - return value < other; - } +var selection_classed = function(name, value) { + var names = classArray(name + ""); - /** - * The base implementation of `_.map` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function baseMap(collection, iteratee) { - var index = -1, - result = isArrayLike(collection) ? Array(collection.length) : []; + if (arguments.length < 2) { + var list = classList(this.node()), i = -1, n = names.length; + while (++i < n) if (!list.contains(names[i])) return false; + return true; + } - baseEach(collection, function(value, key, collection) { - result[++index] = iteratee(value, key, collection); - }); - return result; - } + return this.each((typeof value === "function" + ? classedFunction : value + ? classedTrue + : classedFalse)(names, value)); +}; - /** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return matchesStrictComparable(matchData[0][0], matchData[0][1]); - } - return function(object) { - return object === source || baseIsMatch(object, source, matchData); - }; - } +function textRemove() { + this.textContent = ""; +} - /** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatchesProperty(path, srcValue) { - if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(toKey(path), srcValue); - } - return function(object) { - var objValue = get(object, path); - return (objValue === undefined && objValue === srcValue) - ? hasIn(object, path) - : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); - }; - } +function textConstant(value) { + return function() { + this.textContent = value; + }; +} - /** - * The base implementation of `_.merge` without support for multiple sources. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {number} srcIndex The index of `source`. - * @param {Function} [customizer] The function to customize merged values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMerge(object, source, srcIndex, customizer, stack) { - if (object === source) { - return; - } - baseFor(source, function(srcValue, key) { - if (isObject(srcValue)) { - stack || (stack = new Stack); - baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); - } - else { - var newValue = customizer - ? customizer(object[key], srcValue, (key + ''), object, source, stack) - : undefined; +function textFunction(value) { + return function() { + var v = value.apply(this, arguments); + this.textContent = v == null ? "" : v; + }; +} - if (newValue === undefined) { - newValue = srcValue; - } - assignMergeValue(object, key, newValue); - } - }, keysIn); - } +var selection_text = function(value) { + return arguments.length + ? this.each(value == null + ? textRemove : (typeof value === "function" + ? textFunction + : textConstant)(value)) + : this.node().textContent; +}; - /** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {number} srcIndex The index of `source`. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize assigned values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { - var objValue = object[key], - srcValue = source[key], - stacked = stack.get(srcValue); +function htmlRemove() { + this.innerHTML = ""; +} - if (stacked) { - assignMergeValue(object, key, stacked); - return; - } - var newValue = customizer - ? customizer(objValue, srcValue, (key + ''), object, source, stack) - : undefined; +function htmlConstant(value) { + return function() { + this.innerHTML = value; + }; +} - var isCommon = newValue === undefined; +function htmlFunction(value) { + return function() { + var v = value.apply(this, arguments); + this.innerHTML = v == null ? "" : v; + }; +} - if (isCommon) { - var isArr = isArray(srcValue), - isBuff = !isArr && isBuffer(srcValue), - isTyped = !isArr && !isBuff && isTypedArray(srcValue); +var selection_html = function(value) { + return arguments.length + ? this.each(value == null + ? htmlRemove : (typeof value === "function" + ? htmlFunction + : htmlConstant)(value)) + : this.node().innerHTML; +}; - newValue = srcValue; - if (isArr || isBuff || isTyped) { - if (isArray(objValue)) { - newValue = objValue; - } - else if (isArrayLikeObject(objValue)) { - newValue = copyArray(objValue); - } - else if (isBuff) { - isCommon = false; - newValue = cloneBuffer(srcValue, true); - } - else if (isTyped) { - isCommon = false; - newValue = cloneTypedArray(srcValue, true); - } - else { - newValue = []; - } - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - newValue = objValue; - if (isArguments(objValue)) { - newValue = toPlainObject(objValue); - } - else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { - newValue = initCloneObject(srcValue); - } - } - else { - isCommon = false; - } - } - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, newValue); - mergeFunc(newValue, srcValue, srcIndex, customizer, stack); - stack['delete'](srcValue); - } - assignMergeValue(object, key, newValue); - } +function raise() { + if (this.nextSibling) this.parentNode.appendChild(this); +} - /** - * The base implementation of `_.nth` which doesn't coerce arguments. - * - * @private - * @param {Array} array The array to query. - * @param {number} n The index of the element to return. - * @returns {*} Returns the nth element of `array`. - */ - function baseNth(array, n) { - var length = array.length; - if (!length) { - return; - } - n += n < 0 ? length : 0; - return isIndex(n, length) ? array[n] : undefined; - } +var selection_raise = function() { + return this.each(raise); +}; - /** - * The base implementation of `_.orderBy` without param guards. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {string[]} orders The sort orders of `iteratees`. - * @returns {Array} Returns the new sorted array. - */ - function baseOrderBy(collection, iteratees, orders) { - var index = -1; - iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee())); +function lower() { + if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); +} - var result = baseMap(collection, function(value, key, collection) { - var criteria = arrayMap(iteratees, function(iteratee) { - return iteratee(value); - }); - return { 'criteria': criteria, 'index': ++index, 'value': value }; - }); +var selection_lower = function() { + return this.each(lower); +}; - return baseSortBy(result, function(object, other) { - return compareMultiple(object, other, orders); - }); - } +var selection_append = function(name) { + var create = typeof name === "function" ? name : creator(name); + return this.select(function() { + return this.appendChild(create.apply(this, arguments)); + }); +}; - /** - * The base implementation of `_.pick` without support for individual - * property identifiers. - * - * @private - * @param {Object} object The source object. - * @param {string[]} paths The property paths to pick. - * @returns {Object} Returns the new object. - */ - function basePick(object, paths) { - return basePickBy(object, paths, function(value, path) { - return hasIn(object, path); - }); - } +function constantNull() { + return null; +} - /** - * The base implementation of `_.pickBy` without support for iteratee shorthands. - * - * @private - * @param {Object} object The source object. - * @param {string[]} paths The property paths to pick. - * @param {Function} predicate The function invoked per property. - * @returns {Object} Returns the new object. - */ - function basePickBy(object, paths, predicate) { - var index = -1, - length = paths.length, - result = {}; +var selection_insert = function(name, before) { + var create = typeof name === "function" ? name : creator(name), + select = before == null ? constantNull : typeof before === "function" ? before : selector(before); + return this.select(function() { + return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); + }); +}; - while (++index < length) { - var path = paths[index], - value = baseGet(object, path); +function remove() { + var parent = this.parentNode; + if (parent) parent.removeChild(this); +} - if (predicate(value, path)) { - baseSet(result, castPath(path, object), value); - } - } - return result; - } +var selection_remove = function() { + return this.each(remove); +}; - /** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyDeep(path) { - return function(object) { - return baseGet(object, path); - }; - } +var selection_datum = function(value) { + return arguments.length + ? this.property("__data__", value) + : this.node().__data__; +}; - /** - * The base implementation of `_.pullAllBy` without support for iteratee - * shorthands. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns `array`. - */ - function basePullAll(array, values, iteratee, comparator) { - var indexOf = comparator ? baseIndexOfWith : baseIndexOf, - index = -1, - length = values.length, - seen = array; - - if (array === values) { - values = copyArray(values); - } - if (iteratee) { - seen = arrayMap(array, baseUnary(iteratee)); - } - while (++index < length) { - var fromIndex = 0, - value = values[index], - computed = iteratee ? iteratee(value) : value; - - while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { - if (seen !== array) { - splice.call(seen, fromIndex, 1); - } - splice.call(array, fromIndex, 1); - } - } - return array; - } +function dispatchEvent(node, type, params) { + var window = defaultView(node), + event = window.CustomEvent; - /** - * The base implementation of `_.pullAt` without support for individual - * indexes or capturing the removed elements. - * - * @private - * @param {Array} array The array to modify. - * @param {number[]} indexes The indexes of elements to remove. - * @returns {Array} Returns `array`. - */ - function basePullAt(array, indexes) { - var length = array ? indexes.length : 0, - lastIndex = length - 1; - - while (length--) { - var index = indexes[length]; - if (length == lastIndex || index !== previous) { - var previous = index; - if (isIndex(index)) { - splice.call(array, index, 1); - } else { - baseUnset(array, index); - } - } - } - return array; - } + if (typeof event === "function") { + event = new event(type, params); + } else { + event = window.document.createEvent("Event"); + if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; + else event.initEvent(type, false, false); + } - /** - * The base implementation of `_.random` without support for returning - * floating-point numbers. - * - * @private - * @param {number} lower The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the random number. - */ - function baseRandom(lower, upper) { - return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); - } + node.dispatchEvent(event); +} - /** - * The base implementation of `_.range` and `_.rangeRight` which doesn't - * coerce arguments. - * - * @private - * @param {number} start The start of the range. - * @param {number} end The end of the range. - * @param {number} step The value to increment or decrement by. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the range of numbers. - */ - function baseRange(start, end, step, fromRight) { - var index = -1, - length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), - result = Array(length); - - while (length--) { - result[fromRight ? length : ++index] = start; - start += step; - } - return result; - } +function dispatchConstant(type, params) { + return function() { + return dispatchEvent(this, type, params); + }; +} - /** - * The base implementation of `_.repeat` which doesn't coerce arguments. - * - * @private - * @param {string} string The string to repeat. - * @param {number} n The number of times to repeat the string. - * @returns {string} Returns the repeated string. - */ - function baseRepeat(string, n) { - var result = ''; - if (!string || n < 1 || n > MAX_SAFE_INTEGER) { - return result; - } - // Leverage the exponentiation by squaring algorithm for a faster repeat. - // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. - do { - if (n % 2) { - result += string; - } - n = nativeFloor(n / 2); - if (n) { - string += string; - } - } while (n); +function dispatchFunction(type, params) { + return function() { + return dispatchEvent(this, type, params.apply(this, arguments)); + }; +} - return result; - } +var selection_dispatch = function(type, params) { + return this.each((typeof params === "function" + ? dispatchFunction + : dispatchConstant)(type, params)); +}; - /** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ - function baseRest(func, start) { - return setToString(overRest(func, start, identity), func + ''); - } +var root = [null]; - /** - * The base implementation of `_.sample`. - * - * @private - * @param {Array|Object} collection The collection to sample. - * @returns {*} Returns the random element. - */ - function baseSample(collection) { - return arraySample(values(collection)); - } +function Selection(groups, parents) { + this._groups = groups; + this._parents = parents; +} - /** - * The base implementation of `_.sampleSize` without param guards. - * - * @private - * @param {Array|Object} collection The collection to sample. - * @param {number} n The number of elements to sample. - * @returns {Array} Returns the random elements. - */ - function baseSampleSize(collection, n) { - var array = values(collection); - return shuffleSelf(array, baseClamp(n, 0, array.length)); - } +function selection() { + return new Selection([[document.documentElement]], root); +} - /** - * The base implementation of `_.set`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ - function baseSet(object, path, value, customizer) { - if (!isObject(object)) { - return object; - } - path = castPath(path, object); - - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = toKey(path[index]), - newValue = value; - - if (index != lastIndex) { - var objValue = nested[key]; - newValue = customizer ? customizer(objValue, key, nested) : undefined; - if (newValue === undefined) { - newValue = isObject(objValue) - ? objValue - : (isIndex(path[index + 1]) ? [] : {}); - } - } - assignValue(nested, key, newValue); - nested = nested[key]; - } - return object; - } +Selection.prototype = selection.prototype = { + constructor: Selection, + select: selection_select, + selectAll: selection_selectAll, + filter: selection_filter, + data: selection_data, + enter: selection_enter, + exit: selection_exit, + merge: selection_merge, + order: selection_order, + sort: selection_sort, + call: selection_call, + nodes: selection_nodes, + node: selection_node, + size: selection_size, + empty: selection_empty, + each: selection_each, + attr: selection_attr, + style: selection_style, + property: selection_property, + classed: selection_classed, + text: selection_text, + html: selection_html, + raise: selection_raise, + lower: selection_lower, + append: selection_append, + insert: selection_insert, + remove: selection_remove, + datum: selection_datum, + on: selection_on, + dispatch: selection_dispatch +}; - /** - * The base implementation of `setData` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var baseSetData = !metaMap ? identity : function(func, data) { - metaMap.set(func, data); - return func; - }; +var d3_select = function(selector) { + return typeof selector === "string" + ? new Selection([[document.querySelector(selector)]], [document.documentElement]) + : new Selection([[selector]], root); +}; - /** - * The base implementation of `setToString` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ - var baseSetToString = !defineProperty ? identity : function(func, string) { - return defineProperty(func, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant(string), - 'writable': true - }); - }; +var d3_selectAll = function(selector) { + return typeof selector === "string" + ? new Selection([document.querySelectorAll(selector)], [document.documentElement]) + : new Selection([selector == null ? [] : selector], root); +}; - /** - * The base implementation of `_.shuffle`. - * - * @private - * @param {Array|Object} collection The collection to shuffle. - * @returns {Array} Returns the new shuffled array. - */ - function baseShuffle(collection) { - return shuffleSelf(values(collection)); +var touch = function(node, touches, identifier) { + if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches; + + for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) { + if ((touch = touches[i]).identifier === identifier) { + return point(node, touch); } + } - /** - * The base implementation of `_.slice` without an iteratee call guard. - * - * @private - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function baseSlice(array, start, end) { - var index = -1, - length = array.length; + return null; +}; - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = end > length ? length : end; - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; +var d3_touches = function(node, touches) { + if (touches == null) touches = sourceEvent().touches; - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; - } + for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) { + points[i] = point(node, touches[i]); + } - /** - * The base implementation of `_.some` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function baseSome(collection, predicate) { - var result; + return points; +}; - baseEach(collection, function(value, index, collection) { - result = predicate(value, index, collection); - return !result; - }); - return !!result; - } +function nopropagation() { + event.stopImmediatePropagation(); +} - /** - * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which - * performs a binary search of `array` to determine the index at which `value` - * should be inserted into `array` in order to maintain its sort order. - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function baseSortedIndex(array, value, retHighest) { - var low = 0, - high = array == null ? low : array.length; - - if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { - while (low < high) { - var mid = (low + high) >>> 1, - computed = array[mid]; - - if (computed !== null && !isSymbol(computed) && - (retHighest ? (computed <= value) : (computed < value))) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - return baseSortedIndexBy(array, value, identity, retHighest); - } +var noevent = function() { + event.preventDefault(); + event.stopImmediatePropagation(); +}; - /** - * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` - * which invokes `iteratee` for `value` and each element of `array` to compute - * their sort ranking. The iteratee is invoked with one argument; (value). - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} iteratee The iteratee invoked per element. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function baseSortedIndexBy(array, value, iteratee, retHighest) { - value = iteratee(value); - - var low = 0, - high = array == null ? 0 : array.length, - valIsNaN = value !== value, - valIsNull = value === null, - valIsSymbol = isSymbol(value), - valIsUndefined = value === undefined; - - while (low < high) { - var mid = nativeFloor((low + high) / 2), - computed = iteratee(array[mid]), - othIsDefined = computed !== undefined, - othIsNull = computed === null, - othIsReflexive = computed === computed, - othIsSymbol = isSymbol(computed); - - if (valIsNaN) { - var setLow = retHighest || othIsReflexive; - } else if (valIsUndefined) { - setLow = othIsReflexive && (retHighest || othIsDefined); - } else if (valIsNull) { - setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); - } else if (valIsSymbol) { - setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); - } else if (othIsNull || othIsSymbol) { - setLow = false; - } else { - setLow = retHighest ? (computed <= value) : (computed < value); - } - if (setLow) { - low = mid + 1; - } else { - high = mid; - } - } - return nativeMin(high, MAX_ARRAY_INDEX); - } +var dragDisable = function(view) { + var root = view.document.documentElement, + selection = d3_select(view).on("dragstart.drag", noevent, true); + if ("onselectstart" in root) { + selection.on("selectstart.drag", noevent, true); + } else { + root.__noselect = root.style.MozUserSelect; + root.style.MozUserSelect = "none"; + } +}; - /** - * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ - function baseSortedUniq(array, iteratee) { - var index = -1, - length = array.length, - resIndex = 0, - result = []; +function yesdrag(view, noclick) { + var root = view.document.documentElement, + selection = d3_select(view).on("dragstart.drag", null); + if (noclick) { + selection.on("click.drag", noevent, true); + setTimeout(function() { selection.on("click.drag", null); }, 0); + } + if ("onselectstart" in root) { + selection.on("selectstart.drag", null); + } else { + root.style.MozUserSelect = root.__noselect; + delete root.__noselect; + } +} - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; +var constant$2 = function(x) { + return function() { + return x; + }; +}; - if (!index || !eq(computed, seen)) { - var seen = computed; - result[resIndex++] = value === 0 ? 0 : value; - } - } - return result; - } +function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) { + this.target = target; + this.type = type; + this.subject = subject; + this.identifier = id; + this.active = active; + this.x = x; + this.y = y; + this.dx = dx; + this.dy = dy; + this._ = dispatch; +} - /** - * The base implementation of `_.toNumber` which doesn't ensure correct - * conversions of binary, hexadecimal, or octal string values. - * - * @private - * @param {*} value The value to process. - * @returns {number} Returns the number. - */ - function baseToNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - return +value; - } +DragEvent.prototype.on = function() { + var value = this._.on.apply(this._, arguments); + return value === this._ ? this : value; +}; - /** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ - function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } +// Ignore right-click, since that should open the context menu. +function defaultFilter$1() { + return !event.button; +} - /** - * The base implementation of `_.uniqBy` without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ - function baseUniq(array, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - length = array.length, - isCommon = true, - result = [], - seen = result; - - if (comparator) { - isCommon = false; - includes = arrayIncludesWith; - } - else if (length >= LARGE_ARRAY_SIZE) { - var set = iteratee ? null : createSet(array); - if (set) { - return setToArray(set); - } - isCommon = false; - includes = cacheHas; - seen = new SetCache; - } - else { - seen = iteratee ? [] : result; - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } - if (iteratee) { - seen.push(computed); - } - result.push(value); - } - else if (!includes(seen, computed, comparator)) { - if (seen !== result) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } +function defaultContainer() { + return this.parentNode; +} - /** - * The base implementation of `_.unset`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The property path to unset. - * @returns {boolean} Returns `true` if the property is deleted, else `false`. - */ - function baseUnset(object, path) { - path = castPath(path, object); - object = parent(object, path); - return object == null || delete object[toKey(last(path))]; - } +function defaultSubject(d) { + return d == null ? {x: event.x, y: event.y} : d; +} - /** - * The base implementation of `_.update`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to update. - * @param {Function} updater The function to produce the updated value. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ - function baseUpdate(object, path, updater, customizer) { - return baseSet(object, path, updater(baseGet(object, path)), customizer); - } +function defaultTouchable() { + return "ontouchstart" in this; +} - /** - * The base implementation of methods like `_.dropWhile` and `_.takeWhile` - * without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to query. - * @param {Function} predicate The function invoked per iteration. - * @param {boolean} [isDrop] Specify dropping elements instead of taking them. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the slice of `array`. - */ - function baseWhile(array, predicate, isDrop, fromRight) { - var length = array.length, - index = fromRight ? length : -1; +var drag = function() { + var filter = defaultFilter$1, + container = defaultContainer, + subject = defaultSubject, + touchable = defaultTouchable, + gestures = {}, + listeners = dispatch("start", "drag", "end"), + active = 0, + mousedownx, + mousedowny, + mousemoving, + touchending, + clickDistance2 = 0; - while ((fromRight ? index-- : ++index < length) && - predicate(array[index], index, array)) {} + function drag(selection) { + selection + .on("mousedown.drag", mousedowned) + .filter(touchable) + .on("touchstart.drag", touchstarted) + .on("touchmove.drag", touchmoved) + .on("touchend.drag touchcancel.drag", touchended) + .style("touch-action", "none") + .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); + } - return isDrop - ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) - : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); - } + function mousedowned() { + if (touchending || !filter.apply(this, arguments)) return; + var gesture = beforestart("mouse", container.apply(this, arguments), d3_mouse, this, arguments); + if (!gesture) return; + d3_select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); + dragDisable(event.view); + nopropagation(); + mousemoving = false; + mousedownx = event.clientX; + mousedowny = event.clientY; + gesture("start"); + } - /** - * The base implementation of `wrapperValue` which returns the result of - * performing a sequence of actions on the unwrapped `value`, where each - * successive action is supplied the return value of the previous. - * - * @private - * @param {*} value The unwrapped value. - * @param {Array} actions Actions to perform to resolve the unwrapped value. - * @returns {*} Returns the resolved value. - */ - function baseWrapperValue(value, actions) { - var result = value; - if (result instanceof LazyWrapper) { - result = result.value(); - } - return arrayReduce(actions, function(result, action) { - return action.func.apply(action.thisArg, arrayPush([result], action.args)); - }, result); + function mousemoved() { + noevent(); + if (!mousemoving) { + var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny; + mousemoving = dx * dx + dy * dy > clickDistance2; } + gestures.mouse("drag"); + } - /** - * The base implementation of methods like `_.xor`, without support for - * iteratee shorthands, that accepts an array of arrays to inspect. - * - * @private - * @param {Array} arrays The arrays to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of values. - */ - function baseXor(arrays, iteratee, comparator) { - var length = arrays.length; - if (length < 2) { - return length ? baseUniq(arrays[0]) : []; - } - var index = -1, - result = Array(length); + function mouseupped() { + d3_select(event.view).on("mousemove.drag mouseup.drag", null); + yesdrag(event.view, mousemoving); + noevent(); + gestures.mouse("end"); + } - while (++index < length) { - var array = arrays[index], - othIndex = -1; + function touchstarted() { + if (!filter.apply(this, arguments)) return; + var touches = event.changedTouches, + c = container.apply(this, arguments), + n = touches.length, i, gesture; - while (++othIndex < length) { - if (othIndex != index) { - result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); - } - } + for (i = 0; i < n; ++i) { + if (gesture = beforestart(touches[i].identifier, c, touch, this, arguments)) { + nopropagation(); + gesture("start"); } - return baseUniq(baseFlatten(result, 1), iteratee, comparator); } + } - /** - * This base implementation of `_.zipObject` which assigns values using `assignFunc`. - * - * @private - * @param {Array} props The property identifiers. - * @param {Array} values The property values. - * @param {Function} assignFunc The function to assign values. - * @returns {Object} Returns the new object. - */ - function baseZipObject(props, values, assignFunc) { - var index = -1, - length = props.length, - valsLength = values.length, - result = {}; - - while (++index < length) { - var value = index < valsLength ? values[index] : undefined; - assignFunc(result, props[index], value); + function touchmoved() { + var touches = event.changedTouches, + n = touches.length, i, gesture; + + for (i = 0; i < n; ++i) { + if (gesture = gestures[touches[i].identifier]) { + noevent(); + gesture("drag"); } - return result; - } - - /** - * Casts `value` to an empty array if it's not an array like object. - * - * @private - * @param {*} value The value to inspect. - * @returns {Array|Object} Returns the cast array-like object. - */ - function castArrayLikeObject(value) { - return isArrayLikeObject(value) ? value : []; } + } - /** - * Casts `value` to `identity` if it's not a function. - * - * @private - * @param {*} value The value to inspect. - * @returns {Function} Returns cast function. - */ - function castFunction(value) { - return typeof value == 'function' ? value : identity; - } + function touchended() { + var touches = event.changedTouches, + n = touches.length, i, gesture; - /** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ - function castPath(value, object) { - if (isArray(value)) { - return value; + if (touchending) clearTimeout(touchending); + touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! + for (i = 0; i < n; ++i) { + if (gesture = gestures[touches[i].identifier]) { + nopropagation(); + gesture("end"); } - return isKey(value, object) ? [value] : stringToPath(toString(value)); } + } - /** - * A `baseRest` alias which can be replaced with `identity` by module - * replacement plugins. - * - * @private - * @type {Function} - * @param {Function} func The function to apply a rest parameter to. - * @returns {Function} Returns the new function. - */ - var castRest = baseRest; + function beforestart(id, container, point, that, args) { + var p = point(container, id), s, dx, dy, + sublisteners = listeners.copy(); - /** - * Casts `array` to a slice if it's needed. - * - * @private - * @param {Array} array The array to inspect. - * @param {number} start The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the cast slice. - */ - function castSlice(array, start, end) { - var length = array.length; - end = end === undefined ? length : end; - return (!start && end >= length) ? array : baseSlice(array, start, end); - } + if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() { + if ((event.subject = s = subject.apply(that, args)) == null) return false; + dx = s.x - p[0] || 0; + dy = s.y - p[1] || 0; + return true; + })) return; - /** - * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout). - * - * @private - * @param {number|Object} id The timer id or timeout object of the timer to clear. - */ - var clearTimeout = ctxClearTimeout || function(id) { - return root.clearTimeout(id); + return function gesture(type) { + var p0 = p, n; + switch (type) { + case "start": gestures[id] = gesture, n = active++; break; + case "end": delete gestures[id], --active; // nobreak + case "drag": p = point(container, id), n = active; break; + } + customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]); }; + } - /** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ - function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); - } - var length = buffer.length, - result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + drag.filter = function(_) { + return arguments.length ? (filter = typeof _ === "function" ? _ : constant$2(!!_), drag) : filter; + }; - buffer.copy(result); - return result; - } + drag.container = function(_) { + return arguments.length ? (container = typeof _ === "function" ? _ : constant$2(_), drag) : container; + }; - /** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ - function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array(result).set(new Uint8Array(arrayBuffer)); - return result; - } + drag.subject = function(_) { + return arguments.length ? (subject = typeof _ === "function" ? _ : constant$2(_), drag) : subject; + }; - /** - * Creates a clone of `dataView`. - * - * @private - * @param {Object} dataView The data view to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned data view. - */ - function cloneDataView(dataView, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; - return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); - } + drag.touchable = function(_) { + return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$2(!!_), drag) : touchable; + }; - /** - * Creates a clone of `map`. - * - * @private - * @param {Object} map The map to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned map. - */ - function cloneMap(map, isDeep, cloneFunc) { - var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map); - return arrayReduce(array, addMapEntry, new map.constructor); - } + drag.on = function() { + var value = listeners.on.apply(listeners, arguments); + return value === listeners ? drag : value; + }; - /** - * Creates a clone of `regexp`. - * - * @private - * @param {Object} regexp The regexp to clone. - * @returns {Object} Returns the cloned regexp. - */ - function cloneRegExp(regexp) { - var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); - result.lastIndex = regexp.lastIndex; - return result; - } + drag.clickDistance = function(_) { + return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2); + }; - /** - * Creates a clone of `set`. - * - * @private - * @param {Object} set The set to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned set. - */ - function cloneSet(set, isDeep, cloneFunc) { - var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set); - return arrayReduce(array, addSetEntry, new set.constructor); - } + return drag; +}; - /** - * Creates a clone of the `symbol` object. - * - * @private - * @param {Object} symbol The symbol object to clone. - * @returns {Object} Returns the cloned symbol object. - */ - function cloneSymbol(symbol) { - return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; - } +var define = function(constructor, factory, prototype) { + constructor.prototype = factory.prototype = prototype; + prototype.constructor = constructor; +}; - /** - * Creates a clone of `typedArray`. - * - * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. - */ - function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); - } +function extend(parent, definition) { + var prototype = Object.create(parent.prototype); + for (var key in definition) prototype[key] = definition[key]; + return prototype; +} - /** - * Compares values to sort them in ascending order. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {number} Returns the sort order indicator for `value`. - */ - function compareAscending(value, other) { - if (value !== other) { - var valIsDefined = value !== undefined, - valIsNull = value === null, - valIsReflexive = value === value, - valIsSymbol = isSymbol(value); - - var othIsDefined = other !== undefined, - othIsNull = other === null, - othIsReflexive = other === other, - othIsSymbol = isSymbol(other); - - if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || - (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || - (valIsNull && othIsDefined && othIsReflexive) || - (!valIsDefined && othIsReflexive) || - !valIsReflexive) { - return 1; - } - if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || - (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || - (othIsNull && valIsDefined && valIsReflexive) || - (!othIsDefined && valIsReflexive) || - !othIsReflexive) { - return -1; - } - } - return 0; - } +function Color() {} - /** - * Used by `_.orderBy` to compare multiple properties of a value to another - * and stable sort them. - * - * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, - * specify an order of "desc" for descending or "asc" for ascending sort order - * of corresponding values. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {boolean[]|string[]} orders The order to sort by for each property. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareMultiple(object, other, orders) { - var index = -1, - objCriteria = object.criteria, - othCriteria = other.criteria, - length = objCriteria.length, - ordersLength = orders.length; - - while (++index < length) { - var result = compareAscending(objCriteria[index], othCriteria[index]); - if (result) { - if (index >= ordersLength) { - return result; - } - var order = orders[index]; - return result * (order == 'desc' ? -1 : 1); - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to provide the same value for - // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 - // for more details. - // - // This also ensures a stable sort in V8 and other engines. - // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. - return object.index - other.index; - } +var darker = 0.7; +var brighter = 1 / darker; - /** - * Creates an array that is the composition of partially applied arguments, - * placeholders, and provided arguments into a single array of arguments. - * - * @private - * @param {Array} args The provided arguments. - * @param {Array} partials The arguments to prepend to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @params {boolean} [isCurried] Specify composing for a curried function. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgs(args, partials, holders, isCurried) { - var argsIndex = -1, - argsLength = args.length, - holdersLength = holders.length, - leftIndex = -1, - leftLength = partials.length, - rangeLength = nativeMax(argsLength - holdersLength, 0), - result = Array(leftLength + rangeLength), - isUncurried = !isCurried; - - while (++leftIndex < leftLength) { - result[leftIndex] = partials[leftIndex]; - } - while (++argsIndex < holdersLength) { - if (isUncurried || argsIndex < argsLength) { - result[holders[argsIndex]] = args[argsIndex]; - } - } - while (rangeLength--) { - result[leftIndex++] = args[argsIndex++]; - } - return result; - } +var reI = "\\s*([+-]?\\d+)\\s*"; +var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*"; +var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*"; +var reHex3 = /^#([0-9a-f]{3})$/; +var reHex6 = /^#([0-9a-f]{6})$/; +var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"); +var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"); +var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"); +var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"); +var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"); +var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); - /** - * This function is like `composeArgs` except that the arguments composition - * is tailored for `_.partialRight`. - * - * @private - * @param {Array} args The provided arguments. - * @param {Array} partials The arguments to append to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @params {boolean} [isCurried] Specify composing for a curried function. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgsRight(args, partials, holders, isCurried) { - var argsIndex = -1, - argsLength = args.length, - holdersIndex = -1, - holdersLength = holders.length, - rightIndex = -1, - rightLength = partials.length, - rangeLength = nativeMax(argsLength - holdersLength, 0), - result = Array(rangeLength + rightLength), - isUncurried = !isCurried; - - while (++argsIndex < rangeLength) { - result[argsIndex] = args[argsIndex]; - } - var offset = argsIndex; - while (++rightIndex < rightLength) { - result[offset + rightIndex] = partials[rightIndex]; - } - while (++holdersIndex < holdersLength) { - if (isUncurried || argsIndex < argsLength) { - result[offset + holders[holdersIndex]] = args[argsIndex++]; - } - } - return result; - } +var named = { + aliceblue: 0xf0f8ff, + antiquewhite: 0xfaebd7, + aqua: 0x00ffff, + aquamarine: 0x7fffd4, + azure: 0xf0ffff, + beige: 0xf5f5dc, + bisque: 0xffe4c4, + black: 0x000000, + blanchedalmond: 0xffebcd, + blue: 0x0000ff, + blueviolet: 0x8a2be2, + brown: 0xa52a2a, + burlywood: 0xdeb887, + cadetblue: 0x5f9ea0, + chartreuse: 0x7fff00, + chocolate: 0xd2691e, + coral: 0xff7f50, + cornflowerblue: 0x6495ed, + cornsilk: 0xfff8dc, + crimson: 0xdc143c, + cyan: 0x00ffff, + darkblue: 0x00008b, + darkcyan: 0x008b8b, + darkgoldenrod: 0xb8860b, + darkgray: 0xa9a9a9, + darkgreen: 0x006400, + darkgrey: 0xa9a9a9, + darkkhaki: 0xbdb76b, + darkmagenta: 0x8b008b, + darkolivegreen: 0x556b2f, + darkorange: 0xff8c00, + darkorchid: 0x9932cc, + darkred: 0x8b0000, + darksalmon: 0xe9967a, + darkseagreen: 0x8fbc8f, + darkslateblue: 0x483d8b, + darkslategray: 0x2f4f4f, + darkslategrey: 0x2f4f4f, + darkturquoise: 0x00ced1, + darkviolet: 0x9400d3, + deeppink: 0xff1493, + deepskyblue: 0x00bfff, + dimgray: 0x696969, + dimgrey: 0x696969, + dodgerblue: 0x1e90ff, + firebrick: 0xb22222, + floralwhite: 0xfffaf0, + forestgreen: 0x228b22, + fuchsia: 0xff00ff, + gainsboro: 0xdcdcdc, + ghostwhite: 0xf8f8ff, + gold: 0xffd700, + goldenrod: 0xdaa520, + gray: 0x808080, + green: 0x008000, + greenyellow: 0xadff2f, + grey: 0x808080, + honeydew: 0xf0fff0, + hotpink: 0xff69b4, + indianred: 0xcd5c5c, + indigo: 0x4b0082, + ivory: 0xfffff0, + khaki: 0xf0e68c, + lavender: 0xe6e6fa, + lavenderblush: 0xfff0f5, + lawngreen: 0x7cfc00, + lemonchiffon: 0xfffacd, + lightblue: 0xadd8e6, + lightcoral: 0xf08080, + lightcyan: 0xe0ffff, + lightgoldenrodyellow: 0xfafad2, + lightgray: 0xd3d3d3, + lightgreen: 0x90ee90, + lightgrey: 0xd3d3d3, + lightpink: 0xffb6c1, + lightsalmon: 0xffa07a, + lightseagreen: 0x20b2aa, + lightskyblue: 0x87cefa, + lightslategray: 0x778899, + lightslategrey: 0x778899, + lightsteelblue: 0xb0c4de, + lightyellow: 0xffffe0, + lime: 0x00ff00, + limegreen: 0x32cd32, + linen: 0xfaf0e6, + magenta: 0xff00ff, + maroon: 0x800000, + mediumaquamarine: 0x66cdaa, + mediumblue: 0x0000cd, + mediumorchid: 0xba55d3, + mediumpurple: 0x9370db, + mediumseagreen: 0x3cb371, + mediumslateblue: 0x7b68ee, + mediumspringgreen: 0x00fa9a, + mediumturquoise: 0x48d1cc, + mediumvioletred: 0xc71585, + midnightblue: 0x191970, + mintcream: 0xf5fffa, + mistyrose: 0xffe4e1, + moccasin: 0xffe4b5, + navajowhite: 0xffdead, + navy: 0x000080, + oldlace: 0xfdf5e6, + olive: 0x808000, + olivedrab: 0x6b8e23, + orange: 0xffa500, + orangered: 0xff4500, + orchid: 0xda70d6, + palegoldenrod: 0xeee8aa, + palegreen: 0x98fb98, + paleturquoise: 0xafeeee, + palevioletred: 0xdb7093, + papayawhip: 0xffefd5, + peachpuff: 0xffdab9, + peru: 0xcd853f, + pink: 0xffc0cb, + plum: 0xdda0dd, + powderblue: 0xb0e0e6, + purple: 0x800080, + rebeccapurple: 0x663399, + red: 0xff0000, + rosybrown: 0xbc8f8f, + royalblue: 0x4169e1, + saddlebrown: 0x8b4513, + salmon: 0xfa8072, + sandybrown: 0xf4a460, + seagreen: 0x2e8b57, + seashell: 0xfff5ee, + sienna: 0xa0522d, + silver: 0xc0c0c0, + skyblue: 0x87ceeb, + slateblue: 0x6a5acd, + slategray: 0x708090, + slategrey: 0x708090, + snow: 0xfffafa, + springgreen: 0x00ff7f, + steelblue: 0x4682b4, + tan: 0xd2b48c, + teal: 0x008080, + thistle: 0xd8bfd8, + tomato: 0xff6347, + turquoise: 0x40e0d0, + violet: 0xee82ee, + wheat: 0xf5deb3, + white: 0xffffff, + whitesmoke: 0xf5f5f5, + yellow: 0xffff00, + yellowgreen: 0x9acd32 +}; - /** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ - function copyArray(source, array) { - var index = -1, - length = source.length; +define(Color, color, { + displayable: function() { + return this.rgb().displayable(); + }, + toString: function() { + return this.rgb() + ""; + } +}); - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; - } +function color(format) { + var m; + format = (format + "").trim().toLowerCase(); + return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00 + : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000 + : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) + : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) + : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) + : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) + : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) + : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) + : named.hasOwnProperty(format) ? rgbn(named[format]) + : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) + : null; +} - /** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ - function copyObject(source, props, object, customizer) { - var isNew = !object; - object || (object = {}); +function rgbn(n) { + return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); +} - var index = -1, - length = props.length; +function rgba(r, g, b, a) { + if (a <= 0) r = g = b = NaN; + return new Rgb(r, g, b, a); +} - while (++index < length) { - var key = props[index]; +function rgbConvert(o) { + if (!(o instanceof Color)) o = color(o); + if (!o) return new Rgb; + o = o.rgb(); + return new Rgb(o.r, o.g, o.b, o.opacity); +} - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; +function rgb(r, g, b, opacity) { + return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); +} - if (newValue === undefined) { - newValue = source[key]; - } - if (isNew) { - baseAssignValue(object, key, newValue); - } else { - assignValue(object, key, newValue); - } - } - return object; - } +function Rgb(r, g, b, opacity) { + this.r = +r; + this.g = +g; + this.b = +b; + this.opacity = +opacity; +} - /** - * Copies own symbols of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ - function copySymbols(source, object) { - return copyObject(source, getSymbols(source), object); - } +define(Rgb, rgb, extend(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); + }, + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); + }, + rgb: function() { + return this; + }, + displayable: function() { + return (0 <= this.r && this.r <= 255) + && (0 <= this.g && this.g <= 255) + && (0 <= this.b && this.b <= 255) + && (0 <= this.opacity && this.opacity <= 1); + }, + toString: function() { + var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); + return (a === 1 ? "rgb(" : "rgba(") + + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " + + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " + + Math.max(0, Math.min(255, Math.round(this.b) || 0)) + + (a === 1 ? ")" : ", " + a + ")"); + } +})); - /** - * Copies own and inherited symbols of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ - function copySymbolsIn(source, object) { - return copyObject(source, getSymbolsIn(source), object); - } +function hsla(h, s, l, a) { + if (a <= 0) h = s = l = NaN; + else if (l <= 0 || l >= 1) h = s = NaN; + else if (s <= 0) h = NaN; + return new Hsl(h, s, l, a); +} - /** - * Creates a function like `_.groupBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} [initializer] The accumulator object initializer. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter, initializer) { - return function(collection, iteratee) { - var func = isArray(collection) ? arrayAggregator : baseAggregator, - accumulator = initializer ? initializer() : {}; +function hslConvert(o) { + if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); + if (!(o instanceof Color)) o = color(o); + if (!o) return new Hsl; + if (o instanceof Hsl) return o; + o = o.rgb(); + var r = o.r / 255, + g = o.g / 255, + b = o.b / 255, + min = Math.min(r, g, b), + max = Math.max(r, g, b), + h = NaN, + s = max - min, + l = (max + min) / 2; + if (s) { + if (r === max) h = (g - b) / s + (g < b) * 6; + else if (g === max) h = (b - r) / s + 2; + else h = (r - g) / s + 4; + s /= l < 0.5 ? max + min : 2 - max - min; + h *= 60; + } else { + s = l > 0 && l < 1 ? 0 : h; + } + return new Hsl(h, s, l, o.opacity); +} - return func(collection, setter, getIteratee(iteratee, 2), accumulator); - }; - } +function hsl(h, s, l, opacity) { + return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); +} - /** - * Creates a function like `_.assign`. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ - function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); - } +function Hsl(h, s, l, opacity) { + this.h = +h; + this.s = +s; + this.l = +l; + this.opacity = +opacity; +} - /** - * Creates a `baseEach` or `baseEachRight` function. - * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseEach(eachFunc, fromRight) { - return function(collection, iteratee) { - if (collection == null) { - return collection; - } - if (!isArrayLike(collection)) { - return eachFunc(collection, iteratee); - } - var length = collection.length, - index = fromRight ? length : -1, - iterable = Object(collection); +define(Hsl, hsl, extend(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Hsl(this.h, this.s, this.l * k, this.opacity); + }, + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Hsl(this.h, this.s, this.l * k, this.opacity); + }, + rgb: function() { + var h = this.h % 360 + (this.h < 0) * 360, + s = isNaN(h) || isNaN(this.s) ? 0 : this.s, + l = this.l, + m2 = l + (l < 0.5 ? l : 1 - l) * s, + m1 = 2 * l - m2; + return new Rgb( + hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), + hsl2rgb(h, m1, m2), + hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), + this.opacity + ); + }, + displayable: function() { + return (0 <= this.s && this.s <= 1 || isNaN(this.s)) + && (0 <= this.l && this.l <= 1) + && (0 <= this.opacity && this.opacity <= 1); + } +})); - while ((fromRight ? index-- : ++index < length)) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - }; - } +/* From FvD 13.37, CSS Color Module Level 3 */ +function hsl2rgb(h, m1, m2) { + return (h < 60 ? m1 + (m2 - m1) * h / 60 + : h < 180 ? m2 + : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 + : m1) * 255; +} - /** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; - } +var deg2rad = Math.PI / 180; +var rad2deg = 180 / Math.PI; - /** - * Creates a function that wraps `func` to invoke it with the optional `this` - * binding of `thisArg`. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createBind(func, bitmask, thisArg) { - var isBind = bitmask & WRAP_BIND_FLAG, - Ctor = createCtor(func); - - function wrapper() { - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(isBind ? thisArg : this, arguments); - } - return wrapper; - } +var Kn = 18; +var Xn = 0.950470; +var Yn = 1; +var Zn = 1.088830; +var t0 = 4 / 29; +var t1 = 6 / 29; +var t2 = 3 * t1 * t1; +var t3 = t1 * t1 * t1; - /** - * Creates a function like `_.lowerFirst`. - * - * @private - * @param {string} methodName The name of the `String` case method to use. - * @returns {Function} Returns the new case function. - */ - function createCaseFirst(methodName) { - return function(string) { - string = toString(string); +function labConvert(o) { + if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity); + if (o instanceof Hcl) { + var h = o.h * deg2rad; + return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity); + } + if (!(o instanceof Rgb)) o = rgbConvert(o); + var b = rgb2xyz(o.r), + a = rgb2xyz(o.g), + l = rgb2xyz(o.b), + x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn), + y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn), + z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn); + return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); +} - var strSymbols = hasUnicode(string) - ? stringToArray(string) - : undefined; +function lab(l, a, b, opacity) { + return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity); +} - var chr = strSymbols - ? strSymbols[0] - : string.charAt(0); +function Lab(l, a, b, opacity) { + this.l = +l; + this.a = +a; + this.b = +b; + this.opacity = +opacity; +} - var trailing = strSymbols - ? castSlice(strSymbols, 1).join('') - : string.slice(1); +define(Lab, lab, extend(Color, { + brighter: function(k) { + return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); + }, + darker: function(k) { + return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); + }, + rgb: function() { + var y = (this.l + 16) / 116, + x = isNaN(this.a) ? y : y + this.a / 500, + z = isNaN(this.b) ? y : y - this.b / 200; + y = Yn * lab2xyz(y); + x = Xn * lab2xyz(x); + z = Zn * lab2xyz(z); + return new Rgb( + xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB + xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z), + xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z), + this.opacity + ); + } +})); - return chr[methodName]() + trailing; - }; - } +function xyz2lab(t) { + return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0; +} - /** - * Creates a function like `_.camelCase`. - * - * @private - * @param {Function} callback The function to combine each word. - * @returns {Function} Returns the new compounder function. - */ - function createCompounder(callback) { - return function(string) { - return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); - }; - } +function lab2xyz(t) { + return t > t1 ? t * t * t : t2 * (t - t0); +} - /** - * Creates a function that produces an instance of `Ctor` regardless of - * whether it was invoked as part of a `new` expression or by `call` or `apply`. - * - * @private - * @param {Function} Ctor The constructor to wrap. - * @returns {Function} Returns the new wrapped function. - */ - function createCtor(Ctor) { - return function() { - // Use a `switch` statement to work with class constructors. See - // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist - // for more details. - var args = arguments; - switch (args.length) { - case 0: return new Ctor; - case 1: return new Ctor(args[0]); - case 2: return new Ctor(args[0], args[1]); - case 3: return new Ctor(args[0], args[1], args[2]); - case 4: return new Ctor(args[0], args[1], args[2], args[3]); - case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); - case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); - case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - } - var thisBinding = baseCreate(Ctor.prototype), - result = Ctor.apply(thisBinding, args); - - // Mimic the constructor's `return` behavior. - // See https://es5.github.io/#x13.2.2 for more details. - return isObject(result) ? result : thisBinding; - }; - } +function xyz2rgb(x) { + return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); +} - /** - * Creates a function that wraps `func` to enable currying. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {number} arity The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createCurry(func, bitmask, arity) { - var Ctor = createCtor(func); - - function wrapper() { - var length = arguments.length, - args = Array(length), - index = length, - placeholder = getHolder(wrapper); - - while (index--) { - args[index] = arguments[index]; - } - var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) - ? [] - : replaceHolders(args, placeholder); - - length -= holders.length; - if (length < arity) { - return createRecurry( - func, bitmask, createHybrid, wrapper.placeholder, undefined, - args, holders, undefined, undefined, arity - length); - } - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return apply(fn, this, args); - } - return wrapper; - } +function rgb2xyz(x) { + return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); +} - /** - * Creates a `_.find` or `_.findLast` function. - * - * @private - * @param {Function} findIndexFunc The function to find the collection index. - * @returns {Function} Returns the new find function. - */ - function createFind(findIndexFunc) { - return function(collection, predicate, fromIndex) { - var iterable = Object(collection); - if (!isArrayLike(collection)) { - var iteratee = getIteratee(predicate, 3); - collection = keys(collection); - predicate = function(key) { return iteratee(iterable[key], key, iterable); }; - } - var index = findIndexFunc(collection, predicate, fromIndex); - return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; - }; - } +function hclConvert(o) { + if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity); + if (!(o instanceof Lab)) o = labConvert(o); + var h = Math.atan2(o.b, o.a) * rad2deg; + return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); +} - /** - * Creates a `_.flow` or `_.flowRight` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new flow function. - */ - function createFlow(fromRight) { - return flatRest(function(funcs) { - var length = funcs.length, - index = length, - prereq = LodashWrapper.prototype.thru; - - if (fromRight) { - funcs.reverse(); - } - while (index--) { - var func = funcs[index]; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (prereq && !wrapper && getFuncName(func) == 'wrapper') { - var wrapper = new LodashWrapper([], true); - } - } - index = wrapper ? index : length; - while (++index < length) { - func = funcs[index]; +function hcl(h, c, l, opacity) { + return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity); +} - var funcName = getFuncName(func), - data = funcName == 'wrapper' ? getData(func) : undefined; +function Hcl(h, c, l, opacity) { + this.h = +h; + this.c = +c; + this.l = +l; + this.opacity = +opacity; +} - if (data && isLaziable(data[0]) && - data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && - !data[4].length && data[9] == 1 - ) { - wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); - } else { - wrapper = (func.length == 1 && isLaziable(func)) - ? wrapper[funcName]() - : wrapper.thru(func); - } - } - return function() { - var args = arguments, - value = args[0]; +define(Hcl, hcl, extend(Color, { + brighter: function(k) { + return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity); + }, + darker: function(k) { + return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity); + }, + rgb: function() { + return labConvert(this).rgb(); + } +})); - if (wrapper && args.length == 1 && isArray(value)) { - return wrapper.plant(value).value(); - } - var index = 0, - result = length ? funcs[index].apply(this, args) : value; +var A = -0.14861; +var B = +1.78277; +var C = -0.29227; +var D = -0.90649; +var E = +1.97294; +var ED = E * D; +var EB = E * B; +var BC_DA = B * C - D * A; - while (++index < length) { - result = funcs[index].call(this, result); - } - return result; - }; - }); - } +function cubehelixConvert(o) { + if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); + if (!(o instanceof Rgb)) o = rgbConvert(o); + var r = o.r / 255, + g = o.g / 255, + b = o.b / 255, + l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), + bl = b - l, + k = (E * (g - l) - C * bl) / D, + s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 + h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN; + return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); +} - /** - * Creates a function that wraps `func` to invoke it with optional `this` - * binding of `thisArg`, partial application, and currying. - * - * @private - * @param {Function|string} func The function or method name to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to - * the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [partialsRight] The arguments to append to those provided - * to the new function. - * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { - var isAry = bitmask & WRAP_ARY_FLAG, - isBind = bitmask & WRAP_BIND_FLAG, - isBindKey = bitmask & WRAP_BIND_KEY_FLAG, - isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), - isFlip = bitmask & WRAP_FLIP_FLAG, - Ctor = isBindKey ? undefined : createCtor(func); - - function wrapper() { - var length = arguments.length, - args = Array(length), - index = length; - - while (index--) { - args[index] = arguments[index]; - } - if (isCurried) { - var placeholder = getHolder(wrapper), - holdersCount = countHolders(args, placeholder); - } - if (partials) { - args = composeArgs(args, partials, holders, isCurried); - } - if (partialsRight) { - args = composeArgsRight(args, partialsRight, holdersRight, isCurried); - } - length -= holdersCount; - if (isCurried && length < arity) { - var newHolders = replaceHolders(args, placeholder); - return createRecurry( - func, bitmask, createHybrid, wrapper.placeholder, thisArg, - args, newHolders, argPos, ary, arity - length - ); - } - var thisBinding = isBind ? thisArg : this, - fn = isBindKey ? thisBinding[func] : func; +function cubehelix(h, s, l, opacity) { + return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); +} - length = args.length; - if (argPos) { - args = reorder(args, argPos); - } else if (isFlip && length > 1) { - args.reverse(); - } - if (isAry && ary < length) { - args.length = ary; - } - if (this && this !== root && this instanceof wrapper) { - fn = Ctor || createCtor(fn); - } - return fn.apply(thisBinding, args); - } - return wrapper; - } +function Cubehelix(h, s, l, opacity) { + this.h = +h; + this.s = +s; + this.l = +l; + this.opacity = +opacity; +} - /** - * Creates a function like `_.invertBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} toIteratee The function to resolve iteratees. - * @returns {Function} Returns the new inverter function. - */ - function createInverter(setter, toIteratee) { - return function(object, iteratee) { - return baseInverter(object, setter, toIteratee(iteratee), {}); - }; - } +define(Cubehelix, cubehelix, extend(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Cubehelix(this.h, this.s, this.l * k, this.opacity); + }, + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Cubehelix(this.h, this.s, this.l * k, this.opacity); + }, + rgb: function() { + var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad, + l = +this.l, + a = isNaN(this.s) ? 0 : this.s * l * (1 - l), + cosh = Math.cos(h), + sinh = Math.sin(h); + return new Rgb( + 255 * (l + a * (A * cosh + B * sinh)), + 255 * (l + a * (C * cosh + D * sinh)), + 255 * (l + a * (E * cosh)), + this.opacity + ); + } +})); - /** - * Creates a function that performs a mathematical operation on two values. - * - * @private - * @param {Function} operator The function to perform the operation. - * @param {number} [defaultValue] The value used for `undefined` arguments. - * @returns {Function} Returns the new mathematical operation function. - */ - function createMathOperation(operator, defaultValue) { - return function(value, other) { - var result; - if (value === undefined && other === undefined) { - return defaultValue; - } - if (value !== undefined) { - result = value; - } - if (other !== undefined) { - if (result === undefined) { - return other; - } - if (typeof value == 'string' || typeof other == 'string') { - value = baseToString(value); - other = baseToString(other); - } else { - value = baseToNumber(value); - other = baseToNumber(other); - } - result = operator(value, other); - } - return result; - }; - } +function basis(t1, v0, v1, v2, v3) { + var t2 = t1 * t1, t3 = t2 * t1; + return ((1 - 3 * t1 + 3 * t2 - t3) * v0 + + (4 - 6 * t2 + 3 * t3) * v1 + + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 + + t3 * v3) / 6; +} - /** - * Creates a function like `_.over`. - * - * @private - * @param {Function} arrayFunc The function to iterate over iteratees. - * @returns {Function} Returns the new over function. - */ - function createOver(arrayFunc) { - return flatRest(function(iteratees) { - iteratees = arrayMap(iteratees, baseUnary(getIteratee())); - return baseRest(function(args) { - var thisArg = this; - return arrayFunc(iteratees, function(iteratee) { - return apply(iteratee, thisArg, args); - }); - }); - }); - } +var basis$1 = function(values) { + var n = values.length - 1; + return function(t) { + var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n), + v1 = values[i], + v2 = values[i + 1], + v0 = i > 0 ? values[i - 1] : 2 * v1 - v2, + v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1; + return basis((t - i / n) * n, v0, v1, v2, v3); + }; +}; - /** - * Creates the padding for `string` based on `length`. The `chars` string - * is truncated if the number of characters exceeds `length`. - * - * @private - * @param {number} length The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padding for `string`. - */ - function createPadding(length, chars) { - chars = chars === undefined ? ' ' : baseToString(chars); +var basisClosed = function(values) { + var n = values.length; + return function(t) { + var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n), + v0 = values[(i + n - 1) % n], + v1 = values[i % n], + v2 = values[(i + 1) % n], + v3 = values[(i + 2) % n]; + return basis((t - i / n) * n, v0, v1, v2, v3); + }; +}; - var charsLength = chars.length; - if (charsLength < 2) { - return charsLength ? baseRepeat(chars, length) : chars; - } - var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); - return hasUnicode(chars) - ? castSlice(stringToArray(result), 0, length).join('') - : result.slice(0, length); - } +var constant$3 = function(x) { + return function() { + return x; + }; +}; - /** - * Creates a function that wraps `func` to invoke it with the `this` binding - * of `thisArg` and `partials` prepended to the arguments it receives. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} partials The arguments to prepend to those provided to - * the new function. - * @returns {Function} Returns the new wrapped function. - */ - function createPartial(func, bitmask, thisArg, partials) { - var isBind = bitmask & WRAP_BIND_FLAG, - Ctor = createCtor(func); +function linear(a, d) { + return function(t) { + return a + t * d; + }; +} - function wrapper() { - var argsIndex = -1, - argsLength = arguments.length, - leftIndex = -1, - leftLength = partials.length, - args = Array(leftLength + argsLength), - fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; +function exponential(a, b, y) { + return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { + return Math.pow(a + t * b, y); + }; +} - while (++leftIndex < leftLength) { - args[leftIndex] = partials[leftIndex]; - } - while (argsLength--) { - args[leftIndex++] = arguments[++argsIndex]; - } - return apply(fn, isBind ? thisArg : this, args); - } - return wrapper; - } +function hue(a, b) { + var d = b - a; + return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a); +} - /** - * Creates a `_.range` or `_.rangeRight` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new range function. - */ - function createRange(fromRight) { - return function(start, end, step) { - if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { - end = step = undefined; - } - // Ensure the sign of `-0` is preserved. - start = toFinite(start); - if (end === undefined) { - end = start; - start = 0; - } else { - end = toFinite(end); - } - step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); - return baseRange(start, end, step, fromRight); - }; - } +function gamma(y) { + return (y = +y) === 1 ? nogamma : function(a, b) { + return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a); + }; +} - /** - * Creates a function that performs a relational operation on two values. - * - * @private - * @param {Function} operator The function to perform the operation. - * @returns {Function} Returns the new relational operation function. - */ - function createRelationalOperation(operator) { - return function(value, other) { - if (!(typeof value == 'string' && typeof other == 'string')) { - value = toNumber(value); - other = toNumber(other); - } - return operator(value, other); - }; - } +function nogamma(a, b) { + var d = b - a; + return d ? linear(a, d) : constant$3(isNaN(a) ? b : a); +} - /** - * Creates a function that wraps `func` to continue currying. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {Function} wrapFunc The function to create the `func` wrapper. - * @param {*} placeholder The placeholder value. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to - * the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { - var isCurry = bitmask & WRAP_CURRY_FLAG, - newHolders = isCurry ? holders : undefined, - newHoldersRight = isCurry ? undefined : holders, - newPartials = isCurry ? partials : undefined, - newPartialsRight = isCurry ? undefined : partials; - - bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG); - bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); - - if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { - bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); - } - var newData = [ - func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, - newHoldersRight, argPos, ary, arity - ]; +var d3_interpolateRgb = (function rgbGamma(y) { + var color$$1 = gamma(y); - var result = wrapFunc.apply(undefined, newData); - if (isLaziable(func)) { - setData(result, newData); - } - result.placeholder = placeholder; - return setWrapToString(result, func, bitmask); - } + function rgb$$1(start, end) { + var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r), + g = color$$1(start.g, end.g), + b = color$$1(start.b, end.b), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.r = r(t); + start.g = g(t); + start.b = b(t); + start.opacity = opacity(t); + return start + ""; + }; + } - /** - * Creates a function like `_.round`. - * - * @private - * @param {string} methodName The name of the `Math` method to use when rounding. - * @returns {Function} Returns the new round function. - */ - function createRound(methodName) { - var func = Math[methodName]; - return function(number, precision) { - number = toNumber(number); - precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); - if (precision) { - // Shift with exponential notation to avoid floating-point issues. - // See [MDN](https://mdn.io/round#Examples) for more details. - var pair = (toString(number) + 'e').split('e'), - value = func(pair[0] + 'e' + (+pair[1] + precision)); - - pair = (toString(value) + 'e').split('e'); - return +(pair[0] + 'e' + (+pair[1] - precision)); - } - return func(number); - }; - } + rgb$$1.gamma = rgbGamma; - /** - * Creates a set object of `values`. - * - * @private - * @param {Array} values The values to add to the set. - * @returns {Object} Returns the new set. - */ - var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { - return new Set(values); - }; + return rgb$$1; +})(1); - /** - * Creates a `_.toPairs` or `_.toPairsIn` function. - * - * @private - * @param {Function} keysFunc The function to get the keys of a given object. - * @returns {Function} Returns the new pairs function. - */ - function createToPairs(keysFunc) { - return function(object) { - var tag = getTag(object); - if (tag == mapTag) { - return mapToArray(object); - } - if (tag == setTag) { - return setToPairs(object); - } - return baseToPairs(object, keysFunc(object)); - }; +function rgbSpline(spline) { + return function(colors) { + var n = colors.length, + r = new Array(n), + g = new Array(n), + b = new Array(n), + i, color$$1; + for (i = 0; i < n; ++i) { + color$$1 = rgb(colors[i]); + r[i] = color$$1.r || 0; + g[i] = color$$1.g || 0; + b[i] = color$$1.b || 0; } + r = spline(r); + g = spline(g); + b = spline(b); + color$$1.opacity = 1; + return function(t) { + color$$1.r = r(t); + color$$1.g = g(t); + color$$1.b = b(t); + return color$$1 + ""; + }; + }; +} - /** - * Creates a function that either curries or invokes `func` with optional - * `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to wrap. - * @param {number} bitmask The bitmask flags. - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` or `_.curryRight` of a bound function - * 8 - `_.curry` - * 16 - `_.curryRight` - * 32 - `_.partial` - * 64 - `_.partialRight` - * 128 - `_.rearg` - * 256 - `_.ary` - * 512 - `_.flip` - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to be partially applied. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { - var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; - if (!isBindKey && typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - var length = partials ? partials.length : 0; - if (!length) { - bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); - partials = holders = undefined; - } - ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); - arity = arity === undefined ? arity : toInteger(arity); - length -= holders ? holders.length : 0; - - if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { - var partialsRight = partials, - holdersRight = holders; +var rgbBasis = rgbSpline(basis$1); +var rgbBasisClosed = rgbSpline(basisClosed); - partials = holders = undefined; - } - var data = isBindKey ? undefined : getData(func); +var array$1 = function(a, b) { + var nb = b ? b.length : 0, + na = a ? Math.min(nb, a.length) : 0, + x = new Array(nb), + c = new Array(nb), + i; - var newData = [ - func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, - argPos, ary, arity - ]; + for (i = 0; i < na; ++i) x[i] = d3_interpolate(a[i], b[i]); + for (; i < nb; ++i) c[i] = b[i]; - if (data) { - mergeData(newData, data); - } - func = newData[0]; - bitmask = newData[1]; - thisArg = newData[2]; - partials = newData[3]; - holders = newData[4]; - arity = newData[9] = newData[9] === undefined - ? (isBindKey ? 0 : func.length) - : nativeMax(newData[9] - length, 0); - - if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { - bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); - } - if (!bitmask || bitmask == WRAP_BIND_FLAG) { - var result = createBind(func, bitmask, thisArg); - } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { - result = createCurry(func, bitmask, arity); - } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { - result = createPartial(func, bitmask, thisArg, partials); - } else { - result = createHybrid.apply(undefined, newData); - } - var setter = data ? baseSetData : setData; - return setWrapToString(setter(result, newData), func, bitmask); - } + return function(t) { + for (i = 0; i < na; ++i) c[i] = x[i](t); + return c; + }; +}; - /** - * Used by `_.defaults` to customize its `_.assignIn` use to assign properties - * of source objects to the destination object for all destination properties - * that resolve to `undefined`. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to assign. - * @param {Object} object The parent object of `objValue`. - * @returns {*} Returns the value to assign. - */ - function customDefaultsAssignIn(objValue, srcValue, key, object) { - if (objValue === undefined || - (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { - return srcValue; - } - return objValue; - } +var date = function(a, b) { + var d = new Date; + return a = +a, b -= a, function(t) { + return d.setTime(a + b * t), d; + }; +}; - /** - * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source - * objects into destination objects that are passed thru. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to merge. - * @param {Object} object The parent object of `objValue`. - * @param {Object} source The parent object of `srcValue`. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - * @returns {*} Returns the value to assign. - */ - function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { - if (isObject(objValue) && isObject(srcValue)) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, objValue); - baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); - stack['delete'](srcValue); - } - return objValue; - } +var d3_interpolateNumber = function(a, b) { + return a = +a, b -= a, function(t) { + return a + b * t; + }; +}; - /** - * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain - * objects. - * - * @private - * @param {*} value The value to inspect. - * @param {string} key The key of the property to inspect. - * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. - */ - function customOmitClone(value) { - return isPlainObject(value) ? undefined : value; - } +var object = function(a, b) { + var i = {}, + c = {}, + k; - /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ - function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - arrLength = array.length, - othLength = other.length; + if (a === null || typeof a !== "object") a = {}; + if (b === null || typeof b !== "object") b = {}; - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(array); - if (stacked && stack.get(other)) { - return stacked == other; - } - var index = -1, - result = true, - seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; - - stack.set(array, other); - stack.set(other, array); - - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, arrValue, index, other, array, stack) - : customizer(arrValue, othValue, index, array, other, stack); - } - if (compared !== undefined) { - if (compared) { - continue; - } - result = false; - break; - } - // Recursively compare arrays (susceptible to call stack limits). - if (seen) { - if (!arraySome(other, function(othValue, othIndex) { - if (!cacheHas(seen, othIndex) && - (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { - return seen.push(othIndex); - } - })) { - result = false; - break; - } - } else if (!( - arrValue === othValue || - equalFunc(arrValue, othValue, bitmask, customizer, stack) - )) { - result = false; - break; - } - } - stack['delete'](array); - stack['delete'](other); - return result; + for (k in b) { + if (k in a) { + i[k] = d3_interpolate(a[k], b[k]); + } else { + c[k] = b[k]; } + } - /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { - switch (tag) { - case dataViewTag: - if ((object.byteLength != other.byteLength) || - (object.byteOffset != other.byteOffset)) { - return false; - } - object = object.buffer; - other = other.buffer; - - case arrayBufferTag: - if ((object.byteLength != other.byteLength) || - !equalFunc(new Uint8Array(object), new Uint8Array(other))) { - return false; - } - return true; - - case boolTag: - case dateTag: - case numberTag: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq(+object, +other); - - case errorTag: - return object.name == other.name && object.message == other.message; + return function(t) { + for (k in i) c[k] = i[k](t); + return c; + }; +}; - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring - // for more details. - return object == (other + ''); +var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; +var reB = new RegExp(reA.source, "g"); - case mapTag: - var convert = mapToArray; +function zero(b) { + return function() { + return b; + }; +} - case setTag: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG; - convert || (convert = setToArray); +function one(b) { + return function(t) { + return b(t) + ""; + }; +} - if (object.size != other.size && !isPartial) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked) { - return stacked == other; - } - bitmask |= COMPARE_UNORDERED_FLAG; +var interpolateString = function(a, b) { + var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b + am, // current match in a + bm, // current match in b + bs, // string preceding current number in b, if any + i = -1, // index in s + s = [], // string constants and placeholders + q = []; // number interpolators - // Recursively compare objects (susceptible to call stack limits). - stack.set(object, other); - var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); - stack['delete'](object); - return result; + // Coerce inputs to strings. + a = a + "", b = b + ""; - case symbolTag: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } - } - return false; + // Interpolate pairs of numbers in a & b. + while ((am = reA.exec(a)) + && (bm = reB.exec(b))) { + if ((bs = bm.index) > bi) { // a string precedes the next number in b + bs = b.slice(bi, bs); + if (s[i]) s[i] += bs; // coalesce with previous string + else s[++i] = bs; + } + if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match + if (s[i]) s[i] += bm; // coalesce with previous string + else s[++i] = bm; + } else { // interpolate non-matching numbers + s[++i] = null; + q.push({i: i, x: d3_interpolateNumber(am, bm)}); } + bi = reB.lastIndex; + } - /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - objProps = getAllKeys(object), - objLength = objProps.length, - othProps = getAllKeys(other), - othLength = othProps.length; - - if (objLength != othLength && !isPartial) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { - return false; - } - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked && stack.get(other)) { - return stacked == other; - } - var result = true; - stack.set(object, other); - stack.set(other, object); - - var skipCtor = isPartial; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, objValue, key, other, object, stack) - : customizer(objValue, othValue, key, object, other, stack); - } - // Recursively compare objects (susceptible to call stack limits). - if (!(compared === undefined - ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) - : compared - )) { - result = false; - break; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; - } - } - stack['delete'](object); - stack['delete'](other); - return result; - } + // Add remains of b. + if (bi < b.length) { + bs = b.slice(bi); + if (s[i]) s[i] += bs; // coalesce with previous string + else s[++i] = bs; + } - /** - * A specialized version of `baseRest` which flattens the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @returns {Function} Returns the new function. - */ - function flatRest(func) { - return setToString(overRest(func, undefined, flatten), func + ''); - } + // Special optimization for only a single match. + // Otherwise, interpolate each of the numbers and rejoin the string. + return s.length < 2 ? (q[0] + ? one(q[0].x) + : zero(b)) + : (b = q.length, function(t) { + for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }); +}; - /** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); - } +var d3_interpolate = function(a, b) { + var t = typeof b, c; + return b == null || t === "boolean" ? constant$3(b) + : (t === "number" ? d3_interpolateNumber + : t === "string" ? ((c = color(b)) ? (b = c, d3_interpolateRgb) : interpolateString) + : b instanceof color ? d3_interpolateRgb + : b instanceof Date ? date + : Array.isArray(b) ? array$1 + : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object + : d3_interpolateNumber)(a, b); +}; - /** - * Creates an array of own and inherited enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeysIn(object) { - return baseGetAllKeys(object, keysIn, getSymbolsIn); - } +var interpolateRound = function(a, b) { + return a = +a, b -= a, function(t) { + return Math.round(a + b * t); + }; +}; - /** - * Gets metadata for `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {*} Returns the metadata for `func`. - */ - var getData = !metaMap ? noop : function(func) { - return metaMap.get(func); - }; +var degrees = 180 / Math.PI; - /** - * Gets the name of `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {string} Returns the function name. - */ - function getFuncName(func) { - var result = (func.name + ''), - array = realNames[result], - length = hasOwnProperty.call(realNames, result) ? array.length : 0; +var identity$2 = { + translateX: 0, + translateY: 0, + rotate: 0, + skewX: 0, + scaleX: 1, + scaleY: 1 +}; - while (length--) { - var data = array[length], - otherFunc = data.func; - if (otherFunc == null || otherFunc == func) { - return data.name; - } - } - return result; - } +var decompose = function(a, b, c, d, e, f) { + var scaleX, scaleY, skewX; + if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; + if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; + if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; + if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; + return { + translateX: e, + translateY: f, + rotate: Math.atan2(b, a) * degrees, + skewX: Math.atan(skewX) * degrees, + scaleX: scaleX, + scaleY: scaleY + }; +}; - /** - * Gets the argument placeholder value for `func`. - * - * @private - * @param {Function} func The function to inspect. - * @returns {*} Returns the placeholder value. - */ - function getHolder(func) { - var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; - return object.placeholder; - } +var cssNode; +var cssRoot; +var cssView; +var svgNode; - /** - * Gets the appropriate "iteratee" function. If `_.iteratee` is customized, - * this function returns the custom method, otherwise it returns `baseIteratee`. - * If arguments are provided, the chosen function is invoked with them and - * its result is returned. - * - * @private - * @param {*} [value] The value to convert to an iteratee. - * @param {number} [arity] The arity of the created iteratee. - * @returns {Function} Returns the chosen function or its result. - */ - function getIteratee() { - var result = lodash.iteratee || iteratee; - result = result === iteratee ? baseIteratee : result; - return arguments.length ? result(arguments[0], arguments[1]) : result; - } +function parseCss(value) { + if (value === "none") return identity$2; + if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView; + cssNode.style.transform = value; + value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform"); + cssRoot.removeChild(cssNode); + value = value.slice(7, -1).split(","); + return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]); +} - /** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ - function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; - } +function parseSvg(value) { + if (value == null) return identity$2; + if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); + svgNode.setAttribute("transform", value); + if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2; + value = value.matrix; + return decompose(value.a, value.b, value.c, value.d, value.e, value.f); +} - /** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ - function getMatchData(object) { - var result = keys(object), - length = result.length; +function interpolateTransform(parse, pxComma, pxParen, degParen) { - while (length--) { - var key = result[length], - value = object[key]; + function pop(s) { + return s.length ? s.pop() + " " : ""; + } - result[length] = [key, value, isStrictComparable(value)]; - } - return result; + function translate(xa, ya, xb, yb, s, q) { + if (xa !== xb || ya !== yb) { + var i = s.push("translate(", null, pxComma, null, pxParen); + q.push({i: i - 4, x: d3_interpolateNumber(xa, xb)}, {i: i - 2, x: d3_interpolateNumber(ya, yb)}); + } else if (xb || yb) { + s.push("translate(" + xb + pxComma + yb + pxParen); } + } - /** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ - function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; + function rotate(a, b, s, q) { + if (a !== b) { + if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path + q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: d3_interpolateNumber(a, b)}); + } else if (b) { + s.push(pop(s) + "rotate(" + b + degParen); } + } - /** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ - function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; + function skewX(a, b, s, q) { + if (a !== b) { + q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: d3_interpolateNumber(a, b)}); + } else if (b) { + s.push(pop(s) + "skewX(" + b + degParen); + } + } - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; + function scale(xa, ya, xb, yb, s, q) { + if (xa !== xb || ya !== yb) { + var i = s.push(pop(s) + "scale(", null, ",", null, ")"); + q.push({i: i - 4, x: d3_interpolateNumber(xa, xb)}, {i: i - 2, x: d3_interpolateNumber(ya, yb)}); + } else if (xb !== 1 || yb !== 1) { + s.push(pop(s) + "scale(" + xb + "," + yb + ")"); } + } - /** - * Creates an array of the own enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbols = !nativeGetSymbols ? stubArray : function(object) { - if (object == null) { - return []; - } - object = Object(object); - return arrayFilter(nativeGetSymbols(object), function(symbol) { - return propertyIsEnumerable.call(object, symbol); - }); + return function(a, b) { + var s = [], // string constants and placeholders + q = []; // number interpolators + a = parse(a), b = parse(b); + translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); + rotate(a.rotate, b.rotate, s, q); + skewX(a.skewX, b.skewX, s, q); + scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); + a = b = null; // gc + return function(t) { + var i = -1, n = q.length, o; + while (++i < n) s[(o = q[i]).i] = o.x(t); + return s.join(""); }; + }; +} - /** - * Creates an array of the own and inherited enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { - var result = []; - while (object) { - arrayPush(result, getSymbols(object)); - object = getPrototype(object); - } - return result; - }; +var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); +var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); - /** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - var getTag = baseGetTag; - - // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. - if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || - (Map && getTag(new Map) != mapTag) || - (Promise && getTag(Promise.resolve()) != promiseTag) || - (Set && getTag(new Set) != setTag) || - (WeakMap && getTag(new WeakMap) != weakMapTag)) { - getTag = function(value) { - var result = baseGetTag(value), - Ctor = result == objectTag ? value.constructor : undefined, - ctorString = Ctor ? toSource(Ctor) : ''; - - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag; - case mapCtorString: return mapTag; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag; - case weakMapCtorString: return weakMapTag; - } - } - return result; - }; - } +var rho = Math.SQRT2; +var rho2 = 2; +var rho4 = 4; +var epsilon2 = 1e-12; - /** - * Gets the view, applying any `transforms` to the `start` and `end` positions. - * - * @private - * @param {number} start The start of the view. - * @param {number} end The end of the view. - * @param {Array} transforms The transformations to apply to the view. - * @returns {Object} Returns an object containing the `start` and `end` - * positions of the view. - */ - function getView(start, end, transforms) { - var index = -1, - length = transforms.length; +function cosh(x) { + return ((x = Math.exp(x)) + 1 / x) / 2; +} - while (++index < length) { - var data = transforms[index], - size = data.size; +function sinh(x) { + return ((x = Math.exp(x)) - 1 / x) / 2; +} - switch (data.type) { - case 'drop': start += size; break; - case 'dropRight': end -= size; break; - case 'take': end = nativeMin(end, start + size); break; - case 'takeRight': start = nativeMax(start, end - size); break; - } - } - return { 'start': start, 'end': end }; - } +function tanh(x) { + return ((x = Math.exp(2 * x)) - 1) / (x + 1); +} - /** - * Extracts wrapper details from the `source` body comment. - * - * @private - * @param {string} source The source to inspect. - * @returns {Array} Returns the wrapper details. - */ - function getWrapDetails(source) { - var match = source.match(reWrapDetails); - return match ? match[1].split(reSplitDetails) : []; - } +// p0 = [ux0, uy0, w0] +// p1 = [ux1, uy1, w1] +var interpolateZoom = function(p0, p1) { + var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], + ux1 = p1[0], uy1 = p1[1], w1 = p1[2], + dx = ux1 - ux0, + dy = uy1 - uy0, + d2 = dx * dx + dy * dy, + i, + S; - /** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ - function hasPath(object, path, hasFunc) { - path = castPath(path, object); + // Special case for u0 ≅ u1. + if (d2 < epsilon2) { + S = Math.log(w1 / w0) / rho; + i = function(t) { + return [ + ux0 + t * dx, + uy0 + t * dy, + w0 * Math.exp(rho * t * S) + ]; + }; + } - var index = -1, - length = path.length, - result = false; + // General case. + else { + var d1 = Math.sqrt(d2), + b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), + b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), + r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), + r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); + S = (r1 - r0) / rho; + i = function(t) { + var s = t * S, + coshr0 = cosh(r0), + u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); + return [ + ux0 + u * dx, + uy0 + u * dy, + w0 * coshr0 / cosh(rho * s + r0) + ]; + }; + } - while (++index < length) { - var key = toKey(path[index]); - if (!(result = object != null && hasFunc(object, key))) { - break; - } - object = object[key]; - } - if (result || ++index != length) { - return result; - } - length = object == null ? 0 : object.length; - return !!length && isLength(length) && isIndex(key, length) && - (isArray(object) || isArguments(object)); - } + i.duration = S * 1000; - /** - * Initializes an array clone. - * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. - */ - function initCloneArray(array) { - var length = array.length, - result = array.constructor(length); - - // Add properties assigned by `RegExp#exec`. - if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { - result.index = array.index; - result.input = array.input; - } - return result; - } + return i; +}; - /** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneObject(object) { - return (typeof object.constructor == 'function' && !isPrototype(object)) - ? baseCreate(getPrototype(object)) - : {}; - } +function hsl$1(hue$$1) { + return function(start, end) { + var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h), + s = nogamma(start.s, end.s), + l = nogamma(start.l, end.l), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.h = h(t); + start.s = s(t); + start.l = l(t); + start.opacity = opacity(t); + return start + ""; + }; + } +} - /** - * Initializes an object clone based on its `toStringTag`. - * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to clone. - * @param {string} tag The `toStringTag` of the object to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneByTag(object, tag, cloneFunc, isDeep) { - var Ctor = object.constructor; - switch (tag) { - case arrayBufferTag: - return cloneArrayBuffer(object); +var hsl$2 = hsl$1(hue); +var hslLong = hsl$1(nogamma); - case boolTag: - case dateTag: - return new Ctor(+object); +function lab$1(start, end) { + var l = nogamma((start = lab(start)).l, (end = lab(end)).l), + a = nogamma(start.a, end.a), + b = nogamma(start.b, end.b), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.l = l(t); + start.a = a(t); + start.b = b(t); + start.opacity = opacity(t); + return start + ""; + }; +} - case dataViewTag: - return cloneDataView(object, isDeep); +function hcl$1(hue$$1) { + return function(start, end) { + var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h), + c = nogamma(start.c, end.c), + l = nogamma(start.l, end.l), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.h = h(t); + start.c = c(t); + start.l = l(t); + start.opacity = opacity(t); + return start + ""; + }; + } +} - case float32Tag: case float64Tag: - case int8Tag: case int16Tag: case int32Tag: - case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - return cloneTypedArray(object, isDeep); +var hcl$2 = hcl$1(hue); +var hclLong = hcl$1(nogamma); - case mapTag: - return cloneMap(object, isDeep, cloneFunc); +function cubehelix$1(hue$$1) { + return (function cubehelixGamma(y) { + y = +y; - case numberTag: - case stringTag: - return new Ctor(object); + function cubehelix$$1(start, end) { + var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h), + s = nogamma(start.s, end.s), + l = nogamma(start.l, end.l), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.h = h(t); + start.s = s(t); + start.l = l(Math.pow(t, y)); + start.opacity = opacity(t); + return start + ""; + }; + } - case regexpTag: - return cloneRegExp(object); + cubehelix$$1.gamma = cubehelixGamma; - case setTag: - return cloneSet(object, isDeep, cloneFunc); + return cubehelix$$1; + })(1); +} - case symbolTag: - return cloneSymbol(object); - } - } +var cubehelix$2 = cubehelix$1(hue); +var cubehelixLong = cubehelix$1(nogamma); - /** - * Inserts wrapper `details` in a comment at the top of the `source` body. - * - * @private - * @param {string} source The source to modify. - * @returns {Array} details The details to insert. - * @returns {string} Returns the modified source. - */ - function insertWrapDetails(source, details) { - var length = details.length; - if (!length) { - return source; - } - var lastIndex = length - 1; - details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; - details = details.join(length > 2 ? ', ' : ' '); - return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); - } +var d3_quantize = function(interpolator, n) { + var samples = new Array(n); + for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1)); + return samples; +}; - /** - * Checks if `value` is a flattenable `arguments` object or array. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. - */ - function isFlattenable(value) { - return isArray(value) || isArguments(value) || - !!(spreadableSymbol && value && value[spreadableSymbol]); - } +var frame = 0; +var timeout = 0; +var interval = 0; +var pokeDelay = 1000; +var taskHead; +var taskTail; +var clockLast = 0; +var clockNow = 0; +var clockSkew = 0; +var clock = typeof performance === "object" && performance.now ? performance : Date; +var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); }; - /** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ - function isIndex(value, length) { - length = length == null ? MAX_SAFE_INTEGER : length; - return !!length && - (typeof value == 'number' || reIsUint.test(value)) && - (value > -1 && value % 1 == 0 && value < length); - } +function now() { + return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); +} - /** - * Checks if the given arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. - */ - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; - } +function clearNow() { + clockNow = 0; +} - /** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ - function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); - } +function Timer() { + this._call = + this._time = + this._next = null; +} - /** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ - function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); +Timer.prototype = timer.prototype = { + constructor: Timer, + restart: function(callback, delay, time) { + if (typeof callback !== "function") throw new TypeError("callback is not a function"); + time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); + if (!this._next && taskTail !== this) { + if (taskTail) taskTail._next = this; + else taskHead = this; + taskTail = this; } - - /** - * Checks if `func` has a lazy counterpart. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` has a lazy counterpart, - * else `false`. - */ - function isLaziable(func) { - var funcName = getFuncName(func), - other = lodash[funcName]; - - if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { - return false; - } - if (func === other) { - return true; - } - var data = getData(other); - return !!data && func === data[0]; + this._call = callback; + this._time = time; + sleep(); + }, + stop: function() { + if (this._call) { + this._call = null; + this._time = Infinity; + sleep(); } + } +}; - /** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ - function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); - } +function timer(callback, delay, time) { + var t = new Timer; + t.restart(callback, delay, time); + return t; +} - /** - * Checks if `func` is capable of being masked. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `func` is maskable, else `false`. - */ - var isMaskable = coreJsData ? isFunction : stubFalse; +function timerFlush() { + now(); // Get the current time, if not already set. + ++frame; // Pretend we’ve set an alarm, if we haven’t already. + var t = taskHead, e; + while (t) { + if ((e = clockNow - t._time) >= 0) t._call.call(null, e); + t = t._next; + } + --frame; +} - /** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ - function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; +function wake() { + clockNow = (clockLast = clock.now()) + clockSkew; + frame = timeout = 0; + try { + timerFlush(); + } finally { + frame = 0; + nap(); + clockNow = 0; + } +} - return value === proto; - } +function poke() { + var now = clock.now(), delay = now - clockLast; + if (delay > pokeDelay) clockSkew -= delay, clockLast = now; +} - /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ - function isStrictComparable(value) { - return value === value && !isObject(value); +function nap() { + var t0, t1 = taskHead, t2, time = Infinity; + while (t1) { + if (t1._call) { + if (time > t1._time) time = t1._time; + t0 = t1, t1 = t1._next; + } else { + t2 = t1._next, t1._next = null; + t1 = t0 ? t0._next = t2 : taskHead = t2; } + } + taskTail = t0; + sleep(time); +} - /** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function matchesStrictComparable(key, srcValue) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === srcValue && - (srcValue !== undefined || (key in Object(object))); - }; - } +function sleep(time) { + if (frame) return; // Soonest alarm already set, or will be. + if (timeout) timeout = clearTimeout(timeout); + var delay = time - clockNow; // Strictly less than if we recomputed clockNow. + if (delay > 24) { + if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew); + if (interval) interval = clearInterval(interval); + } else { + if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay); + frame = 1, setFrame(wake); + } +} - /** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ - function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); +var d3_timeout = function(callback, delay, time) { + var t = new Timer; + delay = delay == null ? 0 : +delay; + t.restart(function(elapsed) { + t.stop(); + callback(elapsed + delay); + }, delay, time); + return t; +}; - var cache = result.cache; - return result; - } +var interval$1 = function(callback, delay, time) { + var t = new Timer, total = delay; + if (delay == null) return t.restart(callback, delay, time), t; + delay = +delay, time = time == null ? now() : +time; + t.restart(function tick(elapsed) { + elapsed += total; + t.restart(tick, total += delay, time); + callback(elapsed); + }, delay, time); + return t; +}; - /** - * Merges the function metadata of `source` into `data`. - * - * Merging metadata reduces the number of wrappers used to invoke a function. - * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` - * may be applied regardless of execution order. Methods like `_.ary` and - * `_.rearg` modify function arguments, making the order in which they are - * executed important, preventing the merging of metadata. However, we make - * an exception for a safe combined case where curried functions have `_.ary` - * and or `_.rearg` applied. - * - * @private - * @param {Array} data The destination metadata. - * @param {Array} source The source metadata. - * @returns {Array} Returns `data`. - */ - function mergeData(data, source) { - var bitmask = data[1], - srcBitmask = source[1], - newBitmask = bitmask | srcBitmask, - isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); - - var isCombo = - ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) || - ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) || - ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG)); - - // Exit early if metadata can't be merged. - if (!(isCommon || isCombo)) { - return data; - } - // Use source `thisArg` if available. - if (srcBitmask & WRAP_BIND_FLAG) { - data[2] = source[2]; - // Set when currying a bound function. - newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; - } - // Compose partial arguments. - var value = source[3]; - if (value) { - var partials = data[3]; - data[3] = partials ? composeArgs(partials, value, source[4]) : value; - data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; - } - // Compose partial right arguments. - value = source[5]; - if (value) { - partials = data[5]; - data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; - data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; - } - // Use source `argPos` if available. - value = source[7]; - if (value) { - data[7] = value; - } - // Use source `ary` if it's smaller. - if (srcBitmask & WRAP_ARY_FLAG) { - data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); - } - // Use source `arity` if one is not provided. - if (data[9] == null) { - data[9] = source[9]; - } - // Use source `func` and merge bitmasks. - data[0] = source[0]; - data[1] = newBitmask; +var emptyOn = dispatch("start", "end", "interrupt"); +var emptyTween = []; - return data; - } +var CREATED = 0; +var SCHEDULED = 1; +var STARTING = 2; +var STARTED = 3; +var RUNNING = 4; +var ENDING = 5; +var ENDED = 6; - /** - * This function is like - * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * except that it includes inherited enumerable properties. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function nativeKeysIn(object) { - var result = []; - if (object != null) { - for (var key in Object(object)) { - result.push(key); - } - } - return result; - } +var schedule = function(node, name, id, index, group, timing) { + var schedules = node.__transition; + if (!schedules) node.__transition = {}; + else if (id in schedules) return; + create(node, id, { + name: name, + index: index, // For context during callback. + group: group, // For context during callback. + on: emptyOn, + tween: emptyTween, + time: timing.time, + delay: timing.delay, + duration: timing.duration, + ease: timing.ease, + timer: null, + state: CREATED + }); +}; - /** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ - function objectToString(value) { - return nativeObjectToString.call(value); - } +function init(node, id) { + var schedule = node.__transition; + if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late"); + return schedule; +} - /** - * A specialized version of `baseRest` which transforms the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @param {Function} transform The rest array transform. - * @returns {Function} Returns the new function. - */ - function overRest(func, start, transform) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); +function set$1(node, id) { + var schedule = node.__transition; + if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late"); + return schedule; +} - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = transform(array); - return apply(func, this, otherArgs); - }; - } +function get$1(node, id) { + var schedule = node.__transition; + if (!schedule || !(schedule = schedule[id])) throw new Error("too late"); + return schedule; +} - /** - * Gets the parent value at `path` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} path The path to get the parent value of. - * @returns {*} Returns the parent value. - */ - function parent(object, path) { - return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); - } +function create(node, id, self) { + var schedules = node.__transition, + tween; - /** - * Reorder `array` according to the specified indexes where the element at - * the first index is assigned as the first element, the element at - * the second index is assigned as the second element, and so on. - * - * @private - * @param {Array} array The array to reorder. - * @param {Array} indexes The arranged array indexes. - * @returns {Array} Returns `array`. - */ - function reorder(array, indexes) { - var arrLength = array.length, - length = nativeMin(indexes.length, arrLength), - oldArray = copyArray(array); - - while (length--) { - var index = indexes[length]; - array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; - } - return array; - } + // Initialize the self timer when the transition is created. + // Note the actual delay is not known until the first callback! + schedules[id] = self; + self.timer = timer(schedule, 0, self.time); - /** - * Sets metadata for `func`. - * - * **Note:** If this function becomes hot, i.e. is invoked a lot in a short - * period of time, it will trip its breaker and transition to an identity - * function to avoid garbage collection pauses in V8. See - * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) - * for more details. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var setData = shortOut(baseSetData); + function schedule(elapsed) { + self.state = SCHEDULED; + self.timer.restart(start, self.delay, self.time); - /** - * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout). - * - * @private - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @returns {number|Object} Returns the timer id or timeout object. - */ - var setTimeout = ctxSetTimeout || function(func, wait) { - return root.setTimeout(func, wait); - }; + // If the elapsed delay is less than our first sleep, start immediately. + if (self.delay <= elapsed) start(elapsed - self.delay); + } - /** - * Sets the `toString` method of `func` to return `string`. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ - var setToString = shortOut(baseSetToString); + function start(elapsed) { + var i, j, n, o; - /** - * Sets the `toString` method of `wrapper` to mimic the source of `reference` - * with wrapper details in a comment at the top of the source body. - * - * @private - * @param {Function} wrapper The function to modify. - * @param {Function} reference The reference function. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @returns {Function} Returns `wrapper`. - */ - function setWrapToString(wrapper, reference, bitmask) { - var source = (reference + ''); - return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); - } + // If the state is not SCHEDULED, then we previously errored on start. + if (self.state !== SCHEDULED) return stop(); - /** - * Creates a function that'll short out and invoke `identity` instead - * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` - * milliseconds. - * - * @private - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new shortable function. - */ - function shortOut(func) { - var count = 0, - lastCalled = 0; + for (i in schedules) { + o = schedules[i]; + if (o.name !== self.name) continue; - return function() { - var stamp = nativeNow(), - remaining = HOT_SPAN - (stamp - lastCalled); + // While this element already has a starting transition during this frame, + // defer starting an interrupting transition until that transition has a + // chance to tick (and possibly end); see d3/d3-transition#54! + if (o.state === STARTED) return d3_timeout(start); - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return arguments[0]; - } - } else { - count = 0; - } - return func.apply(undefined, arguments); - }; - } + // Interrupt the active transition, if any. + // Dispatch the interrupt event. + if (o.state === RUNNING) { + o.state = ENDED; + o.timer.stop(); + o.on.call("interrupt", node, node.__data__, o.index, o.group); + delete schedules[i]; + } - /** - * A specialized version of `_.shuffle` which mutates and sets the size of `array`. - * - * @private - * @param {Array} array The array to shuffle. - * @param {number} [size=array.length] The size of `array`. - * @returns {Array} Returns `array`. - */ - function shuffleSelf(array, size) { - var index = -1, - length = array.length, - lastIndex = length - 1; - - size = size === undefined ? length : size; - while (++index < size) { - var rand = baseRandom(index, lastIndex), - value = array[rand]; - - array[rand] = array[index]; - array[index] = value; + // Cancel any pre-empted transitions. No interrupt event is dispatched + // because the cancelled transitions never started. Note that this also + // removes this transition from the pending list! + else if (+i < id) { + o.state = ENDED; + o.timer.stop(); + delete schedules[i]; } - array.length = size; - return array; } - /** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ - var stringToPath = memoizeCapped(function(string) { - var result = []; - if (reLeadingDot.test(string)) { - result.push(''); + // Defer the first tick to end of the current frame; see d3/d3#1576. + // Note the transition may be canceled after start and before the first tick! + // Note this must be scheduled before the start event; see d3/d3-transition#16! + // Assuming this is successful, subsequent callbacks go straight to tick. + d3_timeout(function() { + if (self.state === STARTED) { + self.state = RUNNING; + self.timer.restart(tick, self.delay, self.time); + tick(elapsed); } - string.replace(rePropName, function(match, number, quote, string) { - result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; }); - /** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ - function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } + // Dispatch the start event. + // Note this must be done before the tween are initialized. + self.state = STARTING; + self.on.call("start", node, node.__data__, self.index, self.group); + if (self.state !== STARTING) return; // interrupted + self.state = STARTED; - /** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ - function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} + // Initialize the tween, deleting null tween. + tween = new Array(n = self.tween.length); + for (i = 0, j = -1; i < n; ++i) { + if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) { + tween[++j] = o; } - return ''; } + tween.length = j + 1; + } - /** - * Updates wrapper `details` based on `bitmask` flags. - * - * @private - * @returns {Array} details The details to modify. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @returns {Array} Returns `details`. - */ - function updateWrapDetails(details, bitmask) { - arrayEach(wrapFlags, function(pair) { - var value = '_.' + pair[0]; - if ((bitmask & pair[1]) && !arrayIncludes(details, value)) { - details.push(value); - } - }); - return details.sort(); - } + function tick(elapsed) { + var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), + i = -1, + n = tween.length; - /** - * Creates a clone of `wrapper`. - * - * @private - * @param {Object} wrapper The wrapper to clone. - * @returns {Object} Returns the cloned wrapper. - */ - function wrapperClone(wrapper) { - if (wrapper instanceof LazyWrapper) { - return wrapper.clone(); - } - var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); - result.__actions__ = copyArray(wrapper.__actions__); - result.__index__ = wrapper.__index__; - result.__values__ = wrapper.__values__; - return result; + while (++i < n) { + tween[i].call(null, t); } - /*------------------------------------------------------------------------*/ + // Dispatch the end event. + if (self.state === ENDING) { + self.on.call("end", node, node.__data__, self.index, self.group); + stop(); + } + } - /** - * Creates an array of elements split into groups the length of `size`. - * If `array` can't be split evenly, the final chunk will be the remaining - * elements. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to process. - * @param {number} [size=1] The length of each chunk - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the new array of chunks. - * @example - * - * _.chunk(['a', 'b', 'c', 'd'], 2); - * // => [['a', 'b'], ['c', 'd']] - * - * _.chunk(['a', 'b', 'c', 'd'], 3); - * // => [['a', 'b', 'c'], ['d']] - */ - function chunk(array, size, guard) { - if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) { - size = 1; - } else { - size = nativeMax(toInteger(size), 0); - } - var length = array == null ? 0 : array.length; - if (!length || size < 1) { - return []; - } - var index = 0, - resIndex = 0, - result = Array(nativeCeil(length / size)); + function stop() { + self.state = ENDED; + self.timer.stop(); + delete schedules[id]; + for (var i in schedules) return; // eslint-disable-line no-unused-vars + delete node.__transition; + } +} - while (index < length) { - result[resIndex++] = baseSlice(array, index, (index += size)); - } - return result; - } +var interrupt = function(node, name) { + var schedules = node.__transition, + schedule$$1, + active, + empty = true, + i; - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are falsey. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to compact. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result[resIndex++] = value; - } - } - return result; - } + if (!schedules) return; - /** - * Creates a new array concatenating `array` with any additional arrays - * and/or values. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to concatenate. - * @param {...*} [values] The values to concatenate. - * @returns {Array} Returns the new concatenated array. - * @example - * - * var array = [1]; - * var other = _.concat(array, 2, [3], [[4]]); - * - * console.log(other); - * // => [1, 2, 3, [4]] - * - * console.log(array); - * // => [1] - */ - function concat() { - var length = arguments.length; - if (!length) { - return []; - } - var args = Array(length - 1), - array = arguments[0], - index = length; + name = name == null ? null : name + ""; - while (index--) { - args[index - 1] = arguments[index]; - } - return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); - } + for (i in schedules) { + if ((schedule$$1 = schedules[i]).name !== name) { empty = false; continue; } + active = schedule$$1.state > STARTING && schedule$$1.state < ENDING; + schedule$$1.state = ENDED; + schedule$$1.timer.stop(); + if (active) schedule$$1.on.call("interrupt", node, node.__data__, schedule$$1.index, schedule$$1.group); + delete schedules[i]; + } - /** - * Creates an array of `array` values not included in the other given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. The order and references of result values are - * determined by the first array. - * - * **Note:** Unlike `_.pullAll`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.without, _.xor - * @example - * - * _.difference([2, 1], [2, 3]); - * // => [1] - */ - var difference = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) - : []; - }); + if (empty) delete node.__transition; +}; - /** - * This method is like `_.difference` except that it accepts `iteratee` which - * is invoked for each element of `array` and `values` to generate the criterion - * by which they're compared. The order and references of result values are - * determined by the first array. The iteratee is invoked with one argument: - * (value). - * - * **Note:** Unlike `_.pullAllBy`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [1.2] - * - * // The `_.property` iteratee shorthand. - * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); - * // => [{ 'x': 2 }] - */ - var differenceBy = baseRest(function(array, values) { - var iteratee = last(values); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; - } - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)) - : []; - }); +var selection_interrupt = function(name) { + return this.each(function() { + interrupt(this, name); + }); +}; - /** - * This method is like `_.difference` except that it accepts `comparator` - * which is invoked to compare elements of `array` to `values`. The order and - * references of result values are determined by the first array. The comparator - * is invoked with two arguments: (arrVal, othVal). - * - * **Note:** Unlike `_.pullAllWith`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * - * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); - * // => [{ 'x': 2, 'y': 1 }] - */ - var differenceWith = baseRest(function(array, values) { - var comparator = last(values); - if (isArrayLikeObject(comparator)) { - comparator = undefined; - } - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator) - : []; - }); +function tweenRemove(id, name) { + var tween0, tween1; + return function() { + var schedule$$1 = set$1(this, id), + tween = schedule$$1.tween; - /** - * Creates a slice of `array` with `n` elements dropped from the beginning. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.drop([1, 2, 3]); - * // => [2, 3] - * - * _.drop([1, 2, 3], 2); - * // => [3] - * - * _.drop([1, 2, 3], 5); - * // => [] - * - * _.drop([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function drop(array, n, guard) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; + // If this node shared tween with the previous node, + // just assign the updated shared tween and we’re done! + // Otherwise, copy-on-write. + if (tween !== tween0) { + tween1 = tween0 = tween; + for (var i = 0, n = tween1.length; i < n; ++i) { + if (tween1[i].name === name) { + tween1 = tween1.slice(); + tween1.splice(i, 1); + break; + } } - n = (guard || n === undefined) ? 1 : toInteger(n); - return baseSlice(array, n < 0 ? 0 : n, length); } - /** - * Creates a slice of `array` with `n` elements dropped from the end. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.dropRight([1, 2, 3]); - * // => [1, 2] - * - * _.dropRight([1, 2, 3], 2); - * // => [1] - * - * _.dropRight([1, 2, 3], 5); - * // => [] - * - * _.dropRight([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function dropRight(array, n, guard) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; + schedule$$1.tween = tween1; + }; +} + +function tweenFunction(id, name, value) { + var tween0, tween1; + if (typeof value !== "function") throw new Error; + return function() { + var schedule$$1 = set$1(this, id), + tween = schedule$$1.tween; + + // If this node shared tween with the previous node, + // just assign the updated shared tween and we’re done! + // Otherwise, copy-on-write. + if (tween !== tween0) { + tween1 = (tween0 = tween).slice(); + for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) { + if (tween1[i].name === name) { + tween1[i] = t; + break; + } } - n = (guard || n === undefined) ? 1 : toInteger(n); - n = length - n; - return baseSlice(array, 0, n < 0 ? 0 : n); + if (i === n) tween1.push(t); } - /** - * Creates a slice of `array` excluding elements dropped from the end. - * Elements are dropped until `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.dropRightWhile(users, function(o) { return !o.active; }); - * // => objects for ['barney'] - * - * // The `_.matches` iteratee shorthand. - * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); - * // => objects for ['barney', 'fred'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.dropRightWhile(users, ['active', false]); - * // => objects for ['barney'] - * - * // The `_.property` iteratee shorthand. - * _.dropRightWhile(users, 'active'); - * // => objects for ['barney', 'fred', 'pebbles'] - */ - function dropRightWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), true, true) - : []; - } + schedule$$1.tween = tween1; + }; +} - /** - * Creates a slice of `array` excluding elements dropped from the beginning. - * Elements are dropped until `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.dropWhile(users, function(o) { return !o.active; }); - * // => objects for ['pebbles'] - * - * // The `_.matches` iteratee shorthand. - * _.dropWhile(users, { 'user': 'barney', 'active': false }); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.dropWhile(users, ['active', false]); - * // => objects for ['pebbles'] - * - * // The `_.property` iteratee shorthand. - * _.dropWhile(users, 'active'); - * // => objects for ['barney', 'fred', 'pebbles'] - */ - function dropWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), true) - : []; - } +var transition_tween = function(name, value) { + var id = this._id; - /** - * Fills elements of `array` with `value` from `start` up to, but not - * including, `end`. - * - * **Note:** This method mutates `array`. - * - * @static - * @memberOf _ - * @since 3.2.0 - * @category Array - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3]; - * - * _.fill(array, 'a'); - * console.log(array); - * // => ['a', 'a', 'a'] - * - * _.fill(Array(3), 2); - * // => [2, 2, 2] - * - * _.fill([4, 6, 8, 10], '*', 1, 3); - * // => [4, '*', '*', 10] - */ - function fill(array, value, start, end) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { - start = 0; - end = length; - } - return baseFill(array, value, start, end); - } + name += ""; - /** - * This method is like `_.find` except that it returns the index of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.findIndex(users, function(o) { return o.user == 'barney'; }); - * // => 0 - * - * // The `_.matches` iteratee shorthand. - * _.findIndex(users, { 'user': 'fred', 'active': false }); - * // => 1 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findIndex(users, ['active', false]); - * // => 0 - * - * // The `_.property` iteratee shorthand. - * _.findIndex(users, 'active'); - * // => 2 - */ - function findIndex(array, predicate, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); + if (arguments.length < 2) { + var tween = get$1(this.node(), id).tween; + for (var i = 0, n = tween.length, t; i < n; ++i) { + if ((t = tween[i]).name === name) { + return t.value; } - return baseFindIndex(array, getIteratee(predicate, 3), index); } + return null; + } - /** - * This method is like `_.findIndex` except that it iterates over elements - * of `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); - * // => 2 - * - * // The `_.matches` iteratee shorthand. - * _.findLastIndex(users, { 'user': 'barney', 'active': true }); - * // => 0 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findLastIndex(users, ['active', false]); - * // => 2 - * - * // The `_.property` iteratee shorthand. - * _.findLastIndex(users, 'active'); - * // => 0 - */ - function findLastIndex(array, predicate, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = length - 1; - if (fromIndex !== undefined) { - index = toInteger(fromIndex); - index = fromIndex < 0 - ? nativeMax(length + index, 0) - : nativeMin(index, length - 1); - } - return baseFindIndex(array, getIteratee(predicate, 3), index, true); - } + return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value)); +}; - /** - * Flattens `array` a single level deep. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flatten([1, [2, [3, [4]], 5]]); - * // => [1, 2, [3, [4]], 5] - */ - function flatten(array) { - var length = array == null ? 0 : array.length; - return length ? baseFlatten(array, 1) : []; - } +function tweenValue(transition, name, value) { + var id = transition._id; - /** - * Recursively flattens `array`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flattenDeep([1, [2, [3, [4]], 5]]); - * // => [1, 2, 3, 4, 5] - */ - function flattenDeep(array) { - var length = array == null ? 0 : array.length; - return length ? baseFlatten(array, INFINITY) : []; - } + transition.each(function() { + var schedule$$1 = set$1(this, id); + (schedule$$1.value || (schedule$$1.value = {}))[name] = value.apply(this, arguments); + }); - /** - * Recursively flatten `array` up to `depth` times. - * - * @static - * @memberOf _ - * @since 4.4.0 - * @category Array - * @param {Array} array The array to flatten. - * @param {number} [depth=1] The maximum recursion depth. - * @returns {Array} Returns the new flattened array. - * @example - * - * var array = [1, [2, [3, [4]], 5]]; - * - * _.flattenDepth(array, 1); - * // => [1, 2, [3, [4]], 5] - * - * _.flattenDepth(array, 2); - * // => [1, 2, 3, [4], 5] - */ - function flattenDepth(array, depth) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - depth = depth === undefined ? 1 : toInteger(depth); - return baseFlatten(array, depth); - } + return function(node) { + return get$1(node, id).value[name]; + }; +} - /** - * The inverse of `_.toPairs`; this method returns an object composed - * from key-value `pairs`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} pairs The key-value pairs. - * @returns {Object} Returns the new object. - * @example - * - * _.fromPairs([['a', 1], ['b', 2]]); - * // => { 'a': 1, 'b': 2 } - */ - function fromPairs(pairs) { - var index = -1, - length = pairs == null ? 0 : pairs.length, - result = {}; - - while (++index < length) { - var pair = pairs[index]; - result[pair[0]] = pair[1]; - } - return result; - } +var interpolate = function(a, b) { + var c; + return (typeof b === "number" ? d3_interpolateNumber + : b instanceof color ? d3_interpolateRgb + : (c = color(b)) ? (b = c, d3_interpolateRgb) + : interpolateString)(a, b); +}; - /** - * Gets the first element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias first - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. - * @example - * - * _.head([1, 2, 3]); - * // => 1 - * - * _.head([]); - * // => undefined - */ - function head(array) { - return (array && array.length) ? array[0] : undefined; - } +function attrRemove$1(name) { + return function() { + this.removeAttribute(name); + }; +} - /** - * Gets the index at which the first occurrence of `value` is found in `array` - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. If `fromIndex` is negative, it's used as the - * offset from the end of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.indexOf([1, 2, 1, 2], 2); - * // => 1 - * - * // Search from the `fromIndex`. - * _.indexOf([1, 2, 1, 2], 2, 2); - * // => 3 - */ - function indexOf(array, value, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); - } - return baseIndexOf(array, value, index); - } +function attrRemoveNS$1(fullname) { + return function() { + this.removeAttributeNS(fullname.space, fullname.local); + }; +} - /** - * Gets all but the last element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - */ - function initial(array) { - var length = array == null ? 0 : array.length; - return length ? baseSlice(array, 0, -1) : []; - } +function attrConstant$1(name, interpolate$$1, value1) { + var value00, + interpolate0; + return function() { + var value0 = this.getAttribute(name); + return value0 === value1 ? null + : value0 === value00 ? interpolate0 + : interpolate0 = interpolate$$1(value00 = value0, value1); + }; +} - /** - * Creates an array of unique values that are included in all given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. The order and references of result values are - * determined by the first array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * _.intersection([2, 1], [2, 3]); - * // => [2] - */ - var intersection = baseRest(function(arrays) { - var mapped = arrayMap(arrays, castArrayLikeObject); - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped) - : []; - }); +function attrConstantNS$1(fullname, interpolate$$1, value1) { + var value00, + interpolate0; + return function() { + var value0 = this.getAttributeNS(fullname.space, fullname.local); + return value0 === value1 ? null + : value0 === value00 ? interpolate0 + : interpolate0 = interpolate$$1(value00 = value0, value1); + }; +} - /** - * This method is like `_.intersection` except that it accepts `iteratee` - * which is invoked for each element of each `arrays` to generate the criterion - * by which they're compared. The order and references of result values are - * determined by the first array. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [2.1] - * - * // The `_.property` iteratee shorthand. - * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }] - */ - var intersectionBy = baseRest(function(arrays) { - var iteratee = last(arrays), - mapped = arrayMap(arrays, castArrayLikeObject); +function attrFunction$1(name, interpolate$$1, value) { + var value00, + value10, + interpolate0; + return function() { + var value0, value1 = value(this); + if (value1 == null) return void this.removeAttribute(name); + value0 = this.getAttribute(name); + return value0 === value1 ? null + : value0 === value00 && value1 === value10 ? interpolate0 + : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); + }; +} - if (iteratee === last(mapped)) { - iteratee = undefined; - } else { - mapped.pop(); - } - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped, getIteratee(iteratee, 2)) - : []; - }); +function attrFunctionNS$1(fullname, interpolate$$1, value) { + var value00, + value10, + interpolate0; + return function() { + var value0, value1 = value(this); + if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local); + value0 = this.getAttributeNS(fullname.space, fullname.local); + return value0 === value1 ? null + : value0 === value00 && value1 === value10 ? interpolate0 + : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); + }; +} - /** - * This method is like `_.intersection` except that it accepts `comparator` - * which is invoked to compare elements of `arrays`. The order and references - * of result values are determined by the first array. The comparator is - * invoked with two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.intersectionWith(objects, others, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }] - */ - var intersectionWith = baseRest(function(arrays) { - var comparator = last(arrays), - mapped = arrayMap(arrays, castArrayLikeObject); +var transition_attr = function(name, value) { + var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate; + return this.attrTween(name, typeof value === "function" + ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value)) + : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname) + : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value + "")); +}; - comparator = typeof comparator == 'function' ? comparator : undefined; - if (comparator) { - mapped.pop(); - } - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped, undefined, comparator) - : []; - }); +function attrTweenNS(fullname, value) { + function tween() { + var node = this, i = value.apply(node, arguments); + return i && function(t) { + node.setAttributeNS(fullname.space, fullname.local, i(t)); + }; + } + tween._value = value; + return tween; +} - /** - * Converts all elements in `array` into a string separated by `separator`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to convert. - * @param {string} [separator=','] The element separator. - * @returns {string} Returns the joined string. - * @example - * - * _.join(['a', 'b', 'c'], '~'); - * // => 'a~b~c' - */ - function join(array, separator) { - return array == null ? '' : nativeJoin.call(array, separator); - } +function attrTween(name, value) { + function tween() { + var node = this, i = value.apply(node, arguments); + return i && function(t) { + node.setAttribute(name, i(t)); + }; + } + tween._value = value; + return tween; +} - /** - * Gets the last element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the last element of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - */ - function last(array) { - var length = array == null ? 0 : array.length; - return length ? array[length - 1] : undefined; - } +var transition_attrTween = function(name, value) { + var key = "attr." + name; + if (arguments.length < 2) return (key = this.tween(key)) && key._value; + if (value == null) return this.tween(key, null); + if (typeof value !== "function") throw new Error; + var fullname = namespace(name); + return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value)); +}; - /** - * This method is like `_.indexOf` except that it iterates over elements of - * `array` from right to left. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.lastIndexOf([1, 2, 1, 2], 2); - * // => 3 - * - * // Search from the `fromIndex`. - * _.lastIndexOf([1, 2, 1, 2], 2, 2); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = length; - if (fromIndex !== undefined) { - index = toInteger(fromIndex); - index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); - } - return value === value - ? strictLastIndexOf(array, value, index) - : baseFindIndex(array, baseIsNaN, index, true); - } +function delayFunction(id, value) { + return function() { + init(this, id).delay = +value.apply(this, arguments); + }; +} - /** - * Gets the element at index `n` of `array`. If `n` is negative, the nth - * element from the end is returned. - * - * @static - * @memberOf _ - * @since 4.11.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=0] The index of the element to return. - * @returns {*} Returns the nth element of `array`. - * @example - * - * var array = ['a', 'b', 'c', 'd']; - * - * _.nth(array, 1); - * // => 'b' - * - * _.nth(array, -2); - * // => 'c'; - */ - function nth(array, n) { - return (array && array.length) ? baseNth(array, toInteger(n)) : undefined; - } +function delayConstant(id, value) { + return value = +value, function() { + init(this, id).delay = value; + }; +} - /** - * Removes all given values from `array` using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` - * to remove elements from an array by predicate. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {...*} [values] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = ['a', 'b', 'c', 'a', 'b', 'c']; - * - * _.pull(array, 'a', 'c'); - * console.log(array); - * // => ['b', 'b'] - */ - var pull = baseRest(pullAll); +var transition_delay = function(value) { + var id = this._id; - /** - * This method is like `_.pull` except that it accepts an array of values to remove. - * - * **Note:** Unlike `_.difference`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = ['a', 'b', 'c', 'a', 'b', 'c']; - * - * _.pullAll(array, ['a', 'c']); - * console.log(array); - * // => ['b', 'b'] - */ - function pullAll(array, values) { - return (array && array.length && values && values.length) - ? basePullAll(array, values) - : array; - } + return arguments.length + ? this.each((typeof value === "function" + ? delayFunction + : delayConstant)(id, value)) + : get$1(this.node(), id).delay; +}; - /** - * This method is like `_.pullAll` except that it accepts `iteratee` which is - * invoked for each element of `array` and `values` to generate the criterion - * by which they're compared. The iteratee is invoked with one argument: (value). - * - * **Note:** Unlike `_.differenceBy`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns `array`. - * @example - * - * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; - * - * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); - * console.log(array); - * // => [{ 'x': 2 }] - */ - function pullAllBy(array, values, iteratee) { - return (array && array.length && values && values.length) - ? basePullAll(array, values, getIteratee(iteratee, 2)) - : array; - } +function durationFunction(id, value) { + return function() { + set$1(this, id).duration = +value.apply(this, arguments); + }; +} - /** - * This method is like `_.pullAll` except that it accepts `comparator` which - * is invoked to compare elements of `array` to `values`. The comparator is - * invoked with two arguments: (arrVal, othVal). - * - * **Note:** Unlike `_.differenceWith`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns `array`. - * @example - * - * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; - * - * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); - * console.log(array); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] - */ - function pullAllWith(array, values, comparator) { - return (array && array.length && values && values.length) - ? basePullAll(array, values, undefined, comparator) - : array; - } +function durationConstant(id, value) { + return value = +value, function() { + set$1(this, id).duration = value; + }; +} - /** - * Removes elements from `array` corresponding to `indexes` and returns an - * array of removed elements. - * - * **Note:** Unlike `_.at`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {...(number|number[])} [indexes] The indexes of elements to remove. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = ['a', 'b', 'c', 'd']; - * var pulled = _.pullAt(array, [1, 3]); - * - * console.log(array); - * // => ['a', 'c'] - * - * console.log(pulled); - * // => ['b', 'd'] - */ - var pullAt = flatRest(function(array, indexes) { - var length = array == null ? 0 : array.length, - result = baseAt(array, indexes); +var transition_duration = function(value) { + var id = this._id; - basePullAt(array, arrayMap(indexes, function(index) { - return isIndex(index, length) ? +index : index; - }).sort(compareAscending)); + return arguments.length + ? this.each((typeof value === "function" + ? durationFunction + : durationConstant)(id, value)) + : get$1(this.node(), id).duration; +}; - return result; - }); +function easeConstant(id, value) { + if (typeof value !== "function") throw new Error; + return function() { + set$1(this, id).ease = value; + }; +} - /** - * Removes all elements from `array` that `predicate` returns truthy for - * and returns an array of the removed elements. The predicate is invoked - * with three arguments: (value, index, array). - * - * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` - * to pull elements from an array by value. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4]; - * var evens = _.remove(array, function(n) { - * return n % 2 == 0; - * }); - * - * console.log(array); - * // => [1, 3] - * - * console.log(evens); - * // => [2, 4] - */ - function remove(array, predicate) { - var result = []; - if (!(array && array.length)) { - return result; - } - var index = -1, - indexes = [], - length = array.length; +var transition_ease = function(value) { + var id = this._id; - predicate = getIteratee(predicate, 3); - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result.push(value); - indexes.push(index); - } - } - basePullAt(array, indexes); - return result; - } + return arguments.length + ? this.each(easeConstant(id, value)) + : get$1(this.node(), id).ease; +}; - /** - * Reverses `array` so that the first element becomes the last, the second - * element becomes the second to last, and so on. - * - * **Note:** This method mutates `array` and is based on - * [`Array#reverse`](https://mdn.io/Array/reverse). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3]; - * - * _.reverse(array); - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function reverse(array) { - return array == null ? array : nativeReverse.call(array); - } +var transition_filter = function(match) { + if (typeof match !== "function") match = matcher$1(match); - /** - * Creates a slice of `array` from `start` up to, but not including, `end`. - * - * **Note:** This method is used instead of - * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are - * returned. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function slice(array, start, end) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { - start = 0; - end = length; - } - else { - start = start == null ? 0 : toInteger(start); - end = end === undefined ? length : toInteger(end); + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { + if ((node = group[i]) && match.call(node, node.__data__, i, group)) { + subgroup.push(node); } - return baseSlice(array, start, end); } + } - /** - * Uses a binary search to determine the lowest index at which `value` - * should be inserted into `array` in order to maintain its sort order. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([30, 50], 40); - * // => 1 - */ - function sortedIndex(array, value) { - return baseSortedIndex(array, value); - } + return new Transition(subgroups, this._parents, this._name, this._id); +}; - /** - * This method is like `_.sortedIndex` except that it accepts `iteratee` - * which is invoked for `value` and each element of `array` to compute their - * sort ranking. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * var objects = [{ 'x': 4 }, { 'x': 5 }]; - * - * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); - * // => 0 - * - * // The `_.property` iteratee shorthand. - * _.sortedIndexBy(objects, { 'x': 4 }, 'x'); - * // => 0 - */ - function sortedIndexBy(array, value, iteratee) { - return baseSortedIndexBy(array, value, getIteratee(iteratee, 2)); - } +var transition_merge = function(transition$$1) { + if (transition$$1._id !== this._id) throw new Error; - /** - * This method is like `_.indexOf` except that it performs a binary - * search on a sorted `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.sortedIndexOf([4, 5, 5, 5, 6], 5); - * // => 1 - */ - function sortedIndexOf(array, value) { - var length = array == null ? 0 : array.length; - if (length) { - var index = baseSortedIndex(array, value); - if (index < length && eq(array[index], value)) { - return index; - } + for (var groups0 = this._groups, groups1 = transition$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { + for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { + if (node = group0[i] || group1[i]) { + merge[i] = node; } - return -1; } + } - /** - * This method is like `_.sortedIndex` except that it returns the highest - * index at which `value` should be inserted into `array` in order to - * maintain its sort order. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedLastIndex([4, 5, 5, 5, 6], 5); - * // => 4 - */ - function sortedLastIndex(array, value) { - return baseSortedIndex(array, value, true); - } + for (; j < m0; ++j) { + merges[j] = groups0[j]; + } - /** - * This method is like `_.sortedLastIndex` except that it accepts `iteratee` - * which is invoked for `value` and each element of `array` to compute their - * sort ranking. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * var objects = [{ 'x': 4 }, { 'x': 5 }]; - * - * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); - * // => 1 - * - * // The `_.property` iteratee shorthand. - * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); - * // => 1 - */ - function sortedLastIndexBy(array, value, iteratee) { - return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true); - } + return new Transition(merges, this._parents, this._name, this._id); +}; - /** - * This method is like `_.lastIndexOf` except that it performs a binary - * search on a sorted `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); - * // => 3 - */ - function sortedLastIndexOf(array, value) { - var length = array == null ? 0 : array.length; - if (length) { - var index = baseSortedIndex(array, value, true) - 1; - if (eq(array[index], value)) { - return index; - } - } - return -1; - } +function start(name) { + return (name + "").trim().split(/^|\s+/).every(function(t) { + var i = t.indexOf("."); + if (i >= 0) t = t.slice(0, i); + return !t || t === "start"; + }); +} - /** - * This method is like `_.uniq` except that it's designed and optimized - * for sorted arrays. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.sortedUniq([1, 1, 2]); - * // => [1, 2] - */ - function sortedUniq(array) { - return (array && array.length) - ? baseSortedUniq(array) - : []; - } +function onFunction(id, name, listener) { + var on0, on1, sit = start(name) ? init : set$1; + return function() { + var schedule$$1 = sit(this, id), + on = schedule$$1.on; - /** - * This method is like `_.uniqBy` except that it's designed and optimized - * for sorted arrays. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); - * // => [1.1, 2.3] - */ - function sortedUniqBy(array, iteratee) { - return (array && array.length) - ? baseSortedUniq(array, getIteratee(iteratee, 2)) - : []; - } + // If this node shared a dispatch with the previous node, + // just assign the updated shared dispatch and we’re done! + // Otherwise, copy-on-write. + if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener); - /** - * Gets all but the first element of `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.tail([1, 2, 3]); - * // => [2, 3] - */ - function tail(array) { - var length = array == null ? 0 : array.length; - return length ? baseSlice(array, 1, length) : []; - } + schedule$$1.on = on1; + }; +} - /** - * Creates a slice of `array` with `n` elements taken from the beginning. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.take([1, 2, 3]); - * // => [1] - * - * _.take([1, 2, 3], 2); - * // => [1, 2] - * - * _.take([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.take([1, 2, 3], 0); - * // => [] - */ - function take(array, n, guard) { - if (!(array && array.length)) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - return baseSlice(array, 0, n < 0 ? 0 : n); - } +var transition_on = function(name, listener) { + var id = this._id; - /** - * Creates a slice of `array` with `n` elements taken from the end. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.takeRight([1, 2, 3]); - * // => [3] - * - * _.takeRight([1, 2, 3], 2); - * // => [2, 3] - * - * _.takeRight([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.takeRight([1, 2, 3], 0); - * // => [] - */ - function takeRight(array, n, guard) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - n = length - n; - return baseSlice(array, n < 0 ? 0 : n, length); - } + return arguments.length < 2 + ? get$1(this.node(), id).on.on(name) + : this.each(onFunction(id, name, listener)); +}; - /** - * Creates a slice of `array` with elements taken from the end. Elements are - * taken until `predicate` returns falsey. The predicate is invoked with - * three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.takeRightWhile(users, function(o) { return !o.active; }); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.matches` iteratee shorthand. - * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); - * // => objects for ['pebbles'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.takeRightWhile(users, ['active', false]); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.property` iteratee shorthand. - * _.takeRightWhile(users, 'active'); - * // => [] - */ - function takeRightWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), false, true) - : []; - } +function removeFunction(id) { + return function() { + var parent = this.parentNode; + for (var i in this.__transition) if (+i !== id) return; + if (parent) parent.removeChild(this); + }; +} - /** - * Creates a slice of `array` with elements taken from the beginning. Elements - * are taken until `predicate` returns falsey. The predicate is invoked with - * three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.takeWhile(users, function(o) { return !o.active; }); - * // => objects for ['barney', 'fred'] - * - * // The `_.matches` iteratee shorthand. - * _.takeWhile(users, { 'user': 'barney', 'active': false }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.takeWhile(users, ['active', false]); - * // => objects for ['barney', 'fred'] - * - * // The `_.property` iteratee shorthand. - * _.takeWhile(users, 'active'); - * // => [] - */ - function takeWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3)) - : []; - } +var transition_remove = function() { + return this.on("end.remove", removeFunction(this._id)); +}; - /** - * Creates an array of unique values, in order, from all given arrays using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.union([2], [1, 2]); - * // => [2, 1] - */ - var union = baseRest(function(arrays) { - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); - }); +var transition_select = function(select) { + var name = this._name, + id = this._id; - /** - * This method is like `_.union` except that it accepts `iteratee` which is - * invoked for each element of each `arrays` to generate the criterion by - * which uniqueness is computed. Result values are chosen from the first - * array in which the value occurs. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.unionBy([2.1], [1.2, 2.3], Math.floor); - * // => [2.1, 1.2] - * - * // The `_.property` iteratee shorthand. - * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - var unionBy = baseRest(function(arrays) { - var iteratee = last(arrays); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; + if (typeof select !== "function") select = selector(select); + + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { + if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { + if ("__data__" in node) subnode.__data__ = node.__data__; + subgroup[i] = subnode; + schedule(subgroup[i], name, id, i, subgroup, get$1(node, id)); } - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)); - }); + } + } - /** - * This method is like `_.union` except that it accepts `comparator` which - * is invoked to compare elements of `arrays`. Result values are chosen from - * the first array in which the value occurs. The comparator is invoked - * with two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of combined values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.unionWith(objects, others, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] - */ - var unionWith = baseRest(function(arrays) { - var comparator = last(arrays); - comparator = typeof comparator == 'function' ? comparator : undefined; - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator); - }); + return new Transition(subgroups, this._parents, name, id); +}; - /** - * Creates a duplicate-free version of an array, using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons, in which only the first occurrence of each element - * is kept. The order of result values is determined by the order they occur - * in the array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniq([2, 1, 2]); - * // => [2, 1] - */ - function uniq(array) { - return (array && array.length) ? baseUniq(array) : []; - } +var transition_selectAll = function(select) { + var name = this._name, + id = this._id; - /** - * This method is like `_.uniq` except that it accepts `iteratee` which is - * invoked for each element in `array` to generate the criterion by which - * uniqueness is computed. The order of result values is determined by the - * order they occur in the array. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniqBy([2.1, 1.2, 2.3], Math.floor); - * // => [2.1, 1.2] - * - * // The `_.property` iteratee shorthand. - * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniqBy(array, iteratee) { - return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : []; - } + if (typeof select !== "function") select = selectorAll(select); - /** - * This method is like `_.uniq` except that it accepts `comparator` which - * is invoked to compare elements of `array`. The order of result values is - * determined by the order they occur in the array.The comparator is invoked - * with two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.uniqWith(objects, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] - */ - function uniqWith(array, comparator) { - comparator = typeof comparator == 'function' ? comparator : undefined; - return (array && array.length) ? baseUniq(array, undefined, comparator) : []; + for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + for (var children = select.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) { + if (child = children[k]) { + schedule(child, name, id, k, children, inherit); + } + } + subgroups.push(children); + parents.push(node); + } } + } - /** - * This method is like `_.zip` except that it accepts an array of grouped - * elements and creates an array regrouping the elements to their pre-zip - * configuration. - * - * @static - * @memberOf _ - * @since 1.2.0 - * @category Array - * @param {Array} array The array of grouped elements to process. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - * - * _.unzip(zipped); - * // => [['a', 'b'], [1, 2], [true, false]] - */ - function unzip(array) { - if (!(array && array.length)) { - return []; - } - var length = 0; - array = arrayFilter(array, function(group) { - if (isArrayLikeObject(group)) { - length = nativeMax(group.length, length); - return true; - } - }); - return baseTimes(length, function(index) { - return arrayMap(array, baseProperty(index)); - }); - } + return new Transition(subgroups, parents, name, id); +}; - /** - * This method is like `_.unzip` except that it accepts `iteratee` to specify - * how regrouped values should be combined. The iteratee is invoked with the - * elements of each group: (...group). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Array - * @param {Array} array The array of grouped elements to process. - * @param {Function} [iteratee=_.identity] The function to combine - * regrouped values. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip([1, 2], [10, 20], [100, 200]); - * // => [[1, 10, 100], [2, 20, 200]] - * - * _.unzipWith(zipped, _.add); - * // => [3, 30, 300] - */ - function unzipWith(array, iteratee) { - if (!(array && array.length)) { - return []; - } - var result = unzip(array); - if (iteratee == null) { - return result; - } - return arrayMap(result, function(group) { - return apply(iteratee, undefined, group); - }); - } +var Selection$1 = selection.prototype.constructor; - /** - * Creates an array excluding all given values using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * **Note:** Unlike `_.pull`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...*} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.difference, _.xor - * @example - * - * _.without([2, 1, 2, 3], 1, 2); - * // => [3] - */ - var without = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, values) - : []; - }); +var transition_selection = function() { + return new Selection$1(this._groups, this._parents); +}; - /** - * Creates an array of unique values that is the - * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) - * of the given arrays. The order of result values is determined by the order - * they occur in the arrays. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of filtered values. - * @see _.difference, _.without - * @example - * - * _.xor([2, 1], [2, 3]); - * // => [1, 3] - */ - var xor = baseRest(function(arrays) { - return baseXor(arrayFilter(arrays, isArrayLikeObject)); - }); +function styleRemove$1(name, interpolate$$1) { + var value00, + value10, + interpolate0; + return function() { + var value0 = styleValue(this, name), + value1 = (this.style.removeProperty(name), styleValue(this, name)); + return value0 === value1 ? null + : value0 === value00 && value1 === value10 ? interpolate0 + : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); + }; +} - /** - * This method is like `_.xor` except that it accepts `iteratee` which is - * invoked for each element of each `arrays` to generate the criterion by - * which by which they're compared. The order of result values is determined - * by the order they occur in the arrays. The iteratee is invoked with one - * argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [1.2, 3.4] - * - * // The `_.property` iteratee shorthand. - * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 2 }] - */ - var xorBy = baseRest(function(arrays) { - var iteratee = last(arrays); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; - } - return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2)); - }); +function styleRemoveEnd(name) { + return function() { + this.style.removeProperty(name); + }; +} - /** - * This method is like `_.xor` except that it accepts `comparator` which is - * invoked to compare elements of `arrays`. The order of result values is - * determined by the order they occur in the arrays. The comparator is invoked - * with two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.xorWith(objects, others, _.isEqual); - * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] - */ - var xorWith = baseRest(function(arrays) { - var comparator = last(arrays); - comparator = typeof comparator == 'function' ? comparator : undefined; - return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); - }); +function styleConstant$1(name, interpolate$$1, value1) { + var value00, + interpolate0; + return function() { + var value0 = styleValue(this, name); + return value0 === value1 ? null + : value0 === value00 ? interpolate0 + : interpolate0 = interpolate$$1(value00 = value0, value1); + }; +} - /** - * Creates an array of grouped elements, the first of which contains the - * first elements of the given arrays, the second of which contains the - * second elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - */ - var zip = baseRest(unzip); +function styleFunction$1(name, interpolate$$1, value) { + var value00, + value10, + interpolate0; + return function() { + var value0 = styleValue(this, name), + value1 = value(this); + if (value1 == null) value1 = (this.style.removeProperty(name), styleValue(this, name)); + return value0 === value1 ? null + : value0 === value00 && value1 === value10 ? interpolate0 + : interpolate0 = interpolate$$1(value00 = value0, value10 = value1); + }; +} - /** - * This method is like `_.fromPairs` except that it accepts two arrays, - * one of property identifiers and one of corresponding values. - * - * @static - * @memberOf _ - * @since 0.4.0 - * @category Array - * @param {Array} [props=[]] The property identifiers. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObject(['a', 'b'], [1, 2]); - * // => { 'a': 1, 'b': 2 } - */ - function zipObject(props, values) { - return baseZipObject(props || [], values || [], assignValue); - } +var transition_style = function(name, value, priority) { + var i = (name += "") === "transform" ? interpolateTransformCss : interpolate; + return value == null ? this + .styleTween(name, styleRemove$1(name, i)) + .on("end.style." + name, styleRemoveEnd(name)) + : this.styleTween(name, typeof value === "function" + ? styleFunction$1(name, i, tweenValue(this, "style." + name, value)) + : styleConstant$1(name, i, value + ""), priority); +}; - /** - * This method is like `_.zipObject` except that it supports property paths. - * - * @static - * @memberOf _ - * @since 4.1.0 - * @category Array - * @param {Array} [props=[]] The property identifiers. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); - * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } - */ - function zipObjectDeep(props, values) { - return baseZipObject(props || [], values || [], baseSet); - } +function styleTween(name, value, priority) { + function tween() { + var node = this, i = value.apply(node, arguments); + return i && function(t) { + node.style.setProperty(name, i(t), priority); + }; + } + tween._value = value; + return tween; +} - /** - * This method is like `_.zip` except that it accepts `iteratee` to specify - * how grouped values should be combined. The iteratee is invoked with the - * elements of each group: (...group). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @param {Function} [iteratee=_.identity] The function to combine - * grouped values. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { - * return a + b + c; - * }); - * // => [111, 222] - */ - var zipWith = baseRest(function(arrays) { - var length = arrays.length, - iteratee = length > 1 ? arrays[length - 1] : undefined; +var transition_styleTween = function(name, value, priority) { + var key = "style." + (name += ""); + if (arguments.length < 2) return (key = this.tween(key)) && key._value; + if (value == null) return this.tween(key, null); + if (typeof value !== "function") throw new Error; + return this.tween(key, styleTween(name, value, priority == null ? "" : priority)); +}; - iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; - return unzipWith(arrays, iteratee); - }); +function textConstant$1(value) { + return function() { + this.textContent = value; + }; +} - /*------------------------------------------------------------------------*/ +function textFunction$1(value) { + return function() { + var value1 = value(this); + this.textContent = value1 == null ? "" : value1; + }; +} - /** - * Creates a `lodash` wrapper instance that wraps `value` with explicit method - * chain sequences enabled. The result of such sequences must be unwrapped - * with `_#value`. - * - * @static - * @memberOf _ - * @since 1.3.0 - * @category Seq - * @param {*} value The value to wrap. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'pebbles', 'age': 1 } - * ]; - * - * var youngest = _ - * .chain(users) - * .sortBy('age') - * .map(function(o) { - * return o.user + ' is ' + o.age; - * }) - * .head() - * .value(); - * // => 'pebbles is 1' - */ - function chain(value) { - var result = lodash(value); - result.__chain__ = true; - return result; - } +var transition_text = function(value) { + return this.tween("text", typeof value === "function" + ? textFunction$1(tweenValue(this, "text", value)) + : textConstant$1(value == null ? "" : value + "")); +}; - /** - * This method invokes `interceptor` and returns `value`. The interceptor - * is invoked with one argument; (value). The purpose of this method is to - * "tap into" a method chain sequence in order to modify intermediate results. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @returns {*} Returns `value`. - * @example - * - * _([1, 2, 3]) - * .tap(function(array) { - * // Mutate input array. - * array.pop(); - * }) - * .reverse() - * .value(); - * // => [2, 1] - */ - function tap(value, interceptor) { - interceptor(value); - return value; - } +var transition_transition = function() { + var name = this._name, + id0 = this._id, + id1 = newId(); - /** - * This method is like `_.tap` except that it returns the result of `interceptor`. - * The purpose of this method is to "pass thru" values replacing intermediate - * results in a method chain sequence. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Seq - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @returns {*} Returns the result of `interceptor`. - * @example - * - * _(' abc ') - * .chain() - * .trim() - * .thru(function(value) { - * return [value]; - * }) - * .value(); - * // => ['abc'] - */ - function thru(value, interceptor) { - return interceptor(value); + for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + var inherit = get$1(node, id0); + schedule(node, name, id1, i, group, { + time: inherit.time + inherit.delay + inherit.duration, + delay: 0, + duration: inherit.duration, + ease: inherit.ease + }); + } } + } - /** - * This method is the wrapper version of `_.at`. - * - * @name at - * @memberOf _ - * @since 1.0.0 - * @category Seq - * @param {...(string|string[])} [paths] The property paths to pick. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; - * - * _(object).at(['a[0].b.c', 'a[1]']).value(); - * // => [3, 4] - */ - var wrapperAt = flatRest(function(paths) { - var length = paths.length, - start = length ? paths[0] : 0, - value = this.__wrapped__, - interceptor = function(object) { return baseAt(object, paths); }; - - if (length > 1 || this.__actions__.length || - !(value instanceof LazyWrapper) || !isIndex(start)) { - return this.thru(interceptor); - } - value = value.slice(start, +start + (length ? 1 : 0)); - value.__actions__.push({ - 'func': thru, - 'args': [interceptor], - 'thisArg': undefined - }); - return new LodashWrapper(value, this.__chain__).thru(function(array) { - if (length && !array.length) { - array.push(undefined); - } - return array; - }); - }); + return new Transition(groups, this._parents, name, id1); +}; - /** - * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. - * - * @name chain - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; - * - * // A sequence without explicit chaining. - * _(users).head(); - * // => { 'user': 'barney', 'age': 36 } - * - * // A sequence with explicit chaining. - * _(users) - * .chain() - * .head() - * .pick('user') - * .value(); - * // => { 'user': 'barney' } - */ - function wrapperChain() { - return chain(this); - } +var id = 0; - /** - * Executes the chain sequence and returns the wrapped result. - * - * @name commit - * @memberOf _ - * @since 3.2.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2]; - * var wrapped = _(array).push(3); - * - * console.log(array); - * // => [1, 2] - * - * wrapped = wrapped.commit(); - * console.log(array); - * // => [1, 2, 3] - * - * wrapped.last(); - * // => 3 - * - * console.log(array); - * // => [1, 2, 3] - */ - function wrapperCommit() { - return new LodashWrapper(this.value(), this.__chain__); - } +function Transition(groups, parents, name, id) { + this._groups = groups; + this._parents = parents; + this._name = name; + this._id = id; +} - /** - * Gets the next value on a wrapped object following the - * [iterator protocol](https://mdn.io/iteration_protocols#iterator). - * - * @name next - * @memberOf _ - * @since 4.0.0 - * @category Seq - * @returns {Object} Returns the next iterator value. - * @example - * - * var wrapped = _([1, 2]); - * - * wrapped.next(); - * // => { 'done': false, 'value': 1 } - * - * wrapped.next(); - * // => { 'done': false, 'value': 2 } - * - * wrapped.next(); - * // => { 'done': true, 'value': undefined } - */ - function wrapperNext() { - if (this.__values__ === undefined) { - this.__values__ = toArray(this.value()); - } - var done = this.__index__ >= this.__values__.length, - value = done ? undefined : this.__values__[this.__index__++]; +function transition(name) { + return selection().transition(name); +} - return { 'done': done, 'value': value }; - } +function newId() { + return ++id; +} - /** - * Enables the wrapper to be iterable. - * - * @name Symbol.iterator - * @memberOf _ - * @since 4.0.0 - * @category Seq - * @returns {Object} Returns the wrapper object. - * @example - * - * var wrapped = _([1, 2]); - * - * wrapped[Symbol.iterator]() === wrapped; - * // => true - * - * Array.from(wrapped); - * // => [1, 2] - */ - function wrapperToIterator() { - return this; - } +var selection_prototype = selection.prototype; - /** - * Creates a clone of the chain sequence planting `value` as the wrapped value. - * - * @name plant - * @memberOf _ - * @since 3.2.0 - * @category Seq - * @param {*} value The value to plant. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var wrapped = _([1, 2]).map(square); - * var other = wrapped.plant([3, 4]); - * - * other.value(); - * // => [9, 16] - * - * wrapped.value(); - * // => [1, 4] - */ - function wrapperPlant(value) { - var result, - parent = this; - - while (parent instanceof baseLodash) { - var clone = wrapperClone(parent); - clone.__index__ = 0; - clone.__values__ = undefined; - if (result) { - previous.__wrapped__ = clone; - } else { - result = clone; - } - var previous = clone; - parent = parent.__wrapped__; - } - previous.__wrapped__ = value; - return result; - } +Transition.prototype = transition.prototype = { + constructor: Transition, + select: transition_select, + selectAll: transition_selectAll, + filter: transition_filter, + merge: transition_merge, + selection: transition_selection, + transition: transition_transition, + call: selection_prototype.call, + nodes: selection_prototype.nodes, + node: selection_prototype.node, + size: selection_prototype.size, + empty: selection_prototype.empty, + each: selection_prototype.each, + on: transition_on, + attr: transition_attr, + attrTween: transition_attrTween, + style: transition_style, + styleTween: transition_styleTween, + text: transition_text, + remove: transition_remove, + tween: transition_tween, + delay: transition_delay, + duration: transition_duration, + ease: transition_ease +}; - /** - * This method is the wrapper version of `_.reverse`. - * - * **Note:** This method mutates the wrapped array. - * - * @name reverse - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2, 3]; - * - * _(array).reverse().value() - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function wrapperReverse() { - var value = this.__wrapped__; - if (value instanceof LazyWrapper) { - var wrapped = value; - if (this.__actions__.length) { - wrapped = new LazyWrapper(this); - } - wrapped = wrapped.reverse(); - wrapped.__actions__.push({ - 'func': thru, - 'args': [reverse], - 'thisArg': undefined - }); - return new LodashWrapper(wrapped, this.__chain__); - } - return this.thru(reverse); - } +function linear$1(t) { + return +t; +} - /** - * Executes the chain sequence to resolve the unwrapped value. - * - * @name value - * @memberOf _ - * @since 0.1.0 - * @alias toJSON, valueOf - * @category Seq - * @returns {*} Returns the resolved unwrapped value. - * @example - * - * _([1, 2, 3]).value(); - * // => [1, 2, 3] - */ - function wrapperValue() { - return baseWrapperValue(this.__wrapped__, this.__actions__); - } +function quadIn(t) { + return t * t; +} - /*------------------------------------------------------------------------*/ +function quadOut(t) { + return t * (2 - t); +} - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The corresponding value of - * each key is the number of times the key was returned by `iteratee`. The - * iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([6.1, 4.2, 6.3], Math.floor); - * // => { '4': 1, '6': 2 } - * - * // The `_.property` iteratee shorthand. - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - ++result[key]; - } else { - baseAssignValue(result, key, 1); - } - }); +function quadInOut(t) { + return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2; +} - /** - * Checks if `predicate` returns truthy for **all** elements of `collection`. - * Iteration is stopped once `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index|key, collection). - * - * **Note:** This method returns `true` for - * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because - * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of - * elements of empty collections. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes'], Boolean); - * // => false - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.every(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // The `_.matchesProperty` iteratee shorthand. - * _.every(users, ['active', false]); - * // => true - * - * // The `_.property` iteratee shorthand. - * _.every(users, 'active'); - * // => false - */ - function every(collection, predicate, guard) { - var func = isArray(collection) ? arrayEvery : baseEvery; - if (guard && isIterateeCall(collection, predicate, guard)) { - predicate = undefined; - } - return func(collection, getIteratee(predicate, 3)); - } +function cubicIn(t) { + return t * t * t; +} - /** - * Iterates over elements of `collection`, returning an array of all elements - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * **Note:** Unlike `_.remove`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - * @see _.reject - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * _.filter(users, function(o) { return !o.active; }); - * // => objects for ['fred'] - * - * // The `_.matches` iteratee shorthand. - * _.filter(users, { 'age': 36, 'active': true }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.filter(users, ['active', false]); - * // => objects for ['fred'] - * - * // The `_.property` iteratee shorthand. - * _.filter(users, 'active'); - * // => objects for ['barney'] - */ - function filter(collection, predicate) { - var func = isArray(collection) ? arrayFilter : baseFilter; - return func(collection, getIteratee(predicate, 3)); - } +function cubicOut(t) { + return --t * t * t + 1; +} - /** - * Iterates over elements of `collection`, returning the first element - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * _.find(users, function(o) { return o.age < 40; }); - * // => object for 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.find(users, { 'age': 1, 'active': true }); - * // => object for 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.find(users, ['active', false]); - * // => object for 'fred' - * - * // The `_.property` iteratee shorthand. - * _.find(users, 'active'); - * // => object for 'barney' - */ - var find = createFind(findIndex); +function cubicInOut(t) { + return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; +} - /** - * This method is like `_.find` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Collection - * @param {Array|Object} collection The collection to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=collection.length-1] The index to search from. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(n) { - * return n % 2 == 1; - * }); - * // => 3 - */ - var findLast = createFind(findLastIndex); +var exponent = 3; - /** - * Creates a flattened array of values by running each element in `collection` - * thru `iteratee` and flattening the mapped results. The iteratee is invoked - * with three arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [n, n]; - * } - * - * _.flatMap([1, 2], duplicate); - * // => [1, 1, 2, 2] - */ - function flatMap(collection, iteratee) { - return baseFlatten(map(collection, iteratee), 1); - } +var polyIn = (function custom(e) { + e = +e; - /** - * This method is like `_.flatMap` except that it recursively flattens the - * mapped results. - * - * @static - * @memberOf _ - * @since 4.7.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [[[n, n]]]; - * } - * - * _.flatMapDeep([1, 2], duplicate); - * // => [1, 1, 2, 2] - */ - function flatMapDeep(collection, iteratee) { - return baseFlatten(map(collection, iteratee), INFINITY); - } + function polyIn(t) { + return Math.pow(t, e); + } - /** - * This method is like `_.flatMap` except that it recursively flattens the - * mapped results up to `depth` times. - * - * @static - * @memberOf _ - * @since 4.7.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {number} [depth=1] The maximum recursion depth. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [[[n, n]]]; - * } - * - * _.flatMapDepth([1, 2], duplicate, 2); - * // => [[1, 1], [2, 2]] - */ - function flatMapDepth(collection, iteratee, depth) { - depth = depth === undefined ? 1 : toInteger(depth); - return baseFlatten(map(collection, iteratee), depth); - } + polyIn.exponent = custom; - /** - * Iterates over elements of `collection` and invokes `iteratee` for each element. - * The iteratee is invoked with three arguments: (value, index|key, collection). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * **Note:** As with other "Collections" methods, objects with a "length" - * property are iterated like arrays. To avoid this behavior use `_.forIn` - * or `_.forOwn` for object iteration. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias each - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - * @see _.forEachRight - * @example - * - * _.forEach([1, 2], function(value) { - * console.log(value); - * }); - * // => Logs `1` then `2`. - * - * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a' then 'b' (iteration order is not guaranteed). - */ - function forEach(collection, iteratee) { - var func = isArray(collection) ? arrayEach : baseEach; - return func(collection, getIteratee(iteratee, 3)); - } + return polyIn; +})(exponent); - /** - * This method is like `_.forEach` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @alias eachRight - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - * @see _.forEach - * @example - * - * _.forEachRight([1, 2], function(value) { - * console.log(value); - * }); - * // => Logs `2` then `1`. - */ - function forEachRight(collection, iteratee) { - var func = isArray(collection) ? arrayEachRight : baseEachRight; - return func(collection, getIteratee(iteratee, 3)); - } +var polyOut = (function custom(e) { + e = +e; - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The order of grouped values - * is determined by the order they occur in `collection`. The corresponding - * value of each key is an array of elements responsible for generating the - * key. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([6.1, 4.2, 6.3], Math.floor); - * // => { '4': [4.2], '6': [6.1, 6.3] } - * - * // The `_.property` iteratee shorthand. - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - result[key].push(value); - } else { - baseAssignValue(result, key, [value]); - } - }); + function polyOut(t) { + return 1 - Math.pow(1 - t, e); + } - /** - * Checks if `value` is in `collection`. If `collection` is a string, it's - * checked for a substring of `value`, otherwise - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * is used for equality comparisons. If `fromIndex` is negative, it's used as - * the offset from the end of `collection`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object|string} collection The collection to inspect. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. - * @returns {boolean} Returns `true` if `value` is found, else `false`. - * @example - * - * _.includes([1, 2, 3], 1); - * // => true - * - * _.includes([1, 2, 3], 1, 2); - * // => false - * - * _.includes({ 'a': 1, 'b': 2 }, 1); - * // => true - * - * _.includes('abcd', 'bc'); - * // => true - */ - function includes(collection, value, fromIndex, guard) { - collection = isArrayLike(collection) ? collection : values(collection); - fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + polyOut.exponent = custom; - var length = collection.length; - if (fromIndex < 0) { - fromIndex = nativeMax(length + fromIndex, 0); - } - return isString(collection) - ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) - : (!!length && baseIndexOf(collection, value, fromIndex) > -1); - } + return polyOut; +})(exponent); - /** - * Invokes the method at `path` of each element in `collection`, returning - * an array of the results of each invoked method. Any additional arguments - * are provided to each invoked method. If `path` is a function, it's invoked - * for, and `this` bound to, each element in `collection`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Array|Function|string} path The path of the method to invoke or - * the function invoked per iteration. - * @param {...*} [args] The arguments to invoke each method with. - * @returns {Array} Returns the array of results. - * @example - * - * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invokeMap([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - var invokeMap = baseRest(function(collection, path, args) { - var index = -1, - isFunc = typeof path == 'function', - result = isArrayLike(collection) ? Array(collection.length) : []; +var polyInOut = (function custom(e) { + e = +e; - baseEach(collection, function(value) { - result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); - }); - return result; - }); + function polyInOut(t) { + return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2; + } - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The corresponding value of - * each key is the last element responsible for generating the key. The - * iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var array = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.keyBy(array, function(o) { - * return String.fromCharCode(o.code); - * }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.keyBy(array, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - */ - var keyBy = createAggregator(function(result, value, key) { - baseAssignValue(result, key, value); - }); + polyInOut.exponent = custom; - /** - * Creates an array of values by running each element in `collection` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. - * - * The guarded methods are: - * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, - * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, - * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, - * `template`, `trim`, `trimEnd`, `trimStart`, and `words` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - * @example - * - * function square(n) { - * return n * n; - * } - * - * _.map([4, 8], square); - * // => [16, 64] - * - * _.map({ 'a': 4, 'b': 8 }, square); - * // => [16, 64] (iteration order is not guaranteed) - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * // The `_.property` iteratee shorthand. - * _.map(users, 'user'); - * // => ['barney', 'fred'] - */ - function map(collection, iteratee) { - var func = isArray(collection) ? arrayMap : baseMap; - return func(collection, getIteratee(iteratee, 3)); - } + return polyInOut; +})(exponent); - /** - * This method is like `_.sortBy` except that it allows specifying the sort - * orders of the iteratees to sort by. If `orders` is unspecified, all values - * are sorted in ascending order. Otherwise, specify an order of "desc" for - * descending or "asc" for ascending sort order of corresponding values. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] - * The iteratees to sort by. - * @param {string[]} [orders] The sort orders of `iteratees`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 34 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 36 } - * ]; - * - * // Sort by `user` in ascending order and by `age` in descending order. - * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - */ - function orderBy(collection, iteratees, orders, guard) { - if (collection == null) { - return []; - } - if (!isArray(iteratees)) { - iteratees = iteratees == null ? [] : [iteratees]; - } - orders = guard ? undefined : orders; - if (!isArray(orders)) { - orders = orders == null ? [] : [orders]; - } - return baseOrderBy(collection, iteratees, orders); - } +var pi = Math.PI; +var halfPi = pi / 2; - /** - * Creates an array of elements split into two groups, the first of which - * contains elements `predicate` returns truthy for, the second of which - * contains elements `predicate` returns falsey for. The predicate is - * invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the array of grouped elements. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * _.partition(users, function(o) { return o.active; }); - * // => objects for [['fred'], ['barney', 'pebbles']] - * - * // The `_.matches` iteratee shorthand. - * _.partition(users, { 'age': 1, 'active': false }); - * // => objects for [['pebbles'], ['barney', 'fred']] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.partition(users, ['active', false]); - * // => objects for [['barney', 'pebbles'], ['fred']] - * - * // The `_.property` iteratee shorthand. - * _.partition(users, 'active'); - * // => objects for [['fred'], ['barney', 'pebbles']] - */ - var partition = createAggregator(function(result, value, key) { - result[key ? 0 : 1].push(value); - }, function() { return [[], []]; }); +function sinIn(t) { + return 1 - Math.cos(t * halfPi); +} - /** - * Reduces `collection` to a value which is the accumulated result of running - * each element in `collection` thru `iteratee`, where each successive - * invocation is supplied the return value of the previous. If `accumulator` - * is not given, the first element of `collection` is used as the initial - * value. The iteratee is invoked with four arguments: - * (accumulator, value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.reduce`, `_.reduceRight`, and `_.transform`. - * - * The guarded methods are: - * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, - * and `sortBy` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @returns {*} Returns the accumulated value. - * @see _.reduceRight - * @example - * - * _.reduce([1, 2], function(sum, n) { - * return sum + n; - * }, 0); - * // => 3 - * - * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { - * (result[value] || (result[value] = [])).push(key); - * return result; - * }, {}); - * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) - */ - function reduce(collection, iteratee, accumulator) { - var func = isArray(collection) ? arrayReduce : baseReduce, - initAccum = arguments.length < 3; +function sinOut(t) { + return Math.sin(t * halfPi); +} - return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); - } +function sinInOut(t) { + return (1 - Math.cos(pi * t)) / 2; +} - /** - * This method is like `_.reduce` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @returns {*} Returns the accumulated value. - * @see _.reduce - * @example - * - * var array = [[0, 1], [2, 3], [4, 5]]; - * - * _.reduceRight(array, function(flattened, other) { - * return flattened.concat(other); - * }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, iteratee, accumulator) { - var func = isArray(collection) ? arrayReduceRight : baseReduce, - initAccum = arguments.length < 3; +function expIn(t) { + return Math.pow(2, 10 * t - 10); +} - return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); - } +function expOut(t) { + return 1 - Math.pow(2, -10 * t); +} - /** - * The opposite of `_.filter`; this method returns the elements of `collection` - * that `predicate` does **not** return truthy for. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - * @see _.filter - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true } - * ]; - * - * _.reject(users, function(o) { return !o.active; }); - * // => objects for ['fred'] - * - * // The `_.matches` iteratee shorthand. - * _.reject(users, { 'age': 40, 'active': true }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.reject(users, ['active', false]); - * // => objects for ['fred'] - * - * // The `_.property` iteratee shorthand. - * _.reject(users, 'active'); - * // => objects for ['barney'] - */ - function reject(collection, predicate) { - var func = isArray(collection) ? arrayFilter : baseFilter; - return func(collection, negate(getIteratee(predicate, 3))); - } +function expInOut(t) { + return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2; +} - /** - * Gets a random element from `collection`. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Collection - * @param {Array|Object} collection The collection to sample. - * @returns {*} Returns the random element. - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - */ - function sample(collection) { - var func = isArray(collection) ? arraySample : baseSample; - return func(collection); - } +function circleIn(t) { + return 1 - Math.sqrt(1 - t * t); +} - /** - * Gets `n` random elements at unique keys from `collection` up to the - * size of `collection`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to sample. - * @param {number} [n=1] The number of elements to sample. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the random elements. - * @example - * - * _.sampleSize([1, 2, 3], 2); - * // => [3, 1] - * - * _.sampleSize([1, 2, 3], 4); - * // => [2, 3, 1] - */ - function sampleSize(collection, n, guard) { - if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) { - n = 1; - } else { - n = toInteger(n); - } - var func = isArray(collection) ? arraySampleSize : baseSampleSize; - return func(collection, n); - } +function circleOut(t) { + return Math.sqrt(1 - --t * t); +} - /** - * Creates an array of shuffled values, using a version of the - * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to shuffle. - * @returns {Array} Returns the new shuffled array. - * @example - * - * _.shuffle([1, 2, 3, 4]); - * // => [4, 1, 3, 2] - */ - function shuffle(collection) { - var func = isArray(collection) ? arrayShuffle : baseShuffle; - return func(collection); - } +function circleInOut(t) { + return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2; +} - /** - * Gets the size of `collection` by returning its length for array-like - * values or the number of own enumerable string keyed properties for objects. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns the collection size. - * @example - * - * _.size([1, 2, 3]); - * // => 3 - * - * _.size({ 'a': 1, 'b': 2 }); - * // => 2 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - if (collection == null) { - return 0; - } - if (isArrayLike(collection)) { - return isString(collection) ? stringSize(collection) : collection.length; - } - var tag = getTag(collection); - if (tag == mapTag || tag == setTag) { - return collection.size; - } - return baseKeys(collection).length; - } +var b1 = 4 / 11; +var b2 = 6 / 11; +var b3 = 8 / 11; +var b4 = 3 / 4; +var b5 = 9 / 11; +var b6 = 10 / 11; +var b7 = 15 / 16; +var b8 = 21 / 22; +var b9 = 63 / 64; +var b0 = 1 / b1 / b1; - /** - * Checks if `predicate` returns truthy for **any** element of `collection`. - * Iteration is stopped once `predicate` returns truthy. The predicate is - * invoked with three arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.some(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // The `_.matchesProperty` iteratee shorthand. - * _.some(users, ['active', false]); - * // => true - * - * // The `_.property` iteratee shorthand. - * _.some(users, 'active'); - * // => true - */ - function some(collection, predicate, guard) { - var func = isArray(collection) ? arraySome : baseSome; - if (guard && isIterateeCall(collection, predicate, guard)) { - predicate = undefined; - } - return func(collection, getIteratee(predicate, 3)); - } +function bounceIn(t) { + return 1 - bounceOut(1 - t); +} - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection thru each iteratee. This method - * performs a stable sort, that is, it preserves the original sort order of - * equal elements. The iteratees are invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {...(Function|Function[])} [iteratees=[_.identity]] - * The iteratees to sort by. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 34 } - * ]; - * - * _.sortBy(users, [function(o) { return o.user; }]); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - * - * _.sortBy(users, ['user', 'age']); - * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]] - */ - var sortBy = baseRest(function(collection, iteratees) { - if (collection == null) { - return []; - } - var length = iteratees.length; - if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { - iteratees = []; - } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { - iteratees = [iteratees[0]]; - } - return baseOrderBy(collection, baseFlatten(iteratees, 1), []); - }); +function bounceOut(t) { + return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9; +} - /*------------------------------------------------------------------------*/ +function bounceInOut(t) { + return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2; +} - /** - * Gets the timestamp of the number of milliseconds that have elapsed since - * the Unix epoch (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Date - * @returns {number} Returns the timestamp. - * @example - * - * _.defer(function(stamp) { - * console.log(_.now() - stamp); - * }, _.now()); - * // => Logs the number of milliseconds it took for the deferred invocation. - */ - var now = ctxNow || function() { - return root.Date.now(); - }; +var overshoot = 1.70158; - /*------------------------------------------------------------------------*/ +var backIn = (function custom(s) { + s = +s; - /** - * The opposite of `_.before`; this method creates a function that invokes - * `func` once it's called `n` or more times. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {number} n The number of calls before `func` is invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => Logs 'done saving!' after the two async saves have completed. - */ - function after(n, func) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - n = toInteger(n); - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } + function backIn(t) { + return t * t * ((s + 1) * t - s); + } - /** - * Creates a function that invokes `func`, with up to `n` arguments, - * ignoring any additional arguments. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to cap arguments for. - * @param {number} [n=func.length] The arity cap. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new capped function. - * @example - * - * _.map(['6', '8', '10'], _.ary(parseInt, 1)); - * // => [6, 8, 10] - */ - function ary(func, n, guard) { - n = guard ? undefined : n; - n = (func && n == null) ? func.length : n; - return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n); - } + backIn.overshoot = custom; - /** - * Creates a function that invokes `func`, with the `this` binding and arguments - * of the created function, while it's called less than `n` times. Subsequent - * calls to the created function return the result of the last `func` invocation. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {number} n The number of calls at which `func` is no longer invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * jQuery(element).on('click', _.before(5, addContactToList)); - * // => Allows adding up to 4 contacts to the list. - */ - function before(n, func) { - var result; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - n = toInteger(n); - return function() { - if (--n > 0) { - result = func.apply(this, arguments); - } - if (n <= 1) { - func = undefined; - } - return result; - }; - } + return backIn; +})(overshoot); - /** - * Creates a function that invokes `func` with the `this` binding of `thisArg` - * and `partials` prepended to the arguments it receives. - * - * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for partially applied arguments. - * - * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" - * property of bound functions. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * function greet(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * } - * - * var object = { 'user': 'fred' }; - * - * var bound = _.bind(greet, object, 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * // Bound with placeholders. - * var bound = _.bind(greet, object, _, '!'); - * bound('hi'); - * // => 'hi fred!' - */ - var bind = baseRest(function(func, thisArg, partials) { - var bitmask = WRAP_BIND_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, getHolder(bind)); - bitmask |= WRAP_PARTIAL_FLAG; - } - return createWrap(func, bitmask, thisArg, partials, holders); - }); +var backOut = (function custom(s) { + s = +s; - /** - * Creates a function that invokes the method at `object[key]` with `partials` - * prepended to the arguments it receives. - * - * This method differs from `_.bind` by allowing bound functions to reference - * methods that may be redefined or don't yet exist. See - * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) - * for more details. - * - * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * @static - * @memberOf _ - * @since 0.10.0 - * @category Function - * @param {Object} object The object to invoke the method on. - * @param {string} key The key of the method. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'user': 'fred', - * 'greet': function(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * } - * }; - * - * var bound = _.bindKey(object, 'greet', 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * object.greet = function(greeting, punctuation) { - * return greeting + 'ya ' + this.user + punctuation; - * }; - * - * bound('!'); - * // => 'hiya fred!' - * - * // Bound with placeholders. - * var bound = _.bindKey(object, 'greet', _, '!'); - * bound('hi'); - * // => 'hiya fred!' - */ - var bindKey = baseRest(function(object, key, partials) { - var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, getHolder(bindKey)); - bitmask |= WRAP_PARTIAL_FLAG; - } - return createWrap(key, bitmask, object, partials, holders); - }); + function backOut(t) { + return --t * t * ((s + 1) * t + s) + 1; + } - /** - * Creates a function that accepts arguments of `func` and either invokes - * `func` returning its result, if at least `arity` number of arguments have - * been provided, or returns a function that accepts the remaining `func` - * arguments, and so on. The arity of `func` may be specified if `func.length` - * is not sufficient. - * - * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for provided arguments. - * - * **Note:** This method doesn't set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curry(abc); - * - * curried(1)(2)(3); - * // => [1, 2, 3] - * - * curried(1, 2)(3); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // Curried with placeholders. - * curried(1)(_, 3)(2); - * // => [1, 2, 3] - */ - function curry(func, arity, guard) { - arity = guard ? undefined : arity; - var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); - result.placeholder = curry.placeholder; - return result; - } + backOut.overshoot = custom; - /** - * This method is like `_.curry` except that arguments are applied to `func` - * in the manner of `_.partialRight` instead of `_.partial`. - * - * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for provided arguments. - * - * **Note:** This method doesn't set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curryRight(abc); - * - * curried(3)(2)(1); - * // => [1, 2, 3] - * - * curried(2, 3)(1); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // Curried with placeholders. - * curried(3)(1, _)(2); - * // => [1, 2, 3] - */ - function curryRight(func, arity, guard) { - arity = guard ? undefined : arity; - var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); - result.placeholder = curryRight.placeholder; - return result; - } + return backOut; +})(overshoot); - /** - * Creates a debounced function that delays invoking `func` until after `wait` - * milliseconds have elapsed since the last time the debounced function was - * invoked. The debounced function comes with a `cancel` method to cancel - * delayed `func` invocations and a `flush` method to immediately invoke them. - * Provide `options` to indicate whether `func` should be invoked on the - * leading and/or trailing edge of the `wait` timeout. The `func` is invoked - * with the last arguments provided to the debounced function. Subsequent - * calls to the debounced function return the result of the last `func` - * invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is - * invoked on the trailing edge of the timeout only if the debounced function - * is invoked more than once during the `wait` timeout. - * - * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred - * until to the next tick, similar to `setTimeout` with a timeout of `0`. - * - * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) - * for details over the differences between `_.debounce` and `_.throttle`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to debounce. - * @param {number} [wait=0] The number of milliseconds to delay. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.leading=false] - * Specify invoking on the leading edge of the timeout. - * @param {number} [options.maxWait] - * The maximum time `func` is allowed to be delayed before it's invoked. - * @param {boolean} [options.trailing=true] - * Specify invoking on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // Avoid costly calculations while the window size is in flux. - * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); - * - * // Invoke `sendMail` when clicked, debouncing subsequent calls. - * jQuery(element).on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * })); - * - * // Ensure `batchLog` is invoked once after 1 second of debounced calls. - * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); - * var source = new EventSource('/stream'); - * jQuery(source).on('message', debounced); - * - * // Cancel the trailing debounced invocation. - * jQuery(window).on('popstate', debounced.cancel); - */ - function debounce(func, wait, options) { - var lastArgs, - lastThis, - maxWait, - result, - timerId, - lastCallTime, - lastInvokeTime = 0, - leading = false, - maxing = false, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - wait = toNumber(wait) || 0; - if (isObject(options)) { - leading = !!options.leading; - maxing = 'maxWait' in options; - maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } +var backInOut = (function custom(s) { + s = +s; - function invokeFunc(time) { - var args = lastArgs, - thisArg = lastThis; + function backInOut(t) { + return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2; + } - lastArgs = lastThis = undefined; - lastInvokeTime = time; - result = func.apply(thisArg, args); - return result; - } + backInOut.overshoot = custom; - function leadingEdge(time) { - // Reset any `maxWait` timer. - lastInvokeTime = time; - // Start the timer for the trailing edge. - timerId = setTimeout(timerExpired, wait); - // Invoke the leading edge. - return leading ? invokeFunc(time) : result; - } + return backInOut; +})(overshoot); - function remainingWait(time) { - var timeSinceLastCall = time - lastCallTime, - timeSinceLastInvoke = time - lastInvokeTime, - result = wait - timeSinceLastCall; +var tau = 2 * Math.PI; +var amplitude = 1; +var period = 0.3; - return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; - } +var elasticIn = (function custom(a, p) { + var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); - function shouldInvoke(time) { - var timeSinceLastCall = time - lastCallTime, - timeSinceLastInvoke = time - lastInvokeTime; + function elasticIn(t) { + return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p); + } - // Either this is the first call, activity has stopped and we're at the - // trailing edge, the system time has gone backwards and we're treating - // it as the trailing edge, or we've hit the `maxWait` limit. - return (lastCallTime === undefined || (timeSinceLastCall >= wait) || - (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); - } + elasticIn.amplitude = function(a) { return custom(a, p * tau); }; + elasticIn.period = function(p) { return custom(a, p); }; - function timerExpired() { - var time = now(); - if (shouldInvoke(time)) { - return trailingEdge(time); - } - // Restart the timer. - timerId = setTimeout(timerExpired, remainingWait(time)); - } + return elasticIn; +})(amplitude, period); - function trailingEdge(time) { - timerId = undefined; +var elasticOut = (function custom(a, p) { + var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); - // Only invoke if we have `lastArgs` which means `func` has been - // debounced at least once. - if (trailing && lastArgs) { - return invokeFunc(time); - } - lastArgs = lastThis = undefined; - return result; - } + function elasticOut(t) { + return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p); + } - function cancel() { - if (timerId !== undefined) { - clearTimeout(timerId); - } - lastInvokeTime = 0; - lastArgs = lastCallTime = lastThis = timerId = undefined; - } + elasticOut.amplitude = function(a) { return custom(a, p * tau); }; + elasticOut.period = function(p) { return custom(a, p); }; - function flush() { - return timerId === undefined ? result : trailingEdge(now()); - } + return elasticOut; +})(amplitude, period); - function debounced() { - var time = now(), - isInvoking = shouldInvoke(time); +var elasticInOut = (function custom(a, p) { + var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); - lastArgs = arguments; - lastThis = this; - lastCallTime = time; + function elasticInOut(t) { + return ((t = t * 2 - 1) < 0 + ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p) + : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2; + } - if (isInvoking) { - if (timerId === undefined) { - return leadingEdge(lastCallTime); - } - if (maxing) { - // Handle invocations in a tight loop. - timerId = setTimeout(timerExpired, wait); - return invokeFunc(lastCallTime); - } - } - if (timerId === undefined) { - timerId = setTimeout(timerExpired, wait); - } - return result; - } - debounced.cancel = cancel; - debounced.flush = flush; - return debounced; - } + elasticInOut.amplitude = function(a) { return custom(a, p * tau); }; + elasticInOut.period = function(p) { return custom(a, p); }; - /** - * Defers invoking the `func` until the current call stack has cleared. Any - * additional arguments are provided to `func` when it's invoked. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to defer. - * @param {...*} [args] The arguments to invoke `func` with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { - * console.log(text); - * }, 'deferred'); - * // => Logs 'deferred' after one millisecond. - */ - var defer = baseRest(function(func, args) { - return baseDelay(func, 1, args); - }); + return elasticInOut; +})(amplitude, period); - /** - * Invokes `func` after `wait` milliseconds. Any additional arguments are - * provided to `func` when it's invoked. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {...*} [args] The arguments to invoke `func` with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { - * console.log(text); - * }, 1000, 'later'); - * // => Logs 'later' after one second. - */ - var delay = baseRest(function(func, wait, args) { - return baseDelay(func, toNumber(wait) || 0, args); - }); +var defaultTiming = { + time: null, // Set on use. + delay: 0, + duration: 250, + ease: cubicInOut +}; - /** - * Creates a function that invokes `func` with arguments reversed. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to flip arguments for. - * @returns {Function} Returns the new flipped function. - * @example - * - * var flipped = _.flip(function() { - * return _.toArray(arguments); - * }); - * - * flipped('a', 'b', 'c', 'd'); - * // => ['d', 'c', 'b', 'a'] - */ - function flip(func) { - return createWrap(func, WRAP_FLIP_FLAG); +function inherit(node, id) { + var timing; + while (!(timing = node.__transition) || !(timing = timing[id])) { + if (!(node = node.parentNode)) { + return defaultTiming.time = now(), defaultTiming; } + } + return timing; +} - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ - function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; - } +var selection_transition = function(name) { + var id, + timing; - // Expose `MapCache`. - memoize.Cache = MapCache; + if (name instanceof Transition) { + id = name._id, name = name._name; + } else { + id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + ""; + } - /** - * Creates a function that negates the result of the predicate `func`. The - * `func` predicate is invoked with the `this` binding and arguments of the - * created function. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} predicate The predicate to negate. - * @returns {Function} Returns the new negated function. - * @example - * - * function isEven(n) { - * return n % 2 == 0; - * } - * - * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); - * // => [1, 3, 5] - */ - function negate(predicate) { - if (typeof predicate != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); + for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + schedule(node, name, id, i, group, timing || inherit(node, id)); } - return function() { - var args = arguments; - switch (args.length) { - case 0: return !predicate.call(this); - case 1: return !predicate.call(this, args[0]); - case 2: return !predicate.call(this, args[0], args[1]); - case 3: return !predicate.call(this, args[0], args[1], args[2]); - } - return !predicate.apply(this, args); - }; - } - - /** - * Creates a function that is restricted to invoking `func` once. Repeat calls - * to the function return the value of the first invocation. The `func` is - * invoked with the `this` binding and arguments of the created function. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // => `createApplication` is invoked once - */ - function once(func) { - return before(2, func); } + } - /** - * Creates a function that invokes `func` with its arguments transformed. - * - * @static - * @since 4.0.0 - * @memberOf _ - * @category Function - * @param {Function} func The function to wrap. - * @param {...(Function|Function[])} [transforms=[_.identity]] - * The argument transforms. - * @returns {Function} Returns the new function. - * @example - * - * function doubled(n) { - * return n * 2; - * } - * - * function square(n) { - * return n * n; - * } - * - * var func = _.overArgs(function(x, y) { - * return [x, y]; - * }, [square, doubled]); - * - * func(9, 3); - * // => [81, 6] - * - * func(10, 5); - * // => [100, 10] - */ - var overArgs = castRest(function(func, transforms) { - transforms = (transforms.length == 1 && isArray(transforms[0])) - ? arrayMap(transforms[0], baseUnary(getIteratee())) - : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); - - var funcsLength = transforms.length; - return baseRest(function(args) { - var index = -1, - length = nativeMin(args.length, funcsLength); - - while (++index < length) { - args[index] = transforms[index].call(this, args[index]); - } - return apply(func, this, args); - }); - }); + return new Transition(groups, this._parents, name, id); +}; - /** - * Creates a function that invokes `func` with `partials` prepended to the - * arguments it receives. This method is like `_.bind` except it does **not** - * alter the `this` binding. - * - * The `_.partial.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method doesn't set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @since 0.2.0 - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * function greet(greeting, name) { - * return greeting + ' ' + name; - * } - * - * var sayHelloTo = _.partial(greet, 'hello'); - * sayHelloTo('fred'); - * // => 'hello fred' - * - * // Partially applied with placeholders. - * var greetFred = _.partial(greet, _, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - */ - var partial = baseRest(function(func, partials) { - var holders = replaceHolders(partials, getHolder(partial)); - return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders); - }); +selection.prototype.interrupt = selection_interrupt; +selection.prototype.transition = selection_transition; - /** - * This method is like `_.partial` except that partially applied arguments - * are appended to the arguments it receives. - * - * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method doesn't set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * function greet(greeting, name) { - * return greeting + ' ' + name; - * } - * - * var greetFred = _.partialRight(greet, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - * - * // Partially applied with placeholders. - * var sayHelloTo = _.partialRight(greet, 'hello', _); - * sayHelloTo('fred'); - * // => 'hello fred' - */ - var partialRight = baseRest(function(func, partials) { - var holders = replaceHolders(partials, getHolder(partialRight)); - return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders); - }); +var root$1 = [null]; - /** - * Creates a function that invokes `func` with arguments arranged according - * to the specified `indexes` where the argument value at the first index is - * provided as the first argument, the argument value at the second index is - * provided as the second argument, and so on. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to rearrange arguments for. - * @param {...(number|number[])} indexes The arranged argument indexes. - * @returns {Function} Returns the new function. - * @example - * - * var rearged = _.rearg(function(a, b, c) { - * return [a, b, c]; - * }, [2, 0, 1]); - * - * rearged('b', 'c', 'a') - * // => ['a', 'b', 'c'] - */ - var rearg = flatRest(function(func, indexes) { - return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes); - }); +var active = function(node, name) { + var schedules = node.__transition, + schedule$$1, + i; - /** - * Creates a function that invokes `func` with the `this` binding of the - * created function and arguments from `start` and beyond provided as - * an array. - * - * **Note:** This method is based on the - * [rest parameter](https://mdn.io/rest_parameters). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.rest(function(what, names) { - * return what + ' ' + _.initial(names).join(', ') + - * (_.size(names) > 1 ? ', & ' : '') + _.last(names); - * }); - * - * say('hello', 'fred', 'barney', 'pebbles'); - * // => 'hello fred, barney, & pebbles' - */ - function rest(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); + if (schedules) { + name = name == null ? null : name + ""; + for (i in schedules) { + if ((schedule$$1 = schedules[i]).state > SCHEDULED && schedule$$1.name === name) { + return new Transition([[node]], root$1, name, +i); } - start = start === undefined ? start : toInteger(start); - return baseRest(func, start); } + } - /** - * Creates a function that invokes `func` with the `this` binding of the - * create function and an array of arguments much like - * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply). - * - * **Note:** This method is based on the - * [spread operator](https://mdn.io/spread_operator). - * - * @static - * @memberOf _ - * @since 3.2.0 - * @category Function - * @param {Function} func The function to spread arguments over. - * @param {number} [start=0] The start position of the spread. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.spread(function(who, what) { - * return who + ' says ' + what; - * }); - * - * say(['fred', 'hello']); - * // => 'fred says hello' - * - * var numbers = Promise.all([ - * Promise.resolve(40), - * Promise.resolve(36) - * ]); - * - * numbers.then(_.spread(function(x, y) { - * return x + y; - * })); - * // => a Promise of 76 - */ - function spread(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - start = start == null ? 0 : nativeMax(toInteger(start), 0); - return baseRest(function(args) { - var array = args[start], - otherArgs = castSlice(args, 0, start); - - if (array) { - arrayPush(otherArgs, array); - } - return apply(func, this, otherArgs); - }); - } + return null; +}; - /** - * Creates a throttled function that only invokes `func` at most once per - * every `wait` milliseconds. The throttled function comes with a `cancel` - * method to cancel delayed `func` invocations and a `flush` method to - * immediately invoke them. Provide `options` to indicate whether `func` - * should be invoked on the leading and/or trailing edge of the `wait` - * timeout. The `func` is invoked with the last arguments provided to the - * throttled function. Subsequent calls to the throttled function return the - * result of the last `func` invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is - * invoked on the trailing edge of the timeout only if the throttled function - * is invoked more than once during the `wait` timeout. - * - * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred - * until to the next tick, similar to `setTimeout` with a timeout of `0`. - * - * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) - * for details over the differences between `_.throttle` and `_.debounce`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to throttle. - * @param {number} [wait=0] The number of milliseconds to throttle invocations to. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.leading=true] - * Specify invoking on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] - * Specify invoking on the trailing edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // Avoid excessively updating the position while scrolling. - * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); - * - * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. - * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); - * jQuery(element).on('click', throttled); - * - * // Cancel the trailing throttled invocation. - * jQuery(window).on('popstate', throttled.cancel); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; +var constant$4 = function(x) { + return function() { + return x; + }; +}; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (isObject(options)) { - leading = 'leading' in options ? !!options.leading : leading; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - return debounce(func, wait, { - 'leading': leading, - 'maxWait': wait, - 'trailing': trailing - }); - } +var BrushEvent = function(target, type, selection) { + this.target = target; + this.type = type; + this.selection = selection; +}; - /** - * Creates a function that accepts up to one argument, ignoring any - * additional arguments. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - * @example - * - * _.map(['6', '8', '10'], _.unary(parseInt)); - * // => [6, 8, 10] - */ - function unary(func) { - return ary(func, 1); - } +function nopropagation$1() { + event.stopImmediatePropagation(); +} - /** - * Creates a function that provides `value` to `wrapper` as its first - * argument. Any additional arguments provided to the function are appended - * to those provided to the `wrapper`. The wrapper is invoked with the `this` - * binding of the created function. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {*} value The value to wrap. - * @param {Function} [wrapper=identity] The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '

    ' + func(text) + '

    '; - * }); - * - * p('fred, barney, & pebbles'); - * // => '

    fred, barney, & pebbles

    ' - */ - function wrap(value, wrapper) { - return partial(castFunction(wrapper), value); - } +var noevent$1 = function() { + event.preventDefault(); + event.stopImmediatePropagation(); +}; - /*------------------------------------------------------------------------*/ +var MODE_DRAG = {name: "drag"}; +var MODE_SPACE = {name: "space"}; +var MODE_HANDLE = {name: "handle"}; +var MODE_CENTER = {name: "center"}; - /** - * Casts `value` as an array if it's not one. - * - * @static - * @memberOf _ - * @since 4.4.0 - * @category Lang - * @param {*} value The value to inspect. - * @returns {Array} Returns the cast array. - * @example - * - * _.castArray(1); - * // => [1] - * - * _.castArray({ 'a': 1 }); - * // => [{ 'a': 1 }] - * - * _.castArray('abc'); - * // => ['abc'] - * - * _.castArray(null); - * // => [null] - * - * _.castArray(undefined); - * // => [undefined] - * - * _.castArray(); - * // => [] - * - * var array = [1, 2, 3]; - * console.log(_.castArray(array) === array); - * // => true - */ - function castArray() { - if (!arguments.length) { - return []; - } - var value = arguments[0]; - return isArray(value) ? value : [value]; - } - - /** - * Creates a shallow clone of `value`. - * - * **Note:** This method is loosely based on the - * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) - * and supports cloning arrays, array buffers, booleans, date objects, maps, - * numbers, `Object` objects, regexes, sets, strings, symbols, and typed - * arrays. The own enumerable properties of `arguments` objects are cloned - * as plain objects. An empty object is returned for uncloneable values such - * as error objects, functions, DOM nodes, and WeakMaps. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to clone. - * @returns {*} Returns the cloned value. - * @see _.cloneDeep - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var shallow = _.clone(objects); - * console.log(shallow[0] === objects[0]); - * // => true - */ - function clone(value) { - return baseClone(value, CLONE_SYMBOLS_FLAG); - } - - /** - * This method is like `_.clone` except that it accepts `customizer` which - * is invoked to produce the cloned value. If `customizer` returns `undefined`, - * cloning is handled by the method instead. The `customizer` is invoked with - * up to four arguments; (value [, index|key, object, stack]). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to clone. - * @param {Function} [customizer] The function to customize cloning. - * @returns {*} Returns the cloned value. - * @see _.cloneDeepWith - * @example - * - * function customizer(value) { - * if (_.isElement(value)) { - * return value.cloneNode(false); - * } - * } - * - * var el = _.cloneWith(document.body, customizer); - * - * console.log(el === document.body); - * // => false - * console.log(el.nodeName); - * // => 'BODY' - * console.log(el.childNodes.length); - * // => 0 - */ - function cloneWith(value, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); - } +var X = { + name: "x", + handles: ["e", "w"].map(type), + input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; }, + output: function(xy) { return xy && [xy[0][0], xy[1][0]]; } +}; - /** - * This method is like `_.clone` except that it recursively clones `value`. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Lang - * @param {*} value The value to recursively clone. - * @returns {*} Returns the deep cloned value. - * @see _.clone - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var deep = _.cloneDeep(objects); - * console.log(deep[0] === objects[0]); - * // => false - */ - function cloneDeep(value) { - return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); - } +var Y = { + name: "y", + handles: ["n", "s"].map(type), + input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; }, + output: function(xy) { return xy && [xy[0][1], xy[1][1]]; } +}; - /** - * This method is like `_.cloneWith` except that it recursively clones `value`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to recursively clone. - * @param {Function} [customizer] The function to customize cloning. - * @returns {*} Returns the deep cloned value. - * @see _.cloneWith - * @example - * - * function customizer(value) { - * if (_.isElement(value)) { - * return value.cloneNode(true); - * } - * } - * - * var el = _.cloneDeepWith(document.body, customizer); - * - * console.log(el === document.body); - * // => false - * console.log(el.nodeName); - * // => 'BODY' - * console.log(el.childNodes.length); - * // => 20 - */ - function cloneDeepWith(value, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); - } +var XY = { + name: "xy", + handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type), + input: function(xy) { return xy; }, + output: function(xy) { return xy; } +}; - /** - * Checks if `object` conforms to `source` by invoking the predicate - * properties of `source` with the corresponding property values of `object`. - * - * **Note:** This method is equivalent to `_.conforms` when `source` is - * partially applied. - * - * @static - * @memberOf _ - * @since 4.14.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property predicates to conform to. - * @returns {boolean} Returns `true` if `object` conforms, else `false`. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * - * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); - * // => true - * - * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); - * // => false - */ - function conformsTo(object, source) { - return source == null || baseConformsTo(object, source, keys(source)); - } +var cursors = { + overlay: "crosshair", + selection: "move", + n: "ns-resize", + e: "ew-resize", + s: "ns-resize", + w: "ew-resize", + nw: "nwse-resize", + ne: "nesw-resize", + se: "nwse-resize", + sw: "nesw-resize" +}; - /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ - function eq(value, other) { - return value === other || (value !== value && other !== other); - } +var flipX = { + e: "w", + w: "e", + nw: "ne", + ne: "nw", + se: "sw", + sw: "se" +}; - /** - * Checks if `value` is greater than `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than `other`, - * else `false`. - * @see _.lt - * @example - * - * _.gt(3, 1); - * // => true - * - * _.gt(3, 3); - * // => false - * - * _.gt(1, 3); - * // => false - */ - var gt = createRelationalOperation(baseGt); +var flipY = { + n: "s", + s: "n", + nw: "sw", + ne: "se", + se: "ne", + sw: "nw" +}; - /** - * Checks if `value` is greater than or equal to `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than or equal to - * `other`, else `false`. - * @see _.lte - * @example - * - * _.gte(3, 1); - * // => true - * - * _.gte(3, 3); - * // => true - * - * _.gte(1, 3); - * // => false - */ - var gte = createRelationalOperation(function(value, other) { - return value >= other; - }); +var signsX = { + overlay: +1, + selection: +1, + n: null, + e: +1, + s: null, + w: -1, + nw: -1, + ne: +1, + se: +1, + sw: -1 +}; - /** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { - return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && - !propertyIsEnumerable.call(value, 'callee'); - }; +var signsY = { + overlay: +1, + selection: +1, + n: -1, + e: null, + s: +1, + w: null, + nw: -1, + ne: -1, + se: +1, + sw: +1 +}; - /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ - var isArray = Array.isArray; +function type(t) { + return {type: t}; +} - /** - * Checks if `value` is classified as an `ArrayBuffer` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. - * @example - * - * _.isArrayBuffer(new ArrayBuffer(2)); - * // => true - * - * _.isArrayBuffer(new Array(2)); - * // => false - */ - var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; +// Ignore right-click, since that should open the context menu. +function defaultFilter() { + return !event.button; +} - /** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ - function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); - } +function defaultExtent() { + var svg = this.ownerSVGElement || this; + return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]]; +} - /** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ - function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); - } +// Like d3.local, but with the name “__brush” rather than auto-generated. +function local(node) { + while (!node.__brush) if (!(node = node.parentNode)) return; + return node.__brush; +} - /** - * Checks if `value` is classified as a boolean primitive or object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. - * @example - * - * _.isBoolean(false); - * // => true - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - (isObjectLike(value) && baseGetTag(value) == boolTag); - } +function empty(extent) { + return extent[0][0] === extent[1][0] + || extent[0][1] === extent[1][1]; +} - /** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ - var isBuffer = nativeIsBuffer || stubFalse; +function brushSelection(node) { + var state = node.__brush; + return state ? state.dim.output(state.selection) : null; +} - /** - * Checks if `value` is classified as a `Date` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a date object, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - * - * _.isDate('Mon April 23 2012'); - * // => false - */ - var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; +function brushX() { + return brush$1(X); +} - /** - * Checks if `value` is likely a DOM element. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - * - * _.isElement(''); - * // => false - */ - function isElement(value) { - return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value); - } +function brushY() { + return brush$1(Y); +} - /** - * Checks if `value` is an empty object, collection, map, or set. - * - * Objects are considered empty if they have no own enumerable string keyed - * properties. - * - * Array-like values such as `arguments` objects, arrays, buffers, strings, or - * jQuery-like collections are considered empty if they have a `length` of `0`. - * Similarly, maps and sets are considered empty if they have a `size` of `0`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is empty, else `false`. - * @example - * - * _.isEmpty(null); - * // => true - * - * _.isEmpty(true); - * // => true - * - * _.isEmpty(1); - * // => true - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({ 'a': 1 }); - * // => false - */ - function isEmpty(value) { - if (value == null) { - return true; - } - if (isArrayLike(value) && - (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || - isBuffer(value) || isTypedArray(value) || isArguments(value))) { - return !value.length; - } - var tag = getTag(value); - if (tag == mapTag || tag == setTag) { - return !value.size; - } - if (isPrototype(value)) { - return !baseKeys(value).length; - } - for (var key in value) { - if (hasOwnProperty.call(value, key)) { - return false; - } - } - return true; - } +var brush = function() { + return brush$1(XY); +}; - /** - * Performs a deep comparison between two values to determine if they are - * equivalent. - * - * **Note:** This method supports comparing arrays, array buffers, booleans, - * date objects, error objects, maps, numbers, `Object` objects, regexes, - * sets, strings, symbols, and typed arrays. `Object` objects are compared - * by their own, not inherited, enumerable properties. Functions and DOM - * nodes are compared by strict equality, i.e. `===`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.isEqual(object, other); - * // => true - * - * object === other; - * // => false - */ - function isEqual(value, other) { - return baseIsEqual(value, other); - } +function brush$1(dim) { + var extent = defaultExtent, + filter = defaultFilter, + listeners = dispatch(brush, "start", "brush", "end"), + handleSize = 6, + touchending; - /** - * This method is like `_.isEqual` except that it accepts `customizer` which - * is invoked to compare values. If `customizer` returns `undefined`, comparisons - * are handled by the method instead. The `customizer` is invoked with up to - * six arguments: (objValue, othValue [, index|key, object, other, stack]). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * function isGreeting(value) { - * return /^h(?:i|ello)$/.test(value); - * } - * - * function customizer(objValue, othValue) { - * if (isGreeting(objValue) && isGreeting(othValue)) { - * return true; - * } - * } - * - * var array = ['hello', 'goodbye']; - * var other = ['hi', 'goodbye']; - * - * _.isEqualWith(array, other, customizer); - * // => true - */ - function isEqualWith(value, other, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - var result = customizer ? customizer(value, other) : undefined; - return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result; - } + function brush(group) { + var overlay = group + .property("__brush", initialize) + .selectAll(".overlay") + .data([type("overlay")]); - /** - * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, - * `SyntaxError`, `TypeError`, or `URIError` object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an error object, else `false`. - * @example - * - * _.isError(new Error); - * // => true - * - * _.isError(Error); - * // => false - */ - function isError(value) { - if (!isObjectLike(value)) { - return false; - } - var tag = baseGetTag(value); - return tag == errorTag || tag == domExcTag || - (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); - } + overlay.enter().append("rect") + .attr("class", "overlay") + .attr("pointer-events", "all") + .attr("cursor", cursors.overlay) + .merge(overlay) + .each(function() { + var extent = local(this).extent; + d3_select(this) + .attr("x", extent[0][0]) + .attr("y", extent[0][1]) + .attr("width", extent[1][0] - extent[0][0]) + .attr("height", extent[1][1] - extent[0][1]); + }); - /** - * Checks if `value` is a finite primitive number. - * - * **Note:** This method is based on - * [`Number.isFinite`](https://mdn.io/Number/isFinite). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. - * @example - * - * _.isFinite(3); - * // => true - * - * _.isFinite(Number.MIN_VALUE); - * // => true - * - * _.isFinite(Infinity); - * // => false - * - * _.isFinite('3'); - * // => false - */ - function isFinite(value) { - return typeof value == 'number' && nativeIsFinite(value); - } + group.selectAll(".selection") + .data([type("selection")]) + .enter().append("rect") + .attr("class", "selection") + .attr("cursor", cursors.selection) + .attr("fill", "#777") + .attr("fill-opacity", 0.3) + .attr("stroke", "#fff") + .attr("shape-rendering", "crispEdges"); - /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ - function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; - } + var handle = group.selectAll(".handle") + .data(dim.handles, function(d) { return d.type; }); - /** - * Checks if `value` is an integer. - * - * **Note:** This method is based on - * [`Number.isInteger`](https://mdn.io/Number/isInteger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an integer, else `false`. - * @example - * - * _.isInteger(3); - * // => true - * - * _.isInteger(Number.MIN_VALUE); - * // => false - * - * _.isInteger(Infinity); - * // => false - * - * _.isInteger('3'); - * // => false - */ - function isInteger(value) { - return typeof value == 'number' && value == toInteger(value); - } + handle.exit().remove(); - /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ - function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; - } + handle.enter().append("rect") + .attr("class", function(d) { return "handle handle--" + d.type; }) + .attr("cursor", function(d) { return cursors[d.type]; }); - /** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ - function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); - } + group + .each(redraw) + .attr("fill", "none") + .attr("pointer-events", "all") + .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)") + .on("mousedown.brush touchstart.brush", started); + } - /** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ - function isObjectLike(value) { - return value != null && typeof value == 'object'; - } + brush.move = function(group, selection) { + if (group.selection) { + group + .on("start.brush", function() { emitter(this, arguments).beforestart().start(); }) + .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); }) + .tween("brush", function() { + var that = this, + state = that.__brush, + emit = emitter(that, arguments), + selection0 = state.selection, + selection1 = dim.input(typeof selection === "function" ? selection.apply(this, arguments) : selection, state.extent), + i = d3_interpolate(selection0, selection1); - /** - * Checks if `value` is classified as a `Map` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - * @example - * - * _.isMap(new Map); - * // => true - * - * _.isMap(new WeakMap); - * // => false - */ - var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; + function tween(t) { + state.selection = t === 1 && empty(selection1) ? null : i(t); + redraw.call(that); + emit.brush(); + } - /** - * Performs a partial deep comparison between `object` and `source` to - * determine if `object` contains equivalent property values. - * - * **Note:** This method is equivalent to `_.matches` when `source` is - * partially applied. - * - * Partial comparisons will match empty array and empty object `source` - * values against any array or object value, respectively. See `_.isEqual` - * for a list of supported value comparisons. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * - * _.isMatch(object, { 'b': 2 }); - * // => true - * - * _.isMatch(object, { 'b': 1 }); - * // => false - */ - function isMatch(object, source) { - return object === source || baseIsMatch(object, source, getMatchData(source)); - } + return selection0 && selection1 ? tween : tween(1); + }); + } else { + group + .each(function() { + var that = this, + args = arguments, + state = that.__brush, + selection1 = dim.input(typeof selection === "function" ? selection.apply(that, args) : selection, state.extent), + emit = emitter(that, args).beforestart(); - /** - * This method is like `_.isMatch` except that it accepts `customizer` which - * is invoked to compare values. If `customizer` returns `undefined`, comparisons - * are handled by the method instead. The `customizer` is invoked with five - * arguments: (objValue, srcValue, index|key, object, source). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - * @example - * - * function isGreeting(value) { - * return /^h(?:i|ello)$/.test(value); - * } - * - * function customizer(objValue, srcValue) { - * if (isGreeting(objValue) && isGreeting(srcValue)) { - * return true; - * } - * } - * - * var object = { 'greeting': 'hello' }; - * var source = { 'greeting': 'hi' }; - * - * _.isMatchWith(object, source, customizer); - * // => true - */ - function isMatchWith(object, source, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return baseIsMatch(object, source, getMatchData(source), customizer); + interrupt(that); + state.selection = selection1 == null || empty(selection1) ? null : selection1; + redraw.call(that); + emit.start().brush().end(); + }); } + }; - /** - * Checks if `value` is `NaN`. - * - * **Note:** This method is based on - * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as - * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for - * `undefined` and other non-number values. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // An `NaN` primitive is the only value that is not equal to itself. - // Perform the `toStringTag` check first to avoid errors with some - // ActiveX objects in IE. - return isNumber(value) && value != +value; - } + function redraw() { + var group = d3_select(this), + selection = local(this).selection; - /** - * Checks if `value` is a pristine native function. - * - * **Note:** This method can't reliably detect native functions in the presence - * of the core-js package because core-js circumvents this kind of detection. - * Despite multiple requests, the core-js maintainer has made it clear: any - * attempt to fix the detection will be obstructed. As a result, we're left - * with little choice but to throw an error. Unfortunately, this also affects - * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), - * which rely on core-js. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - * @example - * - * _.isNative(Array.prototype.push); - * // => true - * - * _.isNative(_); - * // => false - */ - function isNative(value) { - if (isMaskable(value)) { - throw new Error(CORE_ERROR_TEXT); - } - return baseIsNative(value); - } + if (selection) { + group.selectAll(".selection") + .style("display", null) + .attr("x", selection[0][0]) + .attr("y", selection[0][1]) + .attr("width", selection[1][0] - selection[0][0]) + .attr("height", selection[1][1] - selection[0][1]); - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(void 0); - * // => false - */ - function isNull(value) { - return value === null; + group.selectAll(".handle") + .style("display", null) + .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; }) + .attr("y", function(d) { return d.type[0] === "s" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; }) + .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection[1][0] - selection[0][0] + handleSize : handleSize; }) + .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection[1][1] - selection[0][1] + handleSize : handleSize; }); } - /** - * Checks if `value` is `null` or `undefined`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is nullish, else `false`. - * @example - * - * _.isNil(null); - * // => true - * - * _.isNil(void 0); - * // => true - * - * _.isNil(NaN); - * // => false - */ - function isNil(value) { - return value == null; + else { + group.selectAll(".selection,.handle") + .style("display", "none") + .attr("x", null) + .attr("y", null) + .attr("width", null) + .attr("height", null); } + } - /** - * Checks if `value` is classified as a `Number` primitive or object. - * - * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are - * classified as numbers, use the `_.isFinite` method. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a number, else `false`. - * @example - * - * _.isNumber(3); - * // => true - * - * _.isNumber(Number.MIN_VALUE); - * // => true - * - * _.isNumber(Infinity); - * // => true - * - * _.isNumber('3'); - * // => false - */ - function isNumber(value) { - return typeof value == 'number' || - (isObjectLike(value) && baseGetTag(value) == numberTag); - } + function emitter(that, args) { + return that.__brush.emitter || new Emitter(that, args); + } - /** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * @static - * @memberOf _ - * @since 0.8.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ - function isPlainObject(value) { - if (!isObjectLike(value) || baseGetTag(value) != objectTag) { - return false; - } - var proto = getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; - return typeof Ctor == 'function' && Ctor instanceof Ctor && - funcToString.call(Ctor) == objectCtorString; + function Emitter(that, args) { + this.that = that; + this.args = args; + this.state = that.__brush; + this.active = 0; + } + + Emitter.prototype = { + beforestart: function() { + if (++this.active === 1) this.state.emitter = this, this.starting = true; + return this; + }, + start: function() { + if (this.starting) this.starting = false, this.emit("start"); + return this; + }, + brush: function() { + this.emit("brush"); + return this; + }, + end: function() { + if (--this.active === 0) delete this.state.emitter, this.emit("end"); + return this; + }, + emit: function(type) { + customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]); } + }; - /** - * Checks if `value` is classified as a `RegExp` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. - * @example - * - * _.isRegExp(/abc/); - * // => true - * - * _.isRegExp('/abc/'); - * // => false - */ - var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; + function started() { + if (event.touches) { if (event.changedTouches.length < event.touches.length) return noevent$1(); } + else if (touchending) return; + if (!filter.apply(this, arguments)) return; - /** - * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 - * double precision number which isn't the result of a rounded unsafe integer. - * - * **Note:** This method is based on - * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. - * @example - * - * _.isSafeInteger(3); - * // => true - * - * _.isSafeInteger(Number.MIN_VALUE); - * // => false - * - * _.isSafeInteger(Infinity); - * // => false - * - * _.isSafeInteger('3'); - * // => false - */ - function isSafeInteger(value) { - return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; + var that = this, + type = event.target.__data__.type, + mode = (event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (event.altKey ? MODE_CENTER : MODE_HANDLE), + signX = dim === Y ? null : signsX[type], + signY = dim === X ? null : signsY[type], + state = local(that), + extent = state.extent, + selection = state.selection, + W = extent[0][0], w0, w1, + N = extent[0][1], n0, n1, + E = extent[1][0], e0, e1, + S = extent[1][1], s0, s1, + dx, + dy, + moving, + shifting = signX && signY && event.shiftKey, + lockX, + lockY, + point0 = d3_mouse(that), + point = point0, + emit = emitter(that, arguments).beforestart(); + + if (type === "overlay") { + state.selection = selection = [ + [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]], + [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0] + ]; + } else { + w0 = selection[0][0]; + n0 = selection[0][1]; + e0 = selection[1][0]; + s0 = selection[1][1]; } - /** - * Checks if `value` is classified as a `Set` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - * @example - * - * _.isSet(new Set); - * // => true - * - * _.isSet(new WeakSet); - * // => false - */ - var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; + w1 = w0; + n1 = n0; + e1 = e0; + s1 = s0; - /** - * Checks if `value` is classified as a `String` primitive or object. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a string, else `false`. - * @example - * - * _.isString('abc'); - * // => true - * - * _.isString(1); - * // => false - */ - function isString(value) { - return typeof value == 'string' || - (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); - } + var group = d3_select(that) + .attr("pointer-events", "none"); - /** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ - function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); - } + var overlay = group.selectAll(".overlay") + .attr("cursor", cursors[type]); - /** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ - var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + if (event.touches) { + group + .on("touchmove.brush", moved, true) + .on("touchend.brush touchcancel.brush", ended, true); + } else { + var view = d3_select(event.view) + .on("keydown.brush", keydowned, true) + .on("keyup.brush", keyupped, true) + .on("mousemove.brush", moved, true) + .on("mouseup.brush", ended, true); - /** - * Checks if `value` is `undefined`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - * - * _.isUndefined(null); - * // => false - */ - function isUndefined(value) { - return value === undefined; + dragDisable(event.view); } - /** - * Checks if `value` is classified as a `WeakMap` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. - * @example - * - * _.isWeakMap(new WeakMap); - * // => true - * - * _.isWeakMap(new Map); - * // => false - */ - function isWeakMap(value) { - return isObjectLike(value) && getTag(value) == weakMapTag; - } + nopropagation$1(); + interrupt(that); + redraw.call(that); + emit.start(); - /** - * Checks if `value` is classified as a `WeakSet` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. - * @example - * - * _.isWeakSet(new WeakSet); - * // => true - * - * _.isWeakSet(new Set); - * // => false - */ - function isWeakSet(value) { - return isObjectLike(value) && baseGetTag(value) == weakSetTag; + function moved() { + var point1 = d3_mouse(that); + if (shifting && !lockX && !lockY) { + if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true; + else lockX = true; + } + point = point1; + moving = true; + noevent$1(); + move(); } - /** - * Checks if `value` is less than `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than `other`, - * else `false`. - * @see _.gt - * @example - * - * _.lt(1, 3); - * // => true - * - * _.lt(3, 3); - * // => false - * - * _.lt(3, 1); - * // => false - */ - var lt = createRelationalOperation(baseLt); + function move() { + var t; - /** - * Checks if `value` is less than or equal to `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than or equal to - * `other`, else `false`. - * @see _.gte - * @example - * - * _.lte(1, 3); - * // => true - * - * _.lte(3, 3); - * // => true - * - * _.lte(3, 1); - * // => false - */ - var lte = createRelationalOperation(function(value, other) { - return value <= other; - }); + dx = point[0] - point0[0]; + dy = point[1] - point0[1]; - /** - * Converts `value` to an array. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Array} Returns the converted array. - * @example - * - * _.toArray({ 'a': 1, 'b': 2 }); - * // => [1, 2] - * - * _.toArray('abc'); - * // => ['a', 'b', 'c'] - * - * _.toArray(1); - * // => [] - * - * _.toArray(null); - * // => [] - */ - function toArray(value) { - if (!value) { - return []; + switch (mode) { + case MODE_SPACE: + case MODE_DRAG: { + if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx; + if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy; + break; + } + case MODE_HANDLE: { + if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0; + else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx; + if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0; + else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy; + break; + } + case MODE_CENTER: { + if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX)); + if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY)); + break; + } } - if (isArrayLike(value)) { - return isString(value) ? stringToArray(value) : copyArray(value); + + if (e1 < w1) { + signX *= -1; + t = w0, w0 = e0, e0 = t; + t = w1, w1 = e1, e1 = t; + if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]); } - if (symIterator && value[symIterator]) { - return iteratorToArray(value[symIterator]()); + + if (s1 < n1) { + signY *= -1; + t = n0, n0 = s0, s0 = t; + t = n1, n1 = s1, s1 = t; + if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]); } - var tag = getTag(value), - func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); - return func(value); - } + if (state.selection) selection = state.selection; // May be set by brush.move! + if (lockX) w1 = selection[0][0], e1 = selection[1][0]; + if (lockY) n1 = selection[0][1], s1 = selection[1][1]; - /** - * Converts `value` to a finite number. - * - * @static - * @memberOf _ - * @since 4.12.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted number. - * @example - * - * _.toFinite(3.2); - * // => 3.2 - * - * _.toFinite(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toFinite(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toFinite('3.2'); - * // => 3.2 - */ - function toFinite(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = (value < 0 ? -1 : 1); - return sign * MAX_INTEGER; + if (selection[0][0] !== w1 + || selection[0][1] !== n1 + || selection[1][0] !== e1 + || selection[1][1] !== s1) { + state.selection = [[w1, n1], [e1, s1]]; + redraw.call(that); + emit.brush(); } - return value === value ? value : 0; } - /** - * Converts `value` to an integer. - * - * **Note:** This method is loosely based on - * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toInteger(3.2); - * // => 3 - * - * _.toInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toInteger(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toInteger('3.2'); - * // => 3 - */ - function toInteger(value) { - var result = toFinite(value), - remainder = result % 1; - - return result === result ? (remainder ? result - remainder : result) : 0; + function ended() { + nopropagation$1(); + if (event.touches) { + if (event.touches.length) return; + if (touchending) clearTimeout(touchending); + touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! + group.on("touchmove.brush touchend.brush touchcancel.brush", null); + } else { + yesdrag(event.view, moving); + view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null); + } + group.attr("pointer-events", "all"); + overlay.attr("cursor", cursors.overlay); + if (state.selection) selection = state.selection; // May be set by brush.move (on start)! + if (empty(selection)) state.selection = null, redraw.call(that); + emit.end(); } - /** - * Converts `value` to an integer suitable for use as the length of an - * array-like object. - * - * **Note:** This method is based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toLength(3.2); - * // => 3 - * - * _.toLength(Number.MIN_VALUE); - * // => 0 - * - * _.toLength(Infinity); - * // => 4294967295 - * - * _.toLength('3.2'); - * // => 3 - */ - function toLength(value) { - return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; + function keydowned() { + switch (event.keyCode) { + case 16: { // SHIFT + shifting = signX && signY; + break; + } + case 18: { // ALT + if (mode === MODE_HANDLE) { + if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX; + if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY; + mode = MODE_CENTER; + move(); + } + break; + } + case 32: { // SPACE; takes priority over ALT + if (mode === MODE_HANDLE || mode === MODE_CENTER) { + if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx; + if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy; + mode = MODE_SPACE; + overlay.attr("cursor", cursors.selection); + move(); + } + break; + } + default: return; + } + noevent$1(); } - /** - * Converts `value` to a number. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to process. - * @returns {number} Returns the number. - * @example - * - * _.toNumber(3.2); - * // => 3.2 - * - * _.toNumber(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toNumber(Infinity); - * // => Infinity - * - * _.toNumber('3.2'); - * // => 3.2 - */ - function toNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - if (isObject(value)) { - var other = typeof value.valueOf == 'function' ? value.valueOf() : value; - value = isObject(other) ? (other + '') : other; - } - if (typeof value != 'string') { - return value === 0 ? value : +value; + function keyupped() { + switch (event.keyCode) { + case 16: { // SHIFT + if (shifting) { + lockX = lockY = shifting = false; + move(); + } + break; + } + case 18: { // ALT + if (mode === MODE_CENTER) { + if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1; + if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1; + mode = MODE_HANDLE; + move(); + } + break; + } + case 32: { // SPACE + if (mode === MODE_SPACE) { + if (event.altKey) { + if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX; + if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY; + mode = MODE_CENTER; + } else { + if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1; + if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1; + mode = MODE_HANDLE; + } + overlay.attr("cursor", cursors[type]); + move(); + } + break; + } + default: return; } - value = value.replace(reTrim, ''); - var isBinary = reIsBinary.test(value); - return (isBinary || reIsOctal.test(value)) - ? freeParseInt(value.slice(2), isBinary ? 2 : 8) - : (reIsBadHex.test(value) ? NAN : +value); + noevent$1(); } + } - /** - * Converts `value` to a plain object flattening inherited enumerable string - * keyed properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example - * - * function Foo() { - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } - * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } - */ - function toPlainObject(value) { - return copyObject(value, keysIn(value)); - } + function initialize() { + var state = this.__brush || {selection: null}; + state.extent = extent.apply(this, arguments); + state.dim = dim; + return state; + } - /** - * Converts `value` to a safe integer. A safe integer can be compared and - * represented correctly. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toSafeInteger(3.2); - * // => 3 - * - * _.toSafeInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toSafeInteger(Infinity); - * // => 9007199254740991 - * - * _.toSafeInteger('3.2'); - * // => 3 - */ - function toSafeInteger(value) { - return value - ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) - : (value === 0 ? value : 0); - } + brush.extent = function(_) { + return arguments.length ? (extent = typeof _ === "function" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent; + }; - /** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ - function toString(value) { - return value == null ? '' : baseToString(value); - } + brush.filter = function(_) { + return arguments.length ? (filter = typeof _ === "function" ? _ : constant$4(!!_), brush) : filter; + }; - /*------------------------------------------------------------------------*/ + brush.handleSize = function(_) { + return arguments.length ? (handleSize = +_, brush) : handleSize; + }; - /** - * Assigns own enumerable string keyed properties of source objects to the - * destination object. Source objects are applied from left to right. - * Subsequent sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object` and is loosely based on - * [`Object.assign`](https://mdn.io/Object/assign). - * - * @static - * @memberOf _ - * @since 0.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assignIn - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assign({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'c': 3 } - */ - var assign = createAssigner(function(object, source) { - if (isPrototype(source) || isArrayLike(source)) { - copyObject(source, keys(source), object); - return; - } - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - assignValue(object, key, source[key]); - } - } - }); + brush.on = function() { + var value = listeners.on.apply(listeners, arguments); + return value === listeners ? brush : value; + }; - /** - * This method is like `_.assign` except that it iterates over own and - * inherited source properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias extend - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assign - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assignIn({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } - */ - var assignIn = createAssigner(function(object, source) { - copyObject(source, keysIn(source), object); - }); + return brush; +} - /** - * This method is like `_.assignIn` except that it accepts `customizer` - * which is invoked to produce the assigned values. If `customizer` returns - * `undefined`, assignment is handled by the method instead. The `customizer` - * is invoked with five arguments: (objValue, srcValue, key, object, source). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias extendWith - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @see _.assignWith - * @example - * - * function customizer(objValue, srcValue) { - * return _.isUndefined(objValue) ? srcValue : objValue; - * } - * - * var defaults = _.partialRight(_.assignInWith, customizer); - * - * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { - copyObject(source, keysIn(source), object, customizer); - }); +var cos = Math.cos; +var sin = Math.sin; +var pi$1 = Math.PI; +var halfPi$1 = pi$1 / 2; +var tau$1 = pi$1 * 2; +var max$1 = Math.max; - /** - * This method is like `_.assign` except that it accepts `customizer` - * which is invoked to produce the assigned values. If `customizer` returns - * `undefined`, assignment is handled by the method instead. The `customizer` - * is invoked with five arguments: (objValue, srcValue, key, object, source). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @see _.assignInWith - * @example - * - * function customizer(objValue, srcValue) { - * return _.isUndefined(objValue) ? srcValue : objValue; - * } - * - * var defaults = _.partialRight(_.assignWith, customizer); - * - * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var assignWith = createAssigner(function(object, source, srcIndex, customizer) { - copyObject(source, keys(source), object, customizer); - }); +function compareValue(compare) { + return function(a, b) { + return compare( + a.source.value + a.target.value, + b.source.value + b.target.value + ); + }; +} - /** - * Creates an array of values corresponding to `paths` of `object`. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {...(string|string[])} [paths] The property paths to pick. - * @returns {Array} Returns the picked values. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; - * - * _.at(object, ['a[0].b.c', 'a[1]']); - * // => [3, 4] - */ - var at = flatRest(baseAt); +var chord = function() { + var padAngle = 0, + sortGroups = null, + sortSubgroups = null, + sortChords = null; - /** - * Creates an object that inherits from the `prototype` object. If a - * `properties` object is given, its own enumerable string keyed properties - * are assigned to the created object. - * - * @static - * @memberOf _ - * @since 2.3.0 - * @category Object - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { - * 'constructor': Circle - * }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties == null ? result : baseAssign(result, properties); + function chord(matrix) { + var n = matrix.length, + groupSums = [], + groupIndex = d3_range(n), + subgroupIndex = [], + chords = [], + groups = chords.groups = new Array(n), + subgroups = new Array(n * n), + k, + x, + x0, + dx, + i, + j; + + // Compute the sum. + k = 0, i = -1; while (++i < n) { + x = 0, j = -1; while (++j < n) { + x += matrix[i][j]; + } + groupSums.push(x); + subgroupIndex.push(d3_range(n)); + k += x; } - /** - * Assigns own and inherited enumerable string keyed properties of source - * objects to the destination object for all destination properties that - * resolve to `undefined`. Source objects are applied from left to right. - * Once a property is set, additional values of the same property are ignored. - * - * **Note:** This method mutates `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaultsDeep - * @example - * - * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var defaults = baseRest(function(args) { - args.push(undefined, customDefaultsAssignIn); - return apply(assignInWith, undefined, args); + // Sort groups… + if (sortGroups) groupIndex.sort(function(a, b) { + return sortGroups(groupSums[a], groupSums[b]); }); - /** - * This method is like `_.defaults` except that it recursively assigns - * default properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaults - * @example - * - * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); - * // => { 'a': { 'b': 2, 'c': 3 } } - */ - var defaultsDeep = baseRest(function(args) { - args.push(undefined, customDefaultsMerge); - return apply(mergeWith, undefined, args); + // Sort subgroups… + if (sortSubgroups) subgroupIndex.forEach(function(d, i) { + d.sort(function(a, b) { + return sortSubgroups(matrix[i][a], matrix[i][b]); + }); }); - /** - * This method is like `_.find` except that it returns the key of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Object - * @param {Object} object The object to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findKey(users, function(o) { return o.age < 40; }); - * // => 'barney' (iteration order is not guaranteed) - * - * // The `_.matches` iteratee shorthand. - * _.findKey(users, { 'age': 1, 'active': true }); - * // => 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findKey(users, 'active'); - * // => 'barney' - */ - function findKey(object, predicate) { - return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); - } - - /** - * This method is like `_.findKey` except that it iterates over elements of - * a collection in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findLastKey(users, function(o) { return o.age < 40; }); - * // => returns 'pebbles' assuming `_.findKey` returns 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.findLastKey(users, { 'age': 36, 'active': true }); - * // => 'barney' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findLastKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findLastKey(users, 'active'); - * // => 'pebbles' - */ - function findLastKey(object, predicate) { - return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); - } + // Convert the sum to scaling factor for [0, 2pi]. + // TODO Allow start and end angle to be specified? + // TODO Allow padding to be specified as percentage? + k = max$1(0, tau$1 - padAngle * n) / k; + dx = k ? padAngle : tau$1 / n; - /** - * Iterates over own and inherited enumerable string keyed properties of an - * object and invokes `iteratee` for each property. The iteratee is invoked - * with three arguments: (value, key, object). Iteratee functions may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 0.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forInRight - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forIn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). - */ - function forIn(object, iteratee) { - return object == null - ? object - : baseFor(object, getIteratee(iteratee, 3), keysIn); + // Compute the start and end angle for each group and subgroup. + // Note: Opera has a bug reordering object literal properties! + x = 0, i = -1; while (++i < n) { + x0 = x, j = -1; while (++j < n) { + var di = groupIndex[i], + dj = subgroupIndex[di][j], + v = matrix[di][dj], + a0 = x, + a1 = x += v * k; + subgroups[dj * n + di] = { + index: di, + subindex: dj, + startAngle: a0, + endAngle: a1, + value: v + }; + } + groups[di] = { + index: di, + startAngle: x0, + endAngle: x, + value: groupSums[di] + }; + x += dx; } - /** - * This method is like `_.forIn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forIn - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forInRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. - */ - function forInRight(object, iteratee) { - return object == null - ? object - : baseForRight(object, getIteratee(iteratee, 3), keysIn); + // Generate chords for each (non-empty) subgroup-subgroup link. + i = -1; while (++i < n) { + j = i - 1; while (++j < n) { + var source = subgroups[j * n + i], + target = subgroups[i * n + j]; + if (source.value || target.value) { + chords.push(source.value < target.value + ? {source: target, target: source} + : {source: source, target: target}); + } + } } - /** - * Iterates over own enumerable string keyed properties of an object and - * invokes `iteratee` for each property. The iteratee is invoked with three - * arguments: (value, key, object). Iteratee functions may exit iteration - * early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 0.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forOwnRight - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a' then 'b' (iteration order is not guaranteed). - */ - function forOwn(object, iteratee) { - return object && baseForOwn(object, getIteratee(iteratee, 3)); - } + return sortChords ? chords.sort(sortChords) : chords; + } - /** - * This method is like `_.forOwn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forOwn - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwnRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. - */ - function forOwnRight(object, iteratee) { - return object && baseForOwnRight(object, getIteratee(iteratee, 3)); - } + chord.padAngle = function(_) { + return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle; + }; - /** - * Creates an array of function property names from own enumerable properties - * of `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the function names. - * @see _.functionsIn - * @example - * - * function Foo() { - * this.a = _.constant('a'); - * this.b = _.constant('b'); - * } - * - * Foo.prototype.c = _.constant('c'); - * - * _.functions(new Foo); - * // => ['a', 'b'] - */ - function functions(object) { - return object == null ? [] : baseFunctions(object, keys(object)); - } + chord.sortGroups = function(_) { + return arguments.length ? (sortGroups = _, chord) : sortGroups; + }; - /** - * Creates an array of function property names from own and inherited - * enumerable properties of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the function names. - * @see _.functions - * @example - * - * function Foo() { - * this.a = _.constant('a'); - * this.b = _.constant('b'); - * } - * - * Foo.prototype.c = _.constant('c'); - * - * _.functionsIn(new Foo); - * // => ['a', 'b', 'c'] - */ - function functionsIn(object) { - return object == null ? [] : baseFunctions(object, keysIn(object)); - } + chord.sortSubgroups = function(_) { + return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups; + }; - /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ - function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; - } + chord.sortChords = function(_) { + return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._; + }; - /** - * Checks if `path` is a direct property of `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = { 'a': { 'b': 2 } }; - * var other = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.has(object, 'a'); - * // => true - * - * _.has(object, 'a.b'); - * // => true - * - * _.has(object, ['a', 'b']); - * // => true - * - * _.has(other, 'a'); - * // => false - */ - function has(object, path) { - return object != null && hasPath(object, path, baseHas); - } + return chord; +}; - /** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ - function hasIn(object, path) { - return object != null && hasPath(object, path, baseHasIn); - } +var slice$2 = Array.prototype.slice; - /** - * Creates an object composed of the inverted keys and values of `object`. - * If `object` contains duplicate values, subsequent values overwrite - * property assignments of previous values. - * - * @static - * @memberOf _ - * @since 0.7.0 - * @category Object - * @param {Object} object The object to invert. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invert(object); - * // => { '1': 'c', '2': 'b' } - */ - var invert = createInverter(function(result, value, key) { - result[value] = key; - }, constant(identity)); +var constant$5 = function(x) { + return function() { + return x; + }; +}; - /** - * This method is like `_.invert` except that the inverted object is generated - * from the results of running each element of `object` thru `iteratee`. The - * corresponding inverted value of each inverted key is an array of keys - * responsible for generating the inverted value. The iteratee is invoked - * with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.1.0 - * @category Object - * @param {Object} object The object to invert. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invertBy(object); - * // => { '1': ['a', 'c'], '2': ['b'] } - * - * _.invertBy(object, function(value) { - * return 'group' + value; - * }); - * // => { 'group1': ['a', 'c'], 'group2': ['b'] } - */ - var invertBy = createInverter(function(result, value, key) { - if (hasOwnProperty.call(result, value)) { - result[value].push(key); - } else { - result[value] = [key]; - } - }, getIteratee); +var pi$2 = Math.PI; +var tau$2 = 2 * pi$2; +var epsilon$1 = 1e-6; +var tauEpsilon = tau$2 - epsilon$1; - /** - * Invokes the method at `path` of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {...*} [args] The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. - * @example - * - * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; - * - * _.invoke(object, 'a[0].b.c.slice', 1, 3); - * // => [2, 3] - */ - var invoke = baseRest(baseInvoke); +function Path() { + this._x0 = this._y0 = // start of current subpath + this._x1 = this._y1 = null; // end of current subpath + this._ = ""; +} - /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ - function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); - } +function path() { + return new Path; +} - /** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ - function keysIn(object) { - return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); +Path.prototype = path.prototype = { + constructor: Path, + moveTo: function(x, y) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y); + }, + closePath: function() { + if (this._x1 !== null) { + this._x1 = this._x0, this._y1 = this._y0; + this._ += "Z"; } + }, + lineTo: function(x, y) { + this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y); + }, + quadraticCurveTo: function(x1, y1, x, y) { + this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y); + }, + bezierCurveTo: function(x1, y1, x2, y2, x, y) { + this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y); + }, + arcTo: function(x1, y1, x2, y2, r) { + x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r; + var x0 = this._x1, + y0 = this._y1, + x21 = x2 - x1, + y21 = y2 - y1, + x01 = x0 - x1, + y01 = y0 - y1, + l01_2 = x01 * x01 + y01 * y01; - /** - * The opposite of `_.mapValues`; this method creates an object with the - * same values as `object` and keys generated by running each own enumerable - * string keyed property of `object` thru `iteratee`. The iteratee is invoked - * with three arguments: (value, key, object). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapValues - * @example - * - * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { - * return key + value; - * }); - * // => { 'a1': 1, 'b2': 2 } - */ - function mapKeys(object, iteratee) { - var result = {}; - iteratee = getIteratee(iteratee, 3); + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); - baseForOwn(object, function(value, key, object) { - baseAssignValue(result, iteratee(value, key, object), value); - }); - return result; + // Is this path empty? Move to (x1,y1). + if (this._x1 === null) { + this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); } - /** - * Creates an object with the same keys as `object` and values generated - * by running each own enumerable string keyed property of `object` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, key, object). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapKeys - * @example - * - * var users = { - * 'fred': { 'user': 'fred', 'age': 40 }, - * 'pebbles': { 'user': 'pebbles', 'age': 1 } - * }; - * - * _.mapValues(users, function(o) { return o.age; }); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - * - * // The `_.property` iteratee shorthand. - * _.mapValues(users, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - */ - function mapValues(object, iteratee) { - var result = {}; - iteratee = getIteratee(iteratee, 3); + // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. + else if (!(l01_2 > epsilon$1)) {} - baseForOwn(object, function(value, key, object) { - baseAssignValue(result, key, iteratee(value, key, object)); - }); - return result; + // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? + // Equivalently, is (x1,y1) coincident with (x2,y2)? + // Or, is the radius zero? Line to (x1,y1). + else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) { + this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); } - /** - * This method is like `_.assign` except that it recursively merges own and - * inherited enumerable string keyed properties of source objects into the - * destination object. Source properties that resolve to `undefined` are - * skipped if a destination value exists. Array and plain object properties - * are merged recursively. Other objects and value types are overridden by - * assignment. Source objects are applied from left to right. Subsequent - * sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * var object = { - * 'a': [{ 'b': 2 }, { 'd': 4 }] - * }; - * - * var other = { - * 'a': [{ 'c': 3 }, { 'e': 5 }] - * }; - * - * _.merge(object, other); - * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } - */ - var merge = createAssigner(function(object, source, srcIndex) { - baseMerge(object, source, srcIndex); - }); - - /** - * This method is like `_.merge` except that it accepts `customizer` which - * is invoked to produce the merged values of the destination and source - * properties. If `customizer` returns `undefined`, merging is handled by the - * method instead. The `customizer` is invoked with six arguments: - * (objValue, srcValue, key, object, source, stack). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} customizer The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * function customizer(objValue, srcValue) { - * if (_.isArray(objValue)) { - * return objValue.concat(srcValue); - * } - * } - * - * var object = { 'a': [1], 'b': [2] }; - * var other = { 'a': [3], 'b': [4] }; - * - * _.mergeWith(object, other, customizer); - * // => { 'a': [1, 3], 'b': [2, 4] } - */ - var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { - baseMerge(object, source, srcIndex, customizer); - }); + // Otherwise, draw an arc! + else { + var x20 = x2 - x0, + y20 = y2 - y0, + l21_2 = x21 * x21 + y21 * y21, + l20_2 = x20 * x20 + y20 * y20, + l21 = Math.sqrt(l21_2), + l01 = Math.sqrt(l01_2), + l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), + t01 = l / l01, + t21 = l / l21; - /** - * The opposite of `_.pick`; this method creates an object composed of the - * own and inherited enumerable property paths of `object` that are not omitted. - * - * **Note:** This method is considerably slower than `_.pick`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {...(string|string[])} [paths] The property paths to omit. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omit(object, ['a', 'c']); - * // => { 'b': '2' } - */ - var omit = flatRest(function(object, paths) { - var result = {}; - if (object == null) { - return result; - } - var isDeep = false; - paths = arrayMap(paths, function(path) { - path = castPath(path, object); - isDeep || (isDeep = path.length > 1); - return path; - }); - copyObject(object, getAllKeysIn(object), result); - if (isDeep) { - result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); - } - var length = paths.length; - while (length--) { - baseUnset(result, paths[length]); + // If the start tangent is not coincident with (x0,y0), line to. + if (Math.abs(t01 - 1) > epsilon$1) { + this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); } - return result; - }); - /** - * The opposite of `_.pickBy`; this method creates an object composed of - * the own and inherited enumerable string keyed properties of `object` that - * `predicate` doesn't return truthy for. The predicate is invoked with two - * arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omitBy(object, _.isNumber); - * // => { 'b': '2' } - */ - function omitBy(object, predicate) { - return pickBy(object, negate(getIteratee(predicate))); + this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); } + }, + arc: function(x, y, r, a0, a1, ccw) { + x = +x, y = +y, r = +r; + var dx = r * Math.cos(a0), + dy = r * Math.sin(a0), + x0 = x + dx, + y0 = y + dy, + cw = 1 ^ ccw, + da = ccw ? a0 - a1 : a1 - a0; - /** - * Creates an object composed of the picked `object` properties. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {...(string|string[])} [paths] The property paths to pick. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pick(object, ['a', 'c']); - * // => { 'a': 1, 'c': 3 } - */ - var pick = flatRest(function(object, paths) { - return object == null ? {} : basePick(object, paths); - }); + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); - /** - * Creates an object composed of the `object` properties `predicate` returns - * truthy for. The predicate is invoked with two arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pickBy(object, _.isNumber); - * // => { 'a': 1, 'c': 3 } - */ - function pickBy(object, predicate) { - if (object == null) { - return {}; - } - var props = arrayMap(getAllKeysIn(object), function(prop) { - return [prop]; - }); - predicate = getIteratee(predicate); - return basePickBy(object, props, function(value, path) { - return predicate(value, path[0]); - }); + // Is this path empty? Move to (x0,y0). + if (this._x1 === null) { + this._ += "M" + x0 + "," + y0; } - /** - * This method is like `_.get` except that if the resolved value is a - * function it's invoked with the `this` binding of its parent object and - * its result is returned. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to resolve. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; - * - * _.result(object, 'a[0].b.c1'); - * // => 3 - * - * _.result(object, 'a[0].b.c2'); - * // => 4 - * - * _.result(object, 'a[0].b.c3', 'default'); - * // => 'default' - * - * _.result(object, 'a[0].b.c3', _.constant('default')); - * // => 'default' - */ - function result(object, path, defaultValue) { - path = castPath(path, object); + // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). + else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) { + this._ += "L" + x0 + "," + y0; + } - var index = -1, - length = path.length; + // Is this arc empty? We’re done. + if (!r) return; - // Ensure the loop is entered when path is empty. - if (!length) { - length = 1; - object = undefined; - } - while (++index < length) { - var value = object == null ? undefined : object[toKey(path[index])]; - if (value === undefined) { - index = length; - value = defaultValue; - } - object = isFunction(value) ? value.call(object) : value; - } - return object; - } + // Does the angle go the wrong way? Flip the direction. + if (da < 0) da = da % tau$2 + tau$2; - /** - * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, - * it's created. Arrays are created for missing index properties while objects - * are created for all other missing properties. Use `_.setWith` to customize - * `path` creation. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.set(object, 'a[0].b.c', 4); - * console.log(object.a[0].b.c); - * // => 4 - * - * _.set(object, ['x', '0', 'y', 'z'], 5); - * console.log(object.x[0].y.z); - * // => 5 - */ - function set(object, path, value) { - return object == null ? object : baseSet(object, path, value); + // Is this a complete circle? Draw two arcs to complete the circle. + if (da > tauEpsilon) { + this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); } - /** - * This method is like `_.set` except that it accepts `customizer` which is - * invoked to produce the objects of `path`. If `customizer` returns `undefined` - * path creation is handled by the method instead. The `customizer` is invoked - * with three arguments: (nsValue, key, nsObject). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * var object = {}; - * - * _.setWith(object, '[0][1]', 'a', Object); - * // => { '0': { '1': 'a' } } - */ - function setWith(object, path, value, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return object == null ? object : baseSet(object, path, value, customizer); + // Is this arc non-empty? Draw an arc! + else if (da > epsilon$1) { + this._ += "A" + r + "," + r + ",0," + (+(da >= pi$2)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); } + }, + rect: function(x, y, w, h) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z"; + }, + toString: function() { + return this._; + } +}; - /** - * Creates an array of own enumerable string keyed-value pairs for `object` - * which can be consumed by `_.fromPairs`. If `object` is a map or set, its - * entries are returned. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias entries - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the key-value pairs. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.toPairs(new Foo); - * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) - */ - var toPairs = createToPairs(keys); +function defaultSource(d) { + return d.source; +} - /** - * Creates an array of own and inherited enumerable string keyed-value pairs - * for `object` which can be consumed by `_.fromPairs`. If `object` is a map - * or set, its entries are returned. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias entriesIn - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the key-value pairs. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.toPairsIn(new Foo); - * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) - */ - var toPairsIn = createToPairs(keysIn); +function defaultTarget(d) { + return d.target; +} - /** - * An alternative to `_.reduce`; this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable string keyed properties thru `iteratee`, with each invocation - * potentially mutating the `accumulator` object. If `accumulator` is not - * provided, a new object with the same `[[Prototype]]` will be used. The - * iteratee is invoked with four arguments: (accumulator, value, key, object). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 1.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @returns {*} Returns the accumulated value. - * @example - * - * _.transform([2, 3, 4], function(result, n) { - * result.push(n *= n); - * return n % 2 == 0; - * }, []); - * // => [4, 9] - * - * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { - * (result[value] || (result[value] = [])).push(key); - * }, {}); - * // => { '1': ['a', 'c'], '2': ['b'] } - */ - function transform(object, iteratee, accumulator) { - var isArr = isArray(object), - isArrLike = isArr || isBuffer(object) || isTypedArray(object); +function defaultRadius(d) { + return d.radius; +} - iteratee = getIteratee(iteratee, 4); - if (accumulator == null) { - var Ctor = object && object.constructor; - if (isArrLike) { - accumulator = isArr ? new Ctor : []; - } - else if (isObject(object)) { - accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; - } - else { - accumulator = {}; - } - } - (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) { - return iteratee(accumulator, value, index, object); - }); - return accumulator; - } +function defaultStartAngle(d) { + return d.startAngle; +} - /** - * Removes the property at `path` of `object`. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to unset. - * @returns {boolean} Returns `true` if the property is deleted, else `false`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 7 } }] }; - * _.unset(object, 'a[0].b.c'); - * // => true - * - * console.log(object); - * // => { 'a': [{ 'b': {} }] }; - * - * _.unset(object, ['a', '0', 'b', 'c']); - * // => true - * - * console.log(object); - * // => { 'a': [{ 'b': {} }] }; - */ - function unset(object, path) { - return object == null ? true : baseUnset(object, path); - } +function defaultEndAngle(d) { + return d.endAngle; +} - /** - * This method is like `_.set` except that accepts `updater` to produce the - * value to set. Use `_.updateWith` to customize `path` creation. The `updater` - * is invoked with one argument: (value). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {Function} updater The function to produce the updated value. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.update(object, 'a[0].b.c', function(n) { return n * n; }); - * console.log(object.a[0].b.c); - * // => 9 - * - * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); - * console.log(object.x[0].y.z); - * // => 0 - */ - function update(object, path, updater) { - return object == null ? object : baseUpdate(object, path, castFunction(updater)); - } +var ribbon = function() { + var source = defaultSource, + target = defaultTarget, + radius = defaultRadius, + startAngle = defaultStartAngle, + endAngle = defaultEndAngle, + context = null; - /** - * This method is like `_.update` except that it accepts `customizer` which is - * invoked to produce the objects of `path`. If `customizer` returns `undefined` - * path creation is handled by the method instead. The `customizer` is invoked - * with three arguments: (nsValue, key, nsObject). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {Function} updater The function to produce the updated value. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * var object = {}; - * - * _.updateWith(object, '[0][1]', _.constant('a'), Object); - * // => { '0': { '1': 'a' } } - */ - function updateWith(object, path, updater, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); - } + function ribbon() { + var buffer, + argv = slice$2.call(arguments), + s = source.apply(this, argv), + t = target.apply(this, argv), + sr = +radius.apply(this, (argv[0] = s, argv)), + sa0 = startAngle.apply(this, argv) - halfPi$1, + sa1 = endAngle.apply(this, argv) - halfPi$1, + sx0 = sr * cos(sa0), + sy0 = sr * sin(sa0), + tr = +radius.apply(this, (argv[0] = t, argv)), + ta0 = startAngle.apply(this, argv) - halfPi$1, + ta1 = endAngle.apply(this, argv) - halfPi$1; - /** - * Creates an array of the own enumerable string keyed property values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.values(new Foo); - * // => [1, 2] (iteration order is not guaranteed) - * - * _.values('hi'); - * // => ['h', 'i'] - */ - function values(object) { - return object == null ? [] : baseValues(object, keys(object)); + if (!context) context = buffer = path(); + + context.moveTo(sx0, sy0); + context.arc(0, 0, sr, sa0, sa1); + if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr? + context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0)); + context.arc(0, 0, tr, ta0, ta1); } + context.quadraticCurveTo(0, 0, sx0, sy0); + context.closePath(); - /** - * Creates an array of the own and inherited enumerable string keyed property - * values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.valuesIn(new Foo); - * // => [1, 2, 3] (iteration order is not guaranteed) - */ - function valuesIn(object) { - return object == null ? [] : baseValues(object, keysIn(object)); - } + if (buffer) return context = null, buffer + "" || null; + } - /*------------------------------------------------------------------------*/ + ribbon.radius = function(_) { + return arguments.length ? (radius = typeof _ === "function" ? _ : constant$5(+_), ribbon) : radius; + }; - /** - * Clamps `number` within the inclusive `lower` and `upper` bounds. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Number - * @param {number} number The number to clamp. - * @param {number} [lower] The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the clamped number. - * @example - * - * _.clamp(-10, -5, 5); - * // => -5 - * - * _.clamp(10, -5, 5); - * // => 5 - */ - function clamp(number, lower, upper) { - if (upper === undefined) { - upper = lower; - lower = undefined; - } - if (upper !== undefined) { - upper = toNumber(upper); - upper = upper === upper ? upper : 0; - } - if (lower !== undefined) { - lower = toNumber(lower); - lower = lower === lower ? lower : 0; - } - return baseClamp(toNumber(number), lower, upper); - } + ribbon.startAngle = function(_) { + return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : startAngle; + }; - /** - * Checks if `n` is between `start` and up to, but not including, `end`. If - * `end` is not specified, it's set to `start` with `start` then set to `0`. - * If `start` is greater than `end` the params are swapped to support - * negative ranges. - * - * @static - * @memberOf _ - * @since 3.3.0 - * @category Number - * @param {number} number The number to check. - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @returns {boolean} Returns `true` if `number` is in the range, else `false`. - * @see _.range, _.rangeRight - * @example - * - * _.inRange(3, 2, 4); - * // => true - * - * _.inRange(4, 8); - * // => true - * - * _.inRange(4, 2); - * // => false - * - * _.inRange(2, 2); - * // => false - * - * _.inRange(1.2, 2); - * // => true - * - * _.inRange(5.2, 4); - * // => false - * - * _.inRange(-3, -2, -6); - * // => true - */ - function inRange(number, start, end) { - start = toFinite(start); - if (end === undefined) { - end = start; - start = 0; - } else { - end = toFinite(end); - } - number = toNumber(number); - return baseInRange(number, start, end); - } + ribbon.endAngle = function(_) { + return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : endAngle; + }; - /** - * Produces a random number between the inclusive `lower` and `upper` bounds. - * If only one argument is provided a number between `0` and the given number - * is returned. If `floating` is `true`, or either `lower` or `upper` are - * floats, a floating-point number is returned instead of an integer. - * - * **Note:** JavaScript follows the IEEE-754 standard for resolving - * floating-point values which can produce unexpected results. - * - * @static - * @memberOf _ - * @since 0.7.0 - * @category Number - * @param {number} [lower=0] The lower bound. - * @param {number} [upper=1] The upper bound. - * @param {boolean} [floating] Specify returning a floating-point number. - * @returns {number} Returns the random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(lower, upper, floating) { - if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { - upper = floating = undefined; - } - if (floating === undefined) { - if (typeof upper == 'boolean') { - floating = upper; - upper = undefined; - } - else if (typeof lower == 'boolean') { - floating = lower; - lower = undefined; - } - } - if (lower === undefined && upper === undefined) { - lower = 0; - upper = 1; - } - else { - lower = toFinite(lower); - if (upper === undefined) { - upper = lower; - lower = 0; - } else { - upper = toFinite(upper); - } - } - if (lower > upper) { - var temp = lower; - lower = upper; - upper = temp; - } - if (floating || lower % 1 || upper % 1) { - var rand = nativeRandom(); - return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); - } - return baseRandom(lower, upper); - } + ribbon.source = function(_) { + return arguments.length ? (source = _, ribbon) : source; + }; - /*------------------------------------------------------------------------*/ + ribbon.target = function(_) { + return arguments.length ? (target = _, ribbon) : target; + }; - /** - * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the camel cased string. - * @example - * - * _.camelCase('Foo Bar'); - * // => 'fooBar' - * - * _.camelCase('--foo-bar--'); - * // => 'fooBar' - * - * _.camelCase('__FOO_BAR__'); - * // => 'fooBar' - */ - var camelCase = createCompounder(function(result, word, index) { - word = word.toLowerCase(); - return result + (index ? capitalize(word) : word); - }); + ribbon.context = function(_) { + return arguments.length ? (context = _ == null ? null : _, ribbon) : context; + }; - /** - * Converts the first character of `string` to upper case and the remaining - * to lower case. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to capitalize. - * @returns {string} Returns the capitalized string. - * @example - * - * _.capitalize('FRED'); - * // => 'Fred' - */ - function capitalize(string) { - return upperFirst(toString(string).toLowerCase()); - } + return ribbon; +}; - /** - * Deburrs `string` by converting - * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) - * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) - * letters to basic Latin letters and removing - * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to deburr. - * @returns {string} Returns the deburred string. - * @example - * - * _.deburr('déjà vu'); - * // => 'deja vu' - */ - function deburr(string) { - string = toString(string); - return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); - } +var prefix = "$"; - /** - * Checks if `string` ends with the given target string. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to inspect. - * @param {string} [target] The string to search for. - * @param {number} [position=string.length] The position to search up to. - * @returns {boolean} Returns `true` if `string` ends with `target`, - * else `false`. - * @example - * - * _.endsWith('abc', 'c'); - * // => true - * - * _.endsWith('abc', 'b'); - * // => false - * - * _.endsWith('abc', 'b', 2); - * // => true - */ - function endsWith(string, target, position) { - string = toString(string); - target = baseToString(target); +function Map() {} + +Map.prototype = map$1.prototype = { + constructor: Map, + has: function(key) { + return (prefix + key) in this; + }, + get: function(key) { + return this[prefix + key]; + }, + set: function(key, value) { + this[prefix + key] = value; + return this; + }, + remove: function(key) { + var property = prefix + key; + return property in this && delete this[property]; + }, + clear: function() { + for (var property in this) if (property[0] === prefix) delete this[property]; + }, + keys: function() { + var keys = []; + for (var property in this) if (property[0] === prefix) keys.push(property.slice(1)); + return keys; + }, + values: function() { + var values = []; + for (var property in this) if (property[0] === prefix) values.push(this[property]); + return values; + }, + entries: function() { + var entries = []; + for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]}); + return entries; + }, + size: function() { + var size = 0; + for (var property in this) if (property[0] === prefix) ++size; + return size; + }, + empty: function() { + for (var property in this) if (property[0] === prefix) return false; + return true; + }, + each: function(f) { + for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this); + } +}; - var length = string.length; - position = position === undefined - ? length - : baseClamp(toInteger(position), 0, length); +function map$1(object, f) { + var map = new Map; - var end = position; - position -= target.length; - return position >= 0 && string.slice(position, end) == target; - } + // Copy constructor. + if (object instanceof Map) object.each(function(value, key) { map.set(key, value); }); - /** - * Converts the characters "&", "<", ">", '"', and "'" in `string` to their - * corresponding HTML entities. - * - * **Note:** No other characters are escaped. To escape additional - * characters use a third-party library like [_he_](https://mths.be/he). - * - * Though the ">" character is escaped for symmetry, characters like - * ">" and "/" don't need escaping in HTML and have no special meaning - * unless they're part of a tag or unquoted attribute value. See - * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) - * (under "semi-related fun fact") for more details. - * - * When working with HTML you should always - * [quote attribute values](http://wonko.com/post/html-escaping) to reduce - * XSS vectors. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('fred, barney, & pebbles'); - * // => 'fred, barney, & pebbles' - */ - function escape(string) { - string = toString(string); - return (string && reHasUnescapedHtml.test(string)) - ? string.replace(reUnescapedHtml, escapeHtmlChar) - : string; + // Index array by numeric index or specified key function. + else if (Array.isArray(object)) { + var i = -1, + n = object.length, + o; + + if (f == null) while (++i < n) map.set(i, object[i]); + else while (++i < n) map.set(f(o = object[i], i, object), o); + } + + // Convert object to map. + else if (object) for (var key in object) map.set(key, object[key]); + + return map; +} + +var nest = function() { + var keys = [], + sortKeys = [], + sortValues, + rollup, + nest; + + function apply(array, depth, createResult, setResult) { + if (depth >= keys.length) { + if (sortValues != null) array.sort(sortValues); + return rollup != null ? rollup(array) : array; } - /** - * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", - * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escapeRegExp('[lodash](https://lodash.com/)'); - * // => '\[lodash\]\(https://lodash\.com/\)' - */ - function escapeRegExp(string) { - string = toString(string); - return (string && reHasRegExpChar.test(string)) - ? string.replace(reRegExpChar, '\\$&') - : string; + var i = -1, + n = array.length, + key = keys[depth++], + keyValue, + value, + valuesByKey = map$1(), + values, + result = createResult(); + + while (++i < n) { + if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) { + values.push(value); + } else { + valuesByKey.set(keyValue, [value]); + } } - /** - * Converts `string` to - * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the kebab cased string. - * @example - * - * _.kebabCase('Foo Bar'); - * // => 'foo-bar' - * - * _.kebabCase('fooBar'); - * // => 'foo-bar' - * - * _.kebabCase('__FOO_BAR__'); - * // => 'foo-bar' - */ - var kebabCase = createCompounder(function(result, word, index) { - return result + (index ? '-' : '') + word.toLowerCase(); + valuesByKey.each(function(values, key) { + setResult(result, key, apply(values, depth, createResult, setResult)); }); - /** - * Converts `string`, as space separated words, to lower case. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the lower cased string. - * @example - * - * _.lowerCase('--Foo-Bar--'); - * // => 'foo bar' - * - * _.lowerCase('fooBar'); - * // => 'foo bar' - * - * _.lowerCase('__FOO_BAR__'); - * // => 'foo bar' - */ - var lowerCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + word.toLowerCase(); - }); + return result; + } - /** - * Converts the first character of `string` to lower case. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.lowerFirst('Fred'); - * // => 'fred' - * - * _.lowerFirst('FRED'); - * // => 'fRED' - */ - var lowerFirst = createCaseFirst('toLowerCase'); + function entries(map, depth) { + if (++depth > keys.length) return map; + var array, sortKey = sortKeys[depth - 1]; + if (rollup != null && depth >= keys.length) array = map.entries(); + else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); }); + return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array; + } - /** - * Pads `string` on the left and right sides if it's shorter than `length`. - * Padding characters are truncated if they can't be evenly divided by `length`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.pad('abc', 8); - * // => ' abc ' - * - * _.pad('abc', 8, '_-'); - * // => '_-abc_-_' - * - * _.pad('abc', 3); - * // => 'abc' - */ - function pad(string, length, chars) { - string = toString(string); - length = toInteger(length); + return nest = { + object: function(array) { return apply(array, 0, createObject, setObject); }, + map: function(array) { return apply(array, 0, createMap, setMap); }, + entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); }, + key: function(d) { keys.push(d); return nest; }, + sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; }, + sortValues: function(order) { sortValues = order; return nest; }, + rollup: function(f) { rollup = f; return nest; } + }; +}; - var strLength = length ? stringSize(string) : 0; - if (!length || strLength >= length) { - return string; - } - var mid = (length - strLength) / 2; - return ( - createPadding(nativeFloor(mid), chars) + - string + - createPadding(nativeCeil(mid), chars) - ); - } +function createObject() { + return {}; +} - /** - * Pads `string` on the right side if it's shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padEnd('abc', 6); - * // => 'abc ' - * - * _.padEnd('abc', 6, '_-'); - * // => 'abc_-_' - * - * _.padEnd('abc', 3); - * // => 'abc' - */ - function padEnd(string, length, chars) { - string = toString(string); - length = toInteger(length); +function setObject(object, key, value) { + object[key] = value; +} - var strLength = length ? stringSize(string) : 0; - return (length && strLength < length) - ? (string + createPadding(length - strLength, chars)) - : string; - } +function createMap() { + return map$1(); +} - /** - * Pads `string` on the left side if it's shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padStart('abc', 6); - * // => ' abc' - * - * _.padStart('abc', 6, '_-'); - * // => '_-_abc' - * - * _.padStart('abc', 3); - * // => 'abc' - */ - function padStart(string, length, chars) { - string = toString(string); - length = toInteger(length); +function setMap(map, key, value) { + map.set(key, value); +} - var strLength = length ? stringSize(string) : 0; - return (length && strLength < length) - ? (createPadding(length - strLength, chars) + string) - : string; - } +function Set() {} - /** - * Converts `string` to an integer of the specified radix. If `radix` is - * `undefined` or `0`, a `radix` of `10` is used unless `value` is a - * hexadecimal, in which case a `radix` of `16` is used. - * - * **Note:** This method aligns with the - * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category String - * @param {string} string The string to convert. - * @param {number} [radix=10] The radix to interpret `value` by. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {number} Returns the converted integer. - * @example - * - * _.parseInt('08'); - * // => 8 - * - * _.map(['6', '08', '10'], _.parseInt); - * // => [6, 8, 10] - */ - function parseInt(string, radix, guard) { - if (guard || radix == null) { - radix = 0; - } else if (radix) { - radix = +radix; - } - return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0); - } +var proto = map$1.prototype; - /** - * Repeats the given string `n` times. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to repeat. - * @param {number} [n=1] The number of times to repeat the string. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {string} Returns the repeated string. - * @example - * - * _.repeat('*', 3); - * // => '***' - * - * _.repeat('abc', 2); - * // => 'abcabc' - * - * _.repeat('abc', 0); - * // => '' - */ - function repeat(string, n, guard) { - if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) { - n = 1; - } else { - n = toInteger(n); - } - return baseRepeat(toString(string), n); - } +Set.prototype = set$2.prototype = { + constructor: Set, + has: proto.has, + add: function(value) { + value += ""; + this[prefix + value] = value; + return this; + }, + remove: proto.remove, + clear: proto.clear, + values: proto.keys, + size: proto.size, + empty: proto.empty, + each: proto.each +}; - /** - * Replaces matches for `pattern` in `string` with `replacement`. - * - * **Note:** This method is based on - * [`String#replace`](https://mdn.io/String/replace). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to modify. - * @param {RegExp|string} pattern The pattern to replace. - * @param {Function|string} replacement The match replacement. - * @returns {string} Returns the modified string. - * @example - * - * _.replace('Hi Fred', 'Fred', 'Barney'); - * // => 'Hi Barney' - */ - function replace() { - var args = arguments, - string = toString(args[0]); +function set$2(object, f) { + var set = new Set; - return args.length < 3 ? string : string.replace(args[1], args[2]); - } + // Copy constructor. + if (object instanceof Set) object.each(function(value) { set.add(value); }); - /** - * Converts `string` to - * [snake case](https://en.wikipedia.org/wiki/Snake_case). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the snake cased string. - * @example - * - * _.snakeCase('Foo Bar'); - * // => 'foo_bar' - * - * _.snakeCase('fooBar'); - * // => 'foo_bar' - * - * _.snakeCase('--FOO-BAR--'); - * // => 'foo_bar' - */ - var snakeCase = createCompounder(function(result, word, index) { - return result + (index ? '_' : '') + word.toLowerCase(); - }); + // Otherwise, assume it’s an array. + else if (object) { + var i = -1, n = object.length; + if (f == null) while (++i < n) set.add(object[i]); + else while (++i < n) set.add(f(object[i], i, object)); + } - /** - * Splits `string` by `separator`. - * - * **Note:** This method is based on - * [`String#split`](https://mdn.io/String/split). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to split. - * @param {RegExp|string} separator The separator pattern to split by. - * @param {number} [limit] The length to truncate results to. - * @returns {Array} Returns the string segments. - * @example - * - * _.split('a-b-c', '-', 2); - * // => ['a', 'b'] - */ - function split(string, separator, limit) { - if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) { - separator = limit = undefined; - } - limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0; - if (!limit) { - return []; - } - string = toString(string); - if (string && ( - typeof separator == 'string' || - (separator != null && !isRegExp(separator)) - )) { - separator = baseToString(separator); - if (!separator && hasUnicode(string)) { - return castSlice(stringToArray(string), 0, limit); - } - } - return string.split(separator, limit); - } + return set; +} - /** - * Converts `string` to - * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). - * - * @static - * @memberOf _ - * @since 3.1.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the start cased string. - * @example - * - * _.startCase('--foo-bar--'); - * // => 'Foo Bar' - * - * _.startCase('fooBar'); - * // => 'Foo Bar' - * - * _.startCase('__FOO_BAR__'); - * // => 'FOO BAR' - */ - var startCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + upperFirst(word); - }); +var keys = function(map) { + var keys = []; + for (var key in map) keys.push(key); + return keys; +}; - /** - * Checks if `string` starts with the given target string. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to inspect. - * @param {string} [target] The string to search for. - * @param {number} [position=0] The position to search from. - * @returns {boolean} Returns `true` if `string` starts with `target`, - * else `false`. - * @example - * - * _.startsWith('abc', 'a'); - * // => true - * - * _.startsWith('abc', 'b'); - * // => false - * - * _.startsWith('abc', 'b', 1); - * // => true - */ - function startsWith(string, target, position) { - string = toString(string); - position = position == null - ? 0 - : baseClamp(toInteger(position), 0, string.length); +var values = function(map) { + var values = []; + for (var key in map) values.push(map[key]); + return values; +}; - target = baseToString(target); - return string.slice(position, position + target.length) == target; - } +var entries = function(map) { + var entries = []; + for (var key in map) entries.push({key: key, value: map[key]}); + return entries; +}; - /** - * Creates a compiled template function that can interpolate data properties - * in "interpolate" delimiters, HTML-escape interpolated data properties in - * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data - * properties may be accessed as free variables in the template. If a setting - * object is given, it takes precedence over `_.templateSettings` values. - * - * **Note:** In the development build `_.template` utilizes - * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) - * for easier debugging. - * - * For more information on precompiling templates see - * [lodash's custom builds documentation](https://lodash.com/custom-builds). - * - * For more information on Chrome extension sandboxes see - * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category String - * @param {string} [string=''] The template string. - * @param {Object} [options={}] The options object. - * @param {RegExp} [options.escape=_.templateSettings.escape] - * The HTML "escape" delimiter. - * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] - * The "evaluate" delimiter. - * @param {Object} [options.imports=_.templateSettings.imports] - * An object to import into the template as free variables. - * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] - * The "interpolate" delimiter. - * @param {string} [options.sourceURL='lodash.templateSources[n]'] - * The sourceURL of the compiled template. - * @param {string} [options.variable='obj'] - * The data object variable name. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the compiled template function. - * @example - * - * // Use the "interpolate" delimiter to create a compiled template. - * var compiled = _.template('hello <%= user %>!'); - * compiled({ 'user': 'fred' }); - * // => 'hello fred!' - * - * // Use the HTML "escape" delimiter to escape data property values. - * var compiled = _.template('<%- value %>'); - * compiled({ 'value': '