]> git.openstreetmap.org Git - rails.git/commitdiff
Merge remote-tracking branch 'upstream/pull/1926'
authorTom Hughes <tom@compton.nu>
Wed, 28 Aug 2019 16:23:10 +0000 (17:23 +0100)
committerTom Hughes <tom@compton.nu>
Wed, 28 Aug 2019 16:23:10 +0000 (17:23 +0100)
933 files changed:
.erb-lint.yml [new file with mode: 0644]
.gitignore
.mailmap
.rubocop.yml
.rubocop_todo.yml
.travis.yml
CONFIGURE.md
CONTRIBUTING.md
Gemfile
Gemfile.lock
INSTALL.md
Vagrantfile
Vendorfile
app/abilities/ability.rb [new file with mode: 0644]
app/abilities/api_ability.rb [new file with mode: 0644]
app/abilities/api_capability.rb [new file with mode: 0644]
app/assets/images/avatar_large.png [moved from app/assets/images/users/images/large.png with 100% similarity]
app/assets/images/avatar_small.png [moved from app/assets/images/users/images/small.png with 100% similarity]
app/assets/images/avatars.svg [moved from app/assets/images/users/images/user-icons.svg with 100% similarity]
app/assets/images/banners/saveyourinternet.png [new file with mode: 0644]
app/assets/javascripts/application.js
app/assets/javascripts/diary_entry.js
app/assets/javascripts/edit/id.js.erb
app/assets/javascripts/embed.js.erb
app/assets/javascripts/fixthemap.js
app/assets/javascripts/id.js
app/assets/javascripts/index.js
app/assets/javascripts/index/browse.js
app/assets/javascripts/index/changeset.js
app/assets/javascripts/index/contextmenu.js
app/assets/javascripts/index/directions.js
app/assets/javascripts/index/directions/fossgis.js [new file with mode: 0644]
app/assets/javascripts/index/directions/graphhopper.js
app/assets/javascripts/index/directions/mapquest.js [deleted file]
app/assets/javascripts/index/directions/osrm.js [deleted file]
app/assets/javascripts/index/export.js
app/assets/javascripts/index/history.js
app/assets/javascripts/index/new_note.js
app/assets/javascripts/index/note.js
app/assets/javascripts/index/notes.js
app/assets/javascripts/index/query.js
app/assets/javascripts/index/search.js
app/assets/javascripts/leaflet.key.js
app/assets/javascripts/leaflet.layers.js
app/assets/javascripts/leaflet.map.js
app/assets/javascripts/leaflet.note.js
app/assets/javascripts/leaflet.query.js
app/assets/javascripts/leaflet.share.js
app/assets/javascripts/leaflet.sidebar.js
app/assets/javascripts/leaflet.zoom.js
app/assets/javascripts/login.js
app/assets/javascripts/oauth.js
app/assets/javascripts/osm.js.erb
app/assets/javascripts/piwik.js
app/assets/javascripts/richtext.js
app/assets/javascripts/router.js
app/assets/javascripts/user.js
app/assets/javascripts/welcome.js
app/assets/stylesheets/common.scss
app/assets/stylesheets/errors.scss [new file with mode: 0644]
app/assets/stylesheets/small.scss
app/controllers/amf_controller.rb [deleted file]
app/controllers/api/amf_controller.rb [new file with mode: 0644]
app/controllers/api/capabilities_controller.rb [new file with mode: 0644]
app/controllers/api/changes_controller.rb [new file with mode: 0644]
app/controllers/api/changeset_comments_controller.rb [new file with mode: 0644]
app/controllers/api/changesets_controller.rb [new file with mode: 0644]
app/controllers/api/map_controller.rb [new file with mode: 0644]
app/controllers/api/nodes_controller.rb [new file with mode: 0644]
app/controllers/api/notes_controller.rb [new file with mode: 0644]
app/controllers/api/old_controller.rb [new file with mode: 0644]
app/controllers/api/old_nodes_controller.rb [new file with mode: 0644]
app/controllers/api/old_relations_controller.rb [new file with mode: 0644]
app/controllers/api/old_ways_controller.rb [new file with mode: 0644]
app/controllers/api/permissions_controller.rb [new file with mode: 0644]
app/controllers/api/relations_controller.rb [new file with mode: 0644]
app/controllers/api/search_controller.rb [new file with mode: 0644]
app/controllers/api/tracepoints_controller.rb [new file with mode: 0644]
app/controllers/api/traces_controller.rb [new file with mode: 0644]
app/controllers/api/user_preferences_controller.rb [new file with mode: 0644]
app/controllers/api/users_controller.rb [new file with mode: 0644]
app/controllers/api/versions_controller.rb [new file with mode: 0644]
app/controllers/api/ways_controller.rb [new file with mode: 0644]
app/controllers/api_controller.rb
app/controllers/application_controller.rb
app/controllers/browse_controller.rb
app/controllers/changeset_comments_controller.rb [new file with mode: 0644]
app/controllers/changeset_controller.rb [deleted file]
app/controllers/changesets_controller.rb [new file with mode: 0644]
app/controllers/diary_entries_controller.rb [moved from app/controllers/diary_entry_controller.rb with 54% similarity]
app/controllers/directions_controller.rb
app/controllers/errors_controller.rb [new file with mode: 0644]
app/controllers/export_controller.rb
app/controllers/geocoder_controller.rb
app/controllers/issue_comments_controller.rb
app/controllers/issues_controller.rb
app/controllers/messages_controller.rb
app/controllers/node_controller.rb [deleted file]
app/controllers/notes_controller.rb
app/controllers/oauth_clients_controller.rb
app/controllers/oauth_controller.rb
app/controllers/old_controller.rb [deleted file]
app/controllers/old_node_controller.rb [deleted file]
app/controllers/old_relation_controller.rb [deleted file]
app/controllers/old_way_controller.rb [deleted file]
app/controllers/redactions_controller.rb
app/controllers/relation_controller.rb [deleted file]
app/controllers/reports_controller.rb
app/controllers/search_controller.rb [deleted file]
app/controllers/site_controller.rb
app/controllers/swf_controller.rb [deleted file]
app/controllers/traces_controller.rb
app/controllers/user_blocks_controller.rb
app/controllers/user_preferences_controller.rb [deleted file]
app/controllers/user_roles_controller.rb
app/controllers/users_controller.rb [moved from app/controllers/user_controller.rb with 75% similarity]
app/controllers/way_controller.rb [deleted file]
app/helpers/application_helper.rb
app/helpers/banner_helper.rb
app/helpers/browse_helper.rb
app/helpers/browse_tags_helper.rb [new file with mode: 0644]
app/helpers/changesets_helper.rb [moved from app/helpers/changeset_helper.rb with 65% similarity]
app/helpers/issues_helper.rb
app/helpers/note_helper.rb
app/helpers/notifier_helper.rb
app/helpers/title_helper.rb
app/helpers/user_blocks_helper.rb
app/helpers/user_helper.rb
app/helpers/user_roles_helper.rb
app/jobs/application_job.rb [new file with mode: 0644]
app/jobs/trace_destroyer_job.rb [new file with mode: 0644]
app/jobs/trace_importer_job.rb [new file with mode: 0644]
app/mailers/notifier.rb [moved from app/models/notifier.rb with 79% similarity]
app/models/acl.rb
app/models/changeset.rb
app/models/changeset_comment.rb
app/models/changeset_tag.rb
app/models/client_application.rb
app/models/concerns/geo_record.rb [moved from lib/geo_record.rb with 88% similarity]
app/models/concerns/not_redactable.rb [moved from lib/not_redactable.rb with 78% similarity]
app/models/concerns/object_metadata.rb [moved from lib/object_metadata.rb with 97% similarity]
app/models/diary_comment.rb
app/models/diary_entry.rb
app/models/diary_entry_subscription.rb
app/models/friendship.rb [moved from app/models/friend.rb with 66% similarity]
app/models/issue_comment.rb
app/models/language.rb
app/models/message.rb
app/models/node.rb
app/models/node_tag.rb
app/models/note.rb
app/models/note_comment.rb
app/models/oauth_nonce.rb
app/models/old_node.rb
app/models/old_node_tag.rb
app/models/old_relation.rb
app/models/old_relation_member.rb
app/models/old_relation_tag.rb
app/models/old_way.rb
app/models/old_way_node.rb
app/models/old_way_tag.rb
app/models/redaction.rb
app/models/relation.rb
app/models/relation_member.rb
app/models/relation_tag.rb
app/models/report.rb
app/models/request_token.rb
app/models/trace.rb
app/models/tracepoint.rb
app/models/tracetag.rb
app/models/user.rb
app/models/user_block.rb
app/models/user_preference.rb
app/models/user_role.rb
app/models/user_token.rb
app/models/way.rb
app/models/way_node.rb
app/models/way_tag.rb
app/validators/characters_validator.rb [new file with mode: 0644]
app/validators/utf8_validator.rb [moved from lib/validators.rb with 100% similarity]
app/validators/whitespace_validator.rb [new file with mode: 0644]
app/views/api/capabilities/show.builder [new file with mode: 0644]
app/views/api/changesets/_changeset.builder [new file with mode: 0644]
app/views/api/changesets/changeset.builder [new file with mode: 0644]
app/views/api/changesets/changesets.builder [new file with mode: 0644]
app/views/api/map/_bounds.xml.builder [new file with mode: 0644]
app/views/api/map/index.xml.builder [new file with mode: 0644]
app/views/api/nodes/_node.xml.builder [new file with mode: 0644]
app/views/api/nodes/index.xml.builder [new file with mode: 0644]
app/views/api/nodes/show.xml.builder [new file with mode: 0644]
app/views/api/notes/_comment.html.erb [moved from app/views/notes/_comment.html.erb with 73% similarity]
app/views/api/notes/_description.html.erb [moved from app/views/notes/_description.html.erb with 100% similarity]
app/views/api/notes/_entry.html.erb [moved from app/views/notes/_entry.html.erb with 100% similarity]
app/views/api/notes/_note.gpx.builder [moved from app/views/notes/_note.gpx.builder with 100% similarity]
app/views/api/notes/_note.json.jsonify [moved from app/views/notes/_note.json.jsonify with 100% similarity]
app/views/api/notes/_note.rss.builder [moved from app/views/notes/_note.rss.builder with 73% similarity]
app/views/api/notes/_note.xml.builder [moved from app/views/notes/_note.xml.builder with 100% similarity]
app/views/api/notes/feed.rss.builder [moved from app/views/notes/feed.rss.builder with 56% similarity]
app/views/api/notes/index.gpx.builder [moved from app/views/notes/index.gpx.builder with 82% similarity]
app/views/api/notes/index.json.jsonify [moved from app/views/notes/index.json.jsonify with 53% similarity]
app/views/api/notes/index.rss.builder [new file with mode: 0644]
app/views/api/notes/index.xml.builder [new file with mode: 0644]
app/views/api/notes/show.gpx.builder [moved from app/views/notes/show.gpx.builder with 85% similarity]
app/views/api/notes/show.json.jsonify [new file with mode: 0644]
app/views/api/notes/show.rss.builder [new file with mode: 0644]
app/views/api/notes/show.xml.builder [new file with mode: 0644]
app/views/api/old_nodes/_old_node.xml.builder [new file with mode: 0644]
app/views/api/old_nodes/history.xml.builder [new file with mode: 0644]
app/views/api/old_nodes/version.xml.builder [new file with mode: 0644]
app/views/api/old_relations/_old_relation.xml.builder [new file with mode: 0644]
app/views/api/old_relations/history.xml.builder [new file with mode: 0644]
app/views/api/old_relations/version.xml.builder [new file with mode: 0644]
app/views/api/old_ways/_old_way.xml.builder [new file with mode: 0644]
app/views/api/old_ways/history.xml.builder [new file with mode: 0644]
app/views/api/old_ways/version.xml.builder [new file with mode: 0644]
app/views/api/permissions/show.builder [moved from app/views/api/permissions.builder with 69% similarity]
app/views/api/relations/_relation.xml.builder [new file with mode: 0644]
app/views/api/relations/full.xml.builder [new file with mode: 0644]
app/views/api/relations/index.xml.builder [new file with mode: 0644]
app/views/api/relations/relations_for_node.xml.builder [new file with mode: 0644]
app/views/api/relations/relations_for_relation.xml.builder [new file with mode: 0644]
app/views/api/relations/relations_for_way.xml.builder [new file with mode: 0644]
app/views/api/relations/show.xml.builder [new file with mode: 0644]
app/views/api/traces/_trace.builder [new file with mode: 0644]
app/views/api/traces/show.builder [new file with mode: 0644]
app/views/api/users/_user.builder [new file with mode: 0644]
app/views/api/users/gpx_files.builder [new file with mode: 0644]
app/views/api/users/index.builder [new file with mode: 0644]
app/views/api/users/show.builder [new file with mode: 0644]
app/views/api/versions/show.builder [new file with mode: 0644]
app/views/api/ways/_way.xml.builder [new file with mode: 0644]
app/views/api/ways/full.xml.builder [new file with mode: 0644]
app/views/api/ways/index.xml.builder [new file with mode: 0644]
app/views/api/ways/show.xml.builder [new file with mode: 0644]
app/views/api/ways/ways_for_node.xml.builder [new file with mode: 0644]
app/views/browse/_common_details.html.erb
app/views/browse/_containing_relation.html.erb
app/views/browse/_node.html.erb
app/views/browse/_relation.html.erb
app/views/browse/_relation_member.html.erb
app/views/browse/_tag_details.html.erb
app/views/browse/_way.html.erb
app/views/browse/changeset.html.erb
app/views/browse/feature.html.erb
app/views/browse/history.html.erb
app/views/browse/new_note.html.erb
app/views/browse/note.html.erb
app/views/browse/query.html.erb
app/views/browse/timeout.html.erb
app/views/changeset/_comment.html.erb [deleted file]
app/views/changeset/_user.atom.builder [deleted file]
app/views/changeset/list.html.erb [deleted file]
app/views/changeset/timeout.html.erb [deleted file]
app/views/changeset_comments/_comment.html.erb [new file with mode: 0644]
app/views/changeset_comments/_comments.rss.builder [moved from app/views/changeset/_comments.rss.builder with 82% similarity]
app/views/changeset_comments/index.rss.builder [moved from app/views/changeset/comments_feed.rss.builder with 70% similarity]
app/views/changeset_comments/timeout.atom.builder [moved from app/views/changeset/timeout.atom.builder with 100% similarity]
app/views/changeset_comments/timeout.html.erb [new file with mode: 0644]
app/views/changesets/_changeset.html.erb [moved from app/views/changeset/_changeset.html.erb with 70% similarity]
app/views/changesets/_user.atom.builder [new file with mode: 0644]
app/views/changesets/history.html.erb [moved from app/views/changeset/history.html.erb with 57% similarity]
app/views/changesets/index.atom.builder [moved from app/views/changeset/list.atom.builder with 76% similarity]
app/views/changesets/index.html.erb [new file with mode: 0644]
app/views/changesets/timeout.atom.builder [new file with mode: 0644]
app/views/changesets/timeout.html.erb [new file with mode: 0644]
app/views/diary_entries/_diary_comment.html.erb [new file with mode: 0644]
app/views/diary_entries/_diary_entry.html.erb [new file with mode: 0644]
app/views/diary_entries/_form.html.erb [new file with mode: 0644]
app/views/diary_entries/_location.html.erb [moved from app/views/diary_entry/_location.html.erb with 79% similarity]
app/views/diary_entries/comments.html.erb [new file with mode: 0644]
app/views/diary_entries/edit.html.erb [new file with mode: 0644]
app/views/diary_entries/index.html.erb [moved from app/views/diary_entry/list.html.erb with 53% similarity]
app/views/diary_entries/new.html.erb [new file with mode: 0644]
app/views/diary_entries/no_such_entry.html.erb [new file with mode: 0644]
app/views/diary_entries/rss.rss.builder [moved from app/views/diary_entry/rss.rss.builder with 63% similarity]
app/views/diary_entries/show.html.erb [moved from app/views/diary_entry/view.html.erb with 50% similarity]
app/views/diary_entry/_diary_comment.html.erb [deleted file]
app/views/diary_entry/_diary_entry.html.erb [deleted file]
app/views/diary_entry/_diary_list_entry.html.erb [deleted file]
app/views/diary_entry/comments.html.erb [deleted file]
app/views/diary_entry/edit.html.erb [deleted file]
app/views/diary_entry/no_such_entry.html.erb [deleted file]
app/views/errors/forbidden.html.erb [new file with mode: 0644]
app/views/errors/internal_server_error.html.erb [new file with mode: 0644]
app/views/errors/not_found.html.erb [new file with mode: 0644]
app/views/export/embed.html.erb
app/views/geocoder/results.html.erb
app/views/geocoder/search.html.erb
app/views/issues/_comments.html.erb
app/views/issues/_reports.html.erb
app/views/issues/index.html.erb
app/views/issues/show.html.erb
app/views/layouts/_head.html.erb
app/views/layouts/_header.html.erb
app/views/layouts/_search.html.erb
app/views/layouts/error.html.erb [new file with mode: 0644]
app/views/layouts/map.html.erb
app/views/layouts/notifier.html.erb
app/views/layouts/site.html.erb
app/views/messages/_message_count.html.erb
app/views/messages/_message_summary.html.erb
app/views/messages/_sent_message_summary.html.erb
app/views/messages/inbox.html.erb
app/views/messages/new.html.erb
app/views/messages/no_such_message.html.erb
app/views/messages/outbox.html.erb
app/views/messages/show.html.erb
app/views/notes/_notes_paging_nav.html.erb
app/views/notes/_user.html.erb [deleted file]
app/views/notes/index.rss.builder [deleted file]
app/views/notes/index.xml.builder [deleted file]
app/views/notes/mine.html.erb
app/views/notes/show.json.jsonify [deleted file]
app/views/notes/show.rss.builder [deleted file]
app/views/notes/show.xml.builder [deleted file]
app/views/notifier/_gpx_description.html.erb
app/views/notifier/_message_body.html.erb
app/views/notifier/changeset_comment_notification.html.erb
app/views/notifier/diary_comment_notification.html.erb
app/views/notifier/email_confirm.html.erb
app/views/notifier/email_confirm.text.erb
app/views/notifier/friend_notification.html.erb
app/views/notifier/gpx_failure.html.erb
app/views/notifier/gpx_success.html.erb
app/views/notifier/lost_password.html.erb
app/views/notifier/message_notification.html.erb
app/views/notifier/note_comment_notification.html.erb
app/views/notifier/signup_confirm.html.erb
app/views/notifier/signup_confirm.text.erb
app/views/oauth/authorize.html.erb
app/views/oauth_clients/_form.html.erb
app/views/oauth_clients/edit.html.erb
app/views/oauth_clients/index.html.erb
app/views/oauth_clients/new.html.erb
app/views/oauth_clients/show.html.erb
app/views/redactions/_redactions.html.erb [deleted file]
app/views/redactions/edit.html.erb
app/views/redactions/index.html.erb
app/views/redactions/new.html.erb
app/views/redactions/show.html.erb
app/views/reports/new.html.erb
app/views/site/_id.html.erb
app/views/site/_potlatch.html.erb
app/views/site/_potlatch2.html.erb
app/views/site/about.html.erb
app/views/site/copyright.html.erb
app/views/site/edit.html.erb
app/views/site/export.html.erb
app/views/site/fixthemap.html.erb
app/views/site/help.html.erb
app/views/site/id.html.erb
app/views/site/index.html.erb
app/views/site/key.html.erb
app/views/site/offline.html.erb
app/views/traces/_trace.html.erb
app/views/traces/_trace_optionals.html.erb
app/views/traces/_trace_paging_nav.html.erb
app/views/traces/edit.html.erb
app/views/traces/georss.rss.builder
app/views/traces/index.html.erb [new file with mode: 0644]
app/views/traces/list.html.erb [deleted file]
app/views/traces/new.html.erb
app/views/traces/offline.html.erb
app/views/traces/show.html.erb [new file with mode: 0644]
app/views/traces/view.html.erb [deleted file]
app/views/user/_api_user.builder [deleted file]
app/views/user/_contact.html.erb [deleted file]
app/views/user/_terms.html.erb [deleted file]
app/views/user/_user.html.erb [deleted file]
app/views/user/account.html.erb [deleted file]
app/views/user/api_read.builder [deleted file]
app/views/user/api_users.builder [deleted file]
app/views/user/blocked.html.erb [deleted file]
app/views/user/lost_password.html.erb [deleted file]
app/views/user/no_such_user.html.erb [deleted file]
app/views/user/reset_password.html.erb [deleted file]
app/views/user/terms.html.erb [deleted file]
app/views/user_blocks/_block.html.erb
app/views/user_blocks/_blocks.html.erb
app/views/user_blocks/blocks_by.html.erb
app/views/user_blocks/blocks_on.html.erb
app/views/user_blocks/edit.html.erb
app/views/user_blocks/index.html.erb
app/views/user_blocks/new.html.erb
app/views/user_blocks/not_found.html.erb
app/views/user_blocks/revoke.html.erb
app/views/user_blocks/show.html.erb
app/views/users/_auth_association.html.erb [moved from app/views/user/_auth_association.html.erb with 100% similarity]
app/views/users/_contact.html.erb [new file with mode: 0644]
app/views/users/_popup.html.erb [moved from app/views/user/_popup.html.erb with 80% similarity]
app/views/users/_terms.html.erb [new file with mode: 0644]
app/views/users/_user.html.erb [new file with mode: 0644]
app/views/users/account.html.erb [new file with mode: 0644]
app/views/users/blocked.html.erb [new file with mode: 0644]
app/views/users/confirm.html.erb [moved from app/views/user/confirm.html.erb with 81% similarity]
app/views/users/confirm_email.html.erb [moved from app/views/user/confirm_email.html.erb with 68% similarity]
app/views/users/index.html.erb [moved from app/views/user/list.html.erb with 58% similarity]
app/views/users/login.html.erb [moved from app/views/user/login.html.erb with 60% similarity]
app/views/users/logout.html.erb [moved from app/views/user/logout.html.erb with 73% similarity]
app/views/users/lost_password.html.erb [new file with mode: 0644]
app/views/users/make_friend.html.erb [moved from app/views/user/make_friend.html.erb with 100% similarity]
app/views/users/new.html.erb [moved from app/views/user/new.html.erb with 54% similarity]
app/views/users/no_such_user.html.erb [new file with mode: 0644]
app/views/users/remove_friend.html.erb [moved from app/views/user/remove_friend.html.erb with 100% similarity]
app/views/users/reset_password.html.erb [new file with mode: 0644]
app/views/users/show.html.erb [moved from app/views/user/view.html.erb with 53% similarity]
app/views/users/suspended.html.erb [moved from app/views/user/suspended.html.erb with 83% similarity]
app/views/users/terms.html.erb [new file with mode: 0644]
bin/yarn
config/.gitignore
config/application.rb
config/banners.yml
config/environments/development.rb
config/environments/production.rb
config/environments/test.rb
config/eslint.json [new file with mode: 0644]
config/example.application.yml [deleted file]
config/example.storage.yml [new file with mode: 0644]
config/i18n-js.yml
config/initializers/action_mailer.rb
config/initializers/active_storage.rb [new file with mode: 0644]
config/initializers/assets.rb
config/initializers/browser.rb [new file with mode: 0644]
config/initializers/canonical_rails.rb
config/initializers/config.rb [new file with mode: 0644]
config/initializers/errors.rb [new file with mode: 0644]
config/initializers/eslint.rb [new file with mode: 0644]
config/initializers/i18n.rb
config/initializers/oauth.rb
config/initializers/omniauth.rb
config/initializers/paperclip.rb [deleted file]
config/initializers/r2.rb
config/initializers/sanitize.rb
config/initializers/secure_headers.rb
config/initializers/session_store.rb
config/initializers/strong_migrations.rb [new file with mode: 0644]
config/jshint.yml [deleted file]
config/locales/af.yml
config/locales/aln.yml
config/locales/ar.yml
config/locales/arz.yml
config/locales/ast.yml
config/locales/az.yml
config/locales/ba.yml
config/locales/be-Tarask.yml
config/locales/be.yml
config/locales/bg.yml
config/locales/bn.yml
config/locales/br.yml
config/locales/bs.yml
config/locales/ca.yml
config/locales/ce.yml
config/locales/cs.yml
config/locales/cy.yml
config/locales/da.yml
config/locales/de.yml
config/locales/diq.yml
config/locales/dsb.yml
config/locales/el.yml
config/locales/en-GB.yml
config/locales/en.yml
config/locales/eo.yml
config/locales/es.yml
config/locales/et.yml
config/locales/eu.yml
config/locales/fa.yml
config/locales/fi.yml
config/locales/fr.yml
config/locales/fur.yml
config/locales/ga.yml
config/locales/gd.yml
config/locales/gl.yml
config/locales/he.yml
config/locales/hr.yml
config/locales/hsb.yml
config/locales/hu.yml
config/locales/ia.yml
config/locales/id.yml
config/locales/is.yml
config/locales/it.yml
config/locales/ja.yml
config/locales/ka.yml
config/locales/kab.yml
config/locales/km.yml
config/locales/kn.yml
config/locales/ko.yml
config/locales/ku-Latn.yml
config/locales/lb.yml
config/locales/lt.yml
config/locales/lv.yml
config/locales/mk.yml
config/locales/mo.yml [new file with mode: 0644]
config/locales/mr.yml
config/locales/ms.yml
config/locales/my.yml [new file with mode: 0644]
config/locales/nb.yml
config/locales/nds.yml
config/locales/ne.yml
config/locales/nl.yml
config/locales/nn.yml
config/locales/oc.yml
config/locales/pa.yml
config/locales/pl.yml
config/locales/pt-BR.yml
config/locales/pt-PT.yml
config/locales/ro.yml
config/locales/ru.yml
config/locales/scn.yml
config/locales/sco.yml
config/locales/sk.yml
config/locales/sl.yml
config/locales/sq.yml
config/locales/sr-Latn.yml
config/locales/sr.yml
config/locales/sv.yml
config/locales/ta.yml
config/locales/te.yml
config/locales/th.yml
config/locales/tl.yml
config/locales/tr.yml
config/locales/uk.yml
config/locales/vi.yml
config/locales/zh-CN.yml
config/locales/zh-TW.yml
config/preinitializer.rb [deleted file]
config/routes.rb
config/settings.yml [new file with mode: 0644]
config/settings/development.yml [new file with mode: 0644]
config/settings/production.yml [new file with mode: 0644]
config/settings/test.yml [new file with mode: 0644]
config/storage.yml [deleted file]
config/wiki_pages.yml
db/functions/Makefile
db/migrate/001_create_osm_db.rb
db/migrate/002_cleanup_osm_db.rb
db/migrate/003_sql_session_store_setup.rb
db/migrate/004_user_enhancements.rb
db/migrate/005_tile_tracepoints.rb
db/migrate/006_tile_nodes.rb
db/migrate/007_add_relations.rb
db/migrate/008_remove_segments.rb
db/migrate/009_way_nodes_node_idx.rb
db/migrate/010_diary_comments.rb
db/migrate/011_add_user_image.rb
db/migrate/012_add_admin_flag.rb
db/migrate/013_add_email_valid.rb
db/migrate/014_add_new_email.rb
db/migrate/015_add_user_visible.rb
db/migrate/016_add_creation_ip.rb
db/migrate/017_add_gpx_indexes.rb
db/migrate/018_create_acls.rb
db/migrate/019_add_timestamp_indexes.rb
db/migrate/020_populate_node_tags_and_remove.rb
db/migrate/021_move_to_innodb.rb
db/migrate/022_key_constraints.rb
db/migrate/023_add_changesets.rb
db/migrate/024_order_relation_members.rb
db/migrate/025_add_end_time_to_changesets.rb
db/migrate/026_add_changeset_user_index.rb
db/migrate/027_add_changeset_indexes.rb
db/migrate/028_add_more_changeset_indexes.rb
db/migrate/029_add_user_foreign_keys.rb
db/migrate/030_add_foreign_keys.rb
db/migrate/031_create_countries.rb
db/migrate/032_add_user_locale.rb
db/migrate/033_change_diary_entries_language.rb
db/migrate/034_create_languages.rb
db/migrate/035_change_user_locale.rb
db/migrate/036_add_visible_to_message.rb
db/migrate/037_add_sender_visible_to_message.rb
db/migrate/038_add_message_sender_index.rb
db/migrate/039_add_more_controls_to_gpx_files.rb
db/migrate/040_create_oauth_tables.rb
db/migrate/041_add_fine_o_auth_permissions.rb
db/migrate/042_add_foreign_keys_to_oauth_tables.rb
db/migrate/043_add_referer_to_user_token.rb
db/migrate/044_create_user_roles.rb
db/migrate/045_create_user_blocks.rb
db/migrate/046_alter_user_roles_and_blocks.rb
db/migrate/047_add_visible_to_diaries.rb
db/migrate/048_add_diary_creation_indexes.rb
db/migrate/049_improve_changeset_user_index.rb
db/migrate/050_add_user_index_to_diary_comments.rb
db/migrate/051_add_status_to_user.rb
db/migrate/052_add_contributor_terms_to_user.rb
db/migrate/053_add_map_bug_tables.rb
db/migrate/054_refactor_map_bug_tables.rb
db/migrate/055_change_map_bug_comment_type.rb
db/migrate/056_add_date_closed.rb
db/migrate/057_add_map_bug_comment_event.rb
db/migrate/20100513171259_add_user_date_index_to_changeset.rb
db/migrate/20100516124737_add_open_id.rb
db/migrate/20100910084426_add_callback_to_oauth_tokens.rb
db/migrate/20101114011429_add_editor_preference_to_user.rb
db/migrate/20110322001319_add_terms_seen_to_user.rb
db/migrate/20110508145337_cleanup_bug_tables.rb
db/migrate/20110521142405_rename_bugs_to_notes.rb
db/migrate/20110925112722_rename_ids.rb
db/migrate/20111116184519_update_oauth.rb
db/migrate/20111212183945_add_lowercase_user_indexes.rb
db/migrate/20120123184321_switch_to_paperclip.rb
db/migrate/20120208122334_merge_acl_address_and_mask.rb
db/migrate/20120208194454_add_domain_to_acl.rb
db/migrate/20120214210114_add_text_format.rb
db/migrate/20120219161649_add_user_image_fingerprint.rb
db/migrate/20120318201948_create_redactions.rb
db/migrate/20120328090602_drop_session_table.rb
db/migrate/20120404205604_add_user_and_description_to_redaction.rb
db/migrate/20120808231205_add_counter_caches.rb
db/migrate/20121005195010_add_diary_entry_counter_caches.rb
db/migrate/20121012044047_add_image_use_gravatar_to_users.rb
db/migrate/20121119165817_drop_nearby_place_from_notes.rb
db/migrate/20121202155309_remove_author_name_from_note_comment.rb
db/migrate/20121203124841_change_note_address_to_inet.rb
db/migrate/20130328184137_add_write_notes_permission.rb
db/migrate/20131212124700_add_created_at_index_to_note_comments.rb
db/migrate/20140115192822_add_text_index_to_note_comments.rb
db/migrate/20140117185510_drop_countries.rb
db/migrate/20140210003018_add_user_image_content_type.rb
db/migrate/20140507110937_create_changeset_comments.rb
db/migrate/20140519141742_add_join_table_between_users_and_changesets.rb
db/migrate/20150110152606_change_default_formats.rb
db/migrate/20150111192335_subscribe_old_changesets.rb
db/migrate/20150222101847_rename_openid_url.rb
db/migrate/20150818224516_set_default_gravatar_to_false_for_privacy.rb
db/migrate/20161002153425_add_join_table_between_users_and_diary_entries.rb
db/migrate/20161011010929_subscribe_authors_to_diary_entries.rb
db/migrate/20170222134109_add_user_indexes.rb
db/migrate/20180204153242_tile_users.rb
db/migrate/20181020114000_add_user_tou_agreed.rb [new file with mode: 0644]
db/migrate/20181031113522_create_delayed_jobs.rb [new file with mode: 0644]
db/migrate/20190518115041_add_acl_indexes.rb [new file with mode: 0644]
db/migrate/20190623093642_add_mx_acls.rb [new file with mode: 0644]
db/migrate/20190702193519_create_active_storage_tables.rb [new file with mode: 0644]
db/migrate/20190716173946_remove_user_images.rb [new file with mode: 0644]
db/structure.sql
lib/auth.rb
lib/bounding_box.rb
lib/classic_pagination/pagination.rb
lib/daemons/gpx_import.rb [deleted file]
lib/daemons/gpx_import_ctl [deleted file]
lib/diff_reader.rb
lib/gpx.rb
lib/osm.rb
lib/password_hash.rb
lib/potlatch.rb
lib/potlatch2.rb
lib/rich_text.rb
lib/tasks/auto_annotate_models.rake
lib/tasks/eslint.rake [new file with mode: 0644]
lib/tasks/subscribe_diary_authors.rb [new file with mode: 0644]
lib/tasks/subscribe_old_changesets.rb [new file with mode: 0644]
lib/utf8.rb
package.json [new file with mode: 0644]
public/403.html [deleted file]
public/404.html [deleted file]
public/500.html [deleted file]
public/robots.txt
script/deliver-message
script/gravatar
script/misc/update-wiki-pages
script/vagrant/setup/provision.sh
test/abilities/abilities_test.rb [new file with mode: 0644]
test/abilities/api_abilities_test.rb [new file with mode: 0644]
test/abilities/api_capability_test.rb [new file with mode: 0644]
test/application_system_test_case.rb
test/controllers/amf_controller_test.rb [deleted file]
test/controllers/api/amf_controller_test.rb [new file with mode: 0644]
test/controllers/api/capabilities_controller_test.rb [new file with mode: 0644]
test/controllers/api/changes_controller_test.rb [new file with mode: 0644]
test/controllers/api/changeset_comments_controller_test.rb [new file with mode: 0644]
test/controllers/api/changesets_controller_test.rb [new file with mode: 0644]
test/controllers/api/map_controller_test.rb [new file with mode: 0644]
test/controllers/api/nodes_controller_test.rb [new file with mode: 0644]
test/controllers/api/notes_controller_test.rb [new file with mode: 0644]
test/controllers/api/old_nodes_controller_test.rb [new file with mode: 0644]
test/controllers/api/old_relations_controller_test.rb [new file with mode: 0644]
test/controllers/api/old_ways_controller_test.rb [new file with mode: 0644]
test/controllers/api/permissions_controller_test.rb [new file with mode: 0644]
test/controllers/api/relations_controller_test.rb [new file with mode: 0644]
test/controllers/api/search_controller_test.rb [new file with mode: 0644]
test/controllers/api/tracepoints_controller_test.rb [new file with mode: 0644]
test/controllers/api/traces_controller_test.rb [new file with mode: 0644]
test/controllers/api/user_preferences_controller_test.rb [new file with mode: 0644]
test/controllers/api/users_controller_test.rb [new file with mode: 0644]
test/controllers/api/versions_controller_test.rb [new file with mode: 0644]
test/controllers/api/ways_controller_test.rb [new file with mode: 0644]
test/controllers/api_controller_test.rb [deleted file]
test/controllers/browse_controller_test.rb
test/controllers/changeset_comments_controller_test.rb [new file with mode: 0644]
test/controllers/changeset_controller_test.rb [deleted file]
test/controllers/changesets_controller_test.rb [new file with mode: 0644]
test/controllers/diary_entries_controller_test.rb [moved from test/controllers/diary_entry_controller_test.rb with 72% similarity]
test/controllers/errors_controller_test.rb [new file with mode: 0644]
test/controllers/export_controller_test.rb
test/controllers/geocoder_controller_test.rb
test/controllers/issue_comments_controller_test.rb
test/controllers/issues_controller_test.rb
test/controllers/messages_controller_test.rb
test/controllers/node_controller_test.rb [deleted file]
test/controllers/notes_controller_test.rb
test/controllers/old_node_controller_test.rb [deleted file]
test/controllers/old_relation_controller_test.rb [deleted file]
test/controllers/old_way_controller_test.rb [deleted file]
test/controllers/redactions_controller_test.rb
test/controllers/relation_controller_test.rb [deleted file]
test/controllers/reports_controller_test.rb
test/controllers/search_controller_test.rb [deleted file]
test/controllers/site_controller_test.rb
test/controllers/swf_controller_test.rb [deleted file]
test/controllers/traces_controller_test.rb
test/controllers/user_blocks_controller_test.rb
test/controllers/user_preferences_controller_test.rb [deleted file]
test/controllers/user_roles_controller_test.rb
test/controllers/users_controller_test.rb [moved from test/controllers/user_controller_test.rb with 71% similarity]
test/controllers/way_controller_test.rb [deleted file]
test/factories/access_tokens.rb [new file with mode: 0644]
test/factories/changeset_comments.rb
test/factories/changesets.rb
test/factories/friendships.rb [moved from test/factories/friends.rb with 83% similarity]
test/factories/issues.rb
test/factories/languages.rb
test/factories/messages.rb
test/factories/node.rb
test/factories/note_comments.rb
test/factories/notes.rb
test/factories/old_node.rb
test/factories/old_relation.rb
test/factories/old_relation_member.rb
test/factories/old_way.rb
test/factories/old_way_node.rb
test/factories/relation.rb
test/factories/relation_member.rb
test/factories/reports.rb
test/factories/tracepoints.rb
test/factories/traces.rb
test/factories/user.rb
test/factories/user_blocks.rb
test/factories/way.rb
test/factories/way_node.rb
test/gpx/fixtures/b.gpx
test/gpx/fixtures/f.gpx
test/gpx/fixtures/g.gpx
test/gpx/fixtures/h.gpx
test/gpx/fixtures/i.gpx
test/helpers/application_helper_test.rb
test/helpers/browse_helper_test.rb
test/helpers/browse_tags_helper_test.rb [new file with mode: 0644]
test/helpers/changesets_helper_test.rb [moved from test/helpers/changeset_helper_test.rb with 96% similarity]
test/helpers/note_helper_test.rb
test/helpers/user_helper_test.rb
test/helpers/user_roles_helper_test.rb
test/integration/client_applications_test.rb
test/integration/cors_test.rb
test/integration/user_blocks_test.rb
test/integration/user_changeset_comments_test.rb
test/integration/user_creation_test.rb
test/integration/user_diaries_test.rb
test/integration/user_login_test.rb
test/integration/user_roles_test.rb [deleted file]
test/integration/user_terms_seen_test.rb
test/jobs/trace_destroyer_job_test.rb [new file with mode: 0644]
test/jobs/trace_importer_job_test.rb [new file with mode: 0644]
test/lib/bounding_box_test.rb
test/lib/country_test.rb
test/lib/rich_text_test.rb
test/models/acl_test.rb
test/models/changeset_test.rb
test/models/message_test.rb
test/models/node_test.rb
test/models/old_node_test.rb
test/models/redaction_test.rb
test/models/relation_test.rb
test/models/trace_test.rb
test/models/tracepoint_test.rb
test/models/user_test.rb
test/models/way_test.rb
test/system/diary_entry_test.rb
test/system/issues_test.rb
test/system/report_diary_comment_test.rb
test/system/report_diary_entry_test.rb
test/system/report_user_test.rb
test/test_helper.rb
test/validators/characters_validator_test.rb [new file with mode: 0644]
test/validators/whitespace_validator_test.rb [new file with mode: 0644]
vendor/assets/augment.js/augment.js [deleted file]
vendor/assets/iD/iD.css.erb
vendor/assets/iD/iD.js
vendor/assets/iD/iD/img/community-sprite.svg
vendor/assets/iD/iD/img/fa-sprite.svg
vendor/assets/iD/iD/img/iD-sprite.svg
vendor/assets/iD/iD/img/maki-sprite.svg
vendor/assets/iD/iD/img/mapillary-sprite.svg
vendor/assets/iD/iD/img/pattern/bushes.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/cemetery_buddhist.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/cemetery_christian.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/cemetery_jewish.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/cemetery_muslim.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/farmyard.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/forest.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/forest_broadleaved.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/forest_leafless.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/forest_needleleaved.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/grass.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/landfill.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/lines.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/pond.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/quarry.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/waves.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/wetland.png
vendor/assets/iD/iD/img/pattern/wetland_bog.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/wetland_marsh.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/wetland_reedbed.png [new file with mode: 0644]
vendor/assets/iD/iD/img/pattern/wetland_swamp.png [new file with mode: 0644]
vendor/assets/iD/iD/img/temaki-sprite.svg
vendor/assets/iD/iD/img/tnp-sprite.svg [new file with mode: 0644]
vendor/assets/iD/iD/locales/af.json
vendor/assets/iD/iD/locales/ar-AA.json
vendor/assets/iD/iD/locales/ar.json
vendor/assets/iD/iD/locales/ast.json
vendor/assets/iD/iD/locales/be.json
vendor/assets/iD/iD/locales/bg.json
vendor/assets/iD/iD/locales/bn.json
vendor/assets/iD/iD/locales/bs.json
vendor/assets/iD/iD/locales/ca.json
vendor/assets/iD/iD/locales/ckb.json
vendor/assets/iD/iD/locales/cs.json
vendor/assets/iD/iD/locales/cy.json
vendor/assets/iD/iD/locales/da.json
vendor/assets/iD/iD/locales/de.json
vendor/assets/iD/iD/locales/dv.json
vendor/assets/iD/iD/locales/el.json
vendor/assets/iD/iD/locales/en-AU.json [new file with mode: 0644]
vendor/assets/iD/iD/locales/en-GB.json
vendor/assets/iD/iD/locales/en.json
vendor/assets/iD/iD/locales/eo.json
vendor/assets/iD/iD/locales/es.json
vendor/assets/iD/iD/locales/et.json
vendor/assets/iD/iD/locales/eu.json
vendor/assets/iD/iD/locales/fa.json
vendor/assets/iD/iD/locales/fi.json
vendor/assets/iD/iD/locales/fr.json
vendor/assets/iD/iD/locales/gl.json
vendor/assets/iD/iD/locales/gu.json
vendor/assets/iD/iD/locales/he.json
vendor/assets/iD/iD/locales/hi.json
vendor/assets/iD/iD/locales/hr.json
vendor/assets/iD/iD/locales/hu.json
vendor/assets/iD/iD/locales/hy.json
vendor/assets/iD/iD/locales/id.json
vendor/assets/iD/iD/locales/is.json
vendor/assets/iD/iD/locales/it.json
vendor/assets/iD/iD/locales/ja.json
vendor/assets/iD/iD/locales/kn.json
vendor/assets/iD/iD/locales/ko.json
vendor/assets/iD/iD/locales/ku.json
vendor/assets/iD/iD/locales/lt.json
vendor/assets/iD/iD/locales/lv.json
vendor/assets/iD/iD/locales/mg.json
vendor/assets/iD/iD/locales/mi.json [new file with mode: 0644]
vendor/assets/iD/iD/locales/mk.json
vendor/assets/iD/iD/locales/ml.json
vendor/assets/iD/iD/locales/ms.json
vendor/assets/iD/iD/locales/ne.json
vendor/assets/iD/iD/locales/nl.json
vendor/assets/iD/iD/locales/nn.json
vendor/assets/iD/iD/locales/no.json
vendor/assets/iD/iD/locales/pap.json [new file with mode: 0644]
vendor/assets/iD/iD/locales/pl.json
vendor/assets/iD/iD/locales/pt-BR.json
vendor/assets/iD/iD/locales/pt.json
vendor/assets/iD/iD/locales/ro.json
vendor/assets/iD/iD/locales/ru.json
vendor/assets/iD/iD/locales/si.json
vendor/assets/iD/iD/locales/sk.json
vendor/assets/iD/iD/locales/sl.json
vendor/assets/iD/iD/locales/so.json
vendor/assets/iD/iD/locales/sq.json
vendor/assets/iD/iD/locales/sr.json
vendor/assets/iD/iD/locales/sv.json
vendor/assets/iD/iD/locales/ta.json
vendor/assets/iD/iD/locales/te.json
vendor/assets/iD/iD/locales/th.json
vendor/assets/iD/iD/locales/tl.json
vendor/assets/iD/iD/locales/tr.json
vendor/assets/iD/iD/locales/uk.json
vendor/assets/iD/iD/locales/vi.json
vendor/assets/iD/iD/locales/yue.json
vendor/assets/iD/iD/locales/zh-CN.json
vendor/assets/iD/iD/locales/zh-HK.json
vendor/assets/iD/iD/locales/zh-TW.json
vendor/assets/iD/iD/locales/zh.json
vendor/assets/iD/iD/mapillary-js/mapillary.js
vendor/assets/iD/iD/mapillary-js/mapillary.js.map
vendor/assets/iD/iD/mapillary-js/mapillary.min.css
vendor/assets/iD/iD/mapillary-js/mapillary.min.js
vendor/assets/javascripts/bowser.js
vendor/assets/leaflet/leaflet.css
vendor/assets/leaflet/leaflet.js
vendor/assets/leaflet/leaflet.locate.js
vendor/assets/leaflet/leaflet.osm.js
vendor/assets/polyfill/es5.js [new file with mode: 0644]
vendor/assets/polyfill/es6.js [new file with mode: 0644]
vendor/assets/potlatch2/potlatch2.swf
vendor/assets/potlatch2/potlatch2/assets.zip
vendor/assets/potlatch2/potlatch2/locales/ar.swf
vendor/assets/potlatch2/potlatch2/locales/be-tarask.swf
vendor/assets/potlatch2/potlatch2/locales/bn.swf
vendor/assets/potlatch2/potlatch2/locales/ce.swf
vendor/assets/potlatch2/potlatch2/locales/diq.swf
vendor/assets/potlatch2/potlatch2/locales/eo.swf
vendor/assets/potlatch2/potlatch2/locales/eu.swf
vendor/assets/potlatch2/potlatch2/locales/fa.swf
vendor/assets/potlatch2/potlatch2/locales/gl.swf
vendor/assets/potlatch2/potlatch2/locales/it_IT.swf
vendor/assets/potlatch2/potlatch2/locales/ja_JP.swf
vendor/assets/potlatch2/potlatch2/locales/ko.swf
vendor/assets/potlatch2/potlatch2/locales/lb.swf
vendor/assets/potlatch2/potlatch2/locales/my.swf [new file with mode: 0644]
vendor/assets/potlatch2/potlatch2/locales/nb_NO.swf
vendor/assets/potlatch2/potlatch2/locales/ne.swf
vendor/assets/potlatch2/potlatch2/locales/pt_PT.swf
vendor/assets/potlatch2/potlatch2/locales/ro.swf
vendor/assets/potlatch2/potlatch2/locales/ru.swf
vendor/assets/potlatch2/potlatch2/locales/th.swf
vendor/assets/potlatch2/potlatch2/locales/tr.swf
vendor/assets/potlatch2/potlatch2/locales/zh_TW.swf
vendor/generators/daemon/daemon_generator.rb [deleted file]
vendor/generators/daemon/templates/daemons [deleted file]
vendor/generators/daemon/templates/daemons.yml [deleted file]
vendor/generators/daemon/templates/script.rb [deleted file]
vendor/generators/daemon/templates/script_ctl [deleted file]
yarn.lock [new file with mode: 0644]

diff --git a/.erb-lint.yml b/.erb-lint.yml
new file mode 100644 (file)
index 0000000..812a6f5
--- /dev/null
@@ -0,0 +1,32 @@
+---
+linters:
+  AllowedScriptType:
+    enabled: true
+    disallow_inline_scripts: true
+  Rubocop:
+    enabled: true
+    rubocop_config:
+      inherit_from:
+        - .rubocop.yml
+      Layout/InitialIndentation:
+        Enabled: false
+      Layout/TrailingBlankLines:
+        Enabled: false
+      Layout/TrailingWhitespace:
+        Enabled: false
+      Naming/FileName:
+        Enabled: false
+      Style/FrozenStringLiteralComment:
+        Enabled: false
+      Metrics/LineLength:
+        Enabled: false
+      Lint/UselessAssignment:
+        Enabled: false
+      Rails/OutputSafety:
+        Enabled: false
+  SelfClosingTag:
+    enabled: false
+  SpaceInHtmlTag:
+    enabled: true
+exclude:
+  - '**/vendor/**'
index 920ca1120ba51aa6171900e39560d36c48d1343f..1328658c6ab5b70d2809f6c665e51ff05b447514 100644 (file)
@@ -1,14 +1,20 @@
-log
+*~
+.DS_Store
+.idea
+.ruby-gemset
+.ruby-version
+.vagrant
+app/assets/javascripts/i18n
+config/environments/*.local.yml
 config/piwik.yml
+config/settings.local.yml
+config/settings/*.local.yml
+coverage
+doc
+log
+node_modules
 public/assets
 public/attachments
 public/export
+storage
 tmp
-.DS_Store
-*~
-doc
-.vagrant
-.ruby-gemset
-.ruby-version
-.idea
-coverage
index 29f21fde6f1178be3dd239791da197b071f89b44..761478b563baaec90676ac4ae7a9d35edd41e271 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -7,4 +7,4 @@ Kai Krueger <kakrueger@gmail.com> <kai@aiputerlx.(none)>
 Michael Glanznig <nebulon42@yandex.com>
 Petr Kadlec <mormegil@centrum.cz>
 Richard Fairhurst <richard@systemeD.net> <richard@systemed.net>
-Simon Poole <simon@poole.ch> <simon@rails-dev.poole.ch>
+Simon Poole <simon@poole.ch> <simon@rails-dev.poole.ch> <simonpoole@users.noreply.github.com>
index 24d57fb37cc0b354c71674e00c8a6f9671bbdf6b..cbd62a052512bc82c9b6858a965391f206fb5327 100644 (file)
@@ -1,5 +1,14 @@
 inherit_from: .rubocop_todo.yml
 
+require:
+  - rubocop-performance
+  - rubocop-rails
+
+AllCops:
+  TargetRubyVersion: 2.5
+  Exclude:
+    - 'vendor/**/*'
+
 Rails:
   Enabled: true
 
@@ -12,6 +21,14 @@ Lint/PercentStringArray:
     - 'app/controllers/application_controller.rb'
     - 'app/controllers/site_controller.rb'
 
+Metrics/BlockLength:
+  Exclude:
+    - 'config/routes.rb'
+
+Metrics/ClassLength:
+  Exclude:
+    - 'test/**/*'
+
 Naming/FileName:
   Exclude:
     - 'script/deliver-message'
@@ -27,6 +44,9 @@ Rails/ApplicationRecord:
 Rails/CreateTableWithTimestamps:
   Enabled: false
 
+Rails/FindEach:
+  Enabled: false
+
 Rails/HasManyOrHasOneDependent:
   Enabled: false
 
@@ -39,7 +59,7 @@ Rails/InverseOf:
 Rails/SkipsModelValidations:
   Exclude:
     - 'db/migrate/*.rb'
-    - 'app/controllers/user_controller.rb'
+    - 'app/controllers/users_controller.rb'
 
 Style/BracesAroundHashParameters:
   EnforcedStyle: context_dependent
@@ -50,10 +70,6 @@ Style/FormatStringToken:
 Style/IfInsideElse:
   Enabled: false
 
-Style/GlobalVars:
-  Exclude:
-    - 'lib/quad_tile/extconf.rb'
-
 Style/GuardClause:
   Enabled: false
 
index a64be72735cff92ec5b445ba875bdd05f5660461..397215c03bd8ef4b006532cd82a8922ac2669eb3 100644 (file)
@@ -1,84 +1,70 @@
 # This configuration was generated by
 # `rubocop --auto-gen-config`
-# on 2018-06-19 09:02:55 +0100 using RuboCop version 0.57.2.
+# on 2019-08-14 19:26:21 +0100 using RuboCop version 0.74.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: 34
-Lint/AmbiguousOperator:
-  Exclude:
-    - 'test/controllers/amf_controller_test.rb'
-    - 'test/controllers/changeset_controller_test.rb'
-    - 'test/lib/bounding_box_test.rb'
-    - 'test/lib/country_test.rb'
-
-# Offense count: 96
-Lint/AmbiguousRegexpLiteral:
-  Enabled: false
-
-# Offense count: 32
+# Offense count: 33
 # Configuration parameters: AllowSafeAssignment.
 Lint/AssignmentInCondition:
   Exclude:
+    - 'app/controllers/api/traces_controller.rb'
+    - 'app/controllers/api/user_preferences_controller.rb'
     - 'app/controllers/application_controller.rb'
     - 'app/controllers/geocoder_controller.rb'
     - 'app/controllers/notes_controller.rb'
     - 'app/controllers/traces_controller.rb'
-    - 'app/controllers/user_controller.rb'
-    - 'app/controllers/user_preferences_controller.rb'
+    - 'app/controllers/users_controller.rb'
     - 'app/helpers/application_helper.rb'
-    - 'app/helpers/browse_helper.rb'
+    - 'app/helpers/browse_tags_helper.rb'
+    - 'app/mailers/notifier.rb'
     - 'app/models/client_application.rb'
-    - 'app/models/notifier.rb'
     - 'lib/nominatim.rb'
     - 'lib/osm.rb'
     - 'script/deliver-message'
 
 # Offense count: 4
+# Configuration parameters: AllowComments.
 Lint/HandleExceptions:
   Exclude:
-    - 'app/controllers/amf_controller.rb'
-    - 'app/controllers/user_controller.rb'
+    - 'app/controllers/api/amf_controller.rb'
+    - 'app/controllers/users_controller.rb'
 
-# Offense count: 2
-Lint/ShadowingOuterLocalVariable:
-  Exclude:
-    - 'app/views/changeset/list.atom.builder'
-
-# Offense count: 690
+# Offense count: 699
 Metrics/AbcSize:
-  Max: 280
+  Max: 279
 
-# Offense count: 41
+# Offense count: 39
 # Configuration parameters: CountComments, ExcludedMethods.
+# ExcludedMethods: refine
 Metrics/BlockLength:
-  Max: 258
+  Max: 71
 
-# Offense count: 11
+# Offense count: 15
 # Configuration parameters: CountBlocks.
 Metrics/BlockNesting:
   Max: 5
 
-# Offense count: 63
+# Offense count: 25
 # Configuration parameters: CountComments.
 Metrics/ClassLength:
-  Max: 1795
+  Max: 645
 
-# Offense count: 72
+# Offense count: 73
 Metrics/CyclomaticComplexity:
-  Max: 20
+  Max: 22
 
-# Offense count: 688
-# Configuration parameters: CountComments.
+# Offense count: 719
+# Configuration parameters: CountComments, ExcludedMethods.
 Metrics/MethodLength:
   Max: 179
 
-# Offense count: 2
+# Offense count: 1
 # Configuration parameters: CountComments.
 Metrics/ModuleLength:
-  Max: 135
+  Max: 107
 
 # Offense count: 4
 # Configuration parameters: CountKeywordArgs.
@@ -87,7 +73,7 @@ Metrics/ParameterLists:
 
 # Offense count: 71
 Metrics/PerceivedComplexity:
-  Max: 23
+  Max: 25
 
 # Offense count: 6
 Naming/AccessorMethodName:
@@ -114,6 +100,14 @@ Naming/PredicateName:
     - 'app/models/user.rb'
     - 'lib/classic_pagination/pagination.rb'
 
+# Offense count: 5
+# Cop supports --auto-correct.
+Performance/RegexpMatch:
+  Exclude:
+    - 'app/helpers/browse_tags_helper.rb'
+    - 'app/validators/characters_validator.rb'
+    - 'app/validators/whitespace_validator.rb'
+
 # Offense count: 6
 # Configuration parameters: Database, Include.
 # SupportedDatabases: mysql, postgresql
@@ -125,14 +119,6 @@ Rails/BulkChangeTable:
     - 'db/migrate/20120208194454_add_domain_to_acl.rb'
     - 'db/migrate/20120404205604_add_user_and_description_to_redaction.rb'
 
-# Offense count: 2
-# Configuration parameters: Include.
-# Include: app/**/*.rb, config/**/*.rb, lib/**/*.rb
-Rails/Exit:
-  Exclude:
-    - 'lib/**/*.rake'
-    - 'lib/daemons/gpx_import.rb'
-
 # Offense count: 2
 # Configuration parameters: Include.
 # Include: app/models/**/*.rb
@@ -141,6 +127,15 @@ Rails/HasAndBelongsToMany:
     - 'app/models/changeset.rb'
     - 'app/models/user.rb'
 
+# Offense count: 11
+# Configuration parameters: Include.
+# Include: app/helpers/**/*.rb
+Rails/HelperInstanceVariable:
+  Exclude:
+    - 'app/helpers/application_helper.rb'
+    - 'app/helpers/title_helper.rb'
+    - 'app/helpers/trace_helper.rb'
+
 # Offense count: 5
 # Configuration parameters: Include.
 # Include: db/migrate/*.rb
@@ -152,21 +147,21 @@ Rails/NotNullColumn:
     - 'db/migrate/025_add_end_time_to_changesets.rb'
     - 'db/migrate/20120404205604_add_user_and_description_to_redaction.rb'
 
-# Offense count: 20
+# Offense count: 18
 Rails/OutputSafety:
   Exclude:
-    - 'app/controllers/user_controller.rb'
+    - 'app/controllers/users_controller.rb'
     - 'app/helpers/application_helper.rb'
-    - 'app/helpers/changeset_helper.rb'
+    - 'app/helpers/changesets_helper.rb'
     - 'app/helpers/geocoder_helper.rb'
     - 'app/helpers/note_helper.rb'
     - 'app/helpers/open_graph_helper.rb'
     - 'app/helpers/user_blocks_helper.rb'
-    - 'app/helpers/user_roles_helper.rb'
     - 'lib/rich_text.rb'
     - 'test/helpers/application_helper_test.rb'
 
-# Offense count: 86
+# Offense count: 94
+# Cop supports --auto-correct.
 # Configuration parameters: EnforcedStyle.
 # SupportedStyles: strict, flexible
 Rails/TimeZone:
@@ -178,15 +173,22 @@ Style/AsciiComments:
   Exclude:
     - 'test/models/message_test.rb'
 
-# Offense count: 229
+# Offense count: 263
 Style/Documentation:
   Enabled: false
 
+# Offense count: 539
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: always, never
+Style/FrozenStringLiteralComment:
+  Enabled: false
+
 # Offense count: 2
 # Cop supports --auto-correct.
 Style/IfUnlessModifier:
   Exclude:
-    - 'app/controllers/way_controller.rb'
+    - 'app/controllers/api/ways_controller.rb'
 
 # Offense count: 70
 # Cop supports --auto-correct.
@@ -194,8 +196,9 @@ Style/IfUnlessModifier:
 Style/NumericLiterals:
   MinDigits: 11
 
-# Offense count: 3064
-# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
+# Offense count: 3322
+# Cop supports --auto-correct.
+# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
 # URISchemes: http, https
 Metrics/LineLength:
-  Max: 1073
+  Max: 307
index 48ddb4a1d09d4e3f1ca0b508c123ee39b0a96b31..e4c81e4c1d401373648fd78d98258dd08ec64e6e 100644 (file)
@@ -1,20 +1,22 @@
-sudo: false
+dist: xenial
 language: ruby
 rvm:
-  - 2.3.1
-cache: bundler
+  - 2.5.3
+cache:
+  - bundler
 addons:
   postgresql: 9.5
   apt:
     packages:
       - postgresql-server-dev-9.5
+      - libarchive-dev
 services:
   - memcached
 env:
   global:
     - OSM_MEMCACHE_SERVERS="127.0.0.1"
 before_script:
-  - cp config/example.application.yml config/application.yml
+  - sed -e "/idle_in_transaction_session_timeout/d" -e 's/ IMMUTABLE / /' -e "s/AS '.*libpgosm.*',/AS 'libpgosm',/" -e "/^--/d" db/structure.sql > db/structure.expected
   - psql -U postgres -c "CREATE DATABASE openstreetmap"
   - psql -U postgres -c "CREATE EXTENSION btree_gist" openstreetmap
   - make -C db/functions libpgosm.so
@@ -23,8 +25,16 @@ before_script:
   - 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
+  - cp config/example.storage.yml config/storage.yml
+  - touch config/settings.local.yml
   - bundle exec rake db:migrate
+  - bundle exec rake i18n:js:export
+  - bundle exec rake yarn:install
 script:
   - bundle exec rubocop -f fuubar
-  - bundle exec rake jshint
+  - bundle exec rake eslint
+  - bundle exec erblint .
+  - bundle exec rake db:structure:dump
+  - sed -e "/idle_in_transaction_session_timeout/d" -e 's/ IMMUTABLE / /' -e "s/AS '.*libpgosm.*',/AS 'libpgosm',/" -e "/^--/d" db/structure.sql > db/structure.actual
+  - diff -uw db/structure.expected db/structure.actual
   - bundle exec rake test:db
index 0b8af0483fbe7a7d5cecbb669142cdd1981ecbf7..91a64119ed33cb5d7ccf057ba266a6684f323bce 100644 (file)
@@ -2,6 +2,10 @@
 
 After [installing](INSTALL.md) this software, you may need to carry out some of these configuration steps, depending on your tasks.
 
+## Application configuration
+
+Many settings are available in `config/settings.yml`. You can customize your installation of The Rails Port by overriding these values using `config/settings.local.yml`
+
 ## Populating the database
 
 Your installation comes with no geographic data loaded. You can either create new data using one of the editors (Potlatch 2, iD, JOSM etc) or by loading an OSM extract.
@@ -71,11 +75,11 @@ Do the following:
 * Everything else can be left with the default blank values.
 * Click the "Register" button
 * On the next page, copy the "consumer key"
-* Edit config/application.yml in your rails tree
-* Uncomment and change the "potlatch2_key" configuration value
+* Edit config/settings.local.yml in your rails tree
+* Add the "potlatch2_key" configuration key and the consumer key as the value
 * Restart your rails server
 
-An example excerpt from application.yml:
+An example excerpt from settings.local.yml:
 
 ```
 # Default editor
@@ -86,8 +90,6 @@ potlatch2_key: "8lFmZPsagHV4l3rkAHq0hWY5vV3Ctl3oEFY1aXth"
 
 Follow the same process for registering and configuring iD (`id_key`) and the website/Notes (`oauth_key`), or to save time, simply reuse the same consumer key for each.
 
-**NOTE:** If you forget to set up OAuth, then you will get an error message similar to `uninitialized constant ActionView::CompiledTemplates::ID_KEY`.
-
 ## Troubleshooting
 
 Rails has its own log.  To inspect the log, do this:
@@ -127,5 +129,5 @@ If you want to deploy The Rails Port for production use, you'll need to make a f
 * Your production database will also need the extensions and functions installed - see [INSTALL.md](INSTALL.md)
 * The included version of the map call is quite slow and eats a lot of memory. You should consider using [CGIMap](https://github.com/zerebubuth/openstreetmap-cgimap) instead.
 * The included version of the GPX importer is slow and/or completely inoperable. You should consider using [the high-speed GPX importer](https://git.openstreetmap.org/gpx-import.git/).
-* Make sure you precompile the production assets: `RAILS_ENV=production rake assets:precompile`
+* Make sure you generate the i18n files and precompile the production assets: `RAILS_ENV=production rake i18n:js:export assets:precompile`
 * Make sure the web server user as well as the rails user can read, write and create directories in `tmp/`.
index acb7807461ea56621f0bf950e324ac110965e5d3..5a2ed5ab7184bcac849d78a2a9d8135bb7e1ce63 100644 (file)
@@ -3,15 +3,16 @@
 
 ## Coding style
 
-When writing code it is generally a good idea to try and match your
-formatting to that of any existing code in the same file, or to other
-similar files if you are writing new code. Consistency of layout is
-far more important than the layout itself as it makes reading code
-much easier.
+We use [Rubocop](https://github.com/rubocop-hq/rubocop) (for ruby files)
+and [ERB Lint](https://github.com/Shopify/erb-lint) (for erb templates)
+to help maintain consistency in our code. You can run these utilities during
+development to check that your code matches our guidelines:
 
-One golden rule of formatting -- please don't use tabs in your code
-as they will cause the file to be formatted differently for different
-people depending on how they have their editor configured.
+```
+bundle exec rubocop
+bundle exec rake eslint
+bundle exec erblint .
+```
 
 ## Testing
 
@@ -35,12 +36,7 @@ You can run the existing test suite with:
 bundle exec rake test
 ```
 
-You can generate test coverage stats with:
-
-```
-sudo gem install rcov
-rcov -x gems test/*/*.rb
-```
+You can view test coverage statistics by browsing the `coverage` directory.
 
 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).
@@ -59,6 +55,13 @@ might be difficult to understand what the code does, why it does it
 and why it should be the way it is.
 * Check existing comments to ensure that they are not misleading.
 
+## i18n
+
+If you make a change that involve the locale files (in `config/locales`) then please
+only submit changes to the `en.yml` file. The other files are updated via
+[Translatewiki](https://translatewiki.net/wiki/Translating:OpenStreetMap) and should
+not be included in your pull request.
+
 ## Code Documentation
 
 To generate the HTML documentation of the API/rails code, run the command
diff --git a/Gemfile b/Gemfile
index 9d759548cf048854e0638d0280e37e9fa598ffd0..c2bb066b7c9c291bd8854f27dc73844a5cd9cf4a 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
 source "https://rubygems.org"
 
 # Require rails
-gem "rails", "5.2.0"
+gem "rails", "5.2.3"
 
 # Require things which have moved to gems in ruby 1.9
 gem "bigdecimal", "~> 1.1.0", :platforms => :ruby_19
@@ -13,10 +13,10 @@ gem "psych", :platforms => :ruby_20
 gem "json"
 
 # Use postgres as the database
-gem "pg", "~> 0.18"
+gem "pg"
 
 # Use SCSS for stylesheets
-gem "sass-rails", "~> 5.0"
+gem "sassc-rails"
 
 # Use Uglifier as compressor for JavaScript assets
 gem "uglifier", ">= 1.3.0"
@@ -38,24 +38,29 @@ gem "bootsnap", ">= 1.1.0", :require => false
 gem "r2", "~> 0.2.7"
 
 # Use autoprefixer to generate CSS prefixes
-gem "autoprefixer-rails"
+gem "autoprefixer-rails", "~> 8.6.3"
 
 # Use image_optim to optimise images
 gem "image_optim_rails"
 
 # Load rails plugins
 gem "actionpack-page_caching"
-gem "composite_primary_keys", "~> 11.0.0"
+gem "active_record_union"
+gem "activerecord-import"
+gem "cancancan"
+gem "composite_primary_keys", "~> 11.1.0"
+gem "config"
+gem "delayed_job_active_record"
 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", "~> 5.2"
 gem "rack-cors"
 gem "rails-i18n", "~> 4.0.0"
 gem "record_tag_helper"
-gem "rinku", ">= 1.2.2", :require => "rails_rinku"
+gem "rinku", ">= 2.0.6", :require => "rails_rinku"
+gem "strong_migrations"
 gem "validates_email_format_of", ">= 1.5.1"
 
 # Native OSM extensions
@@ -68,13 +73,13 @@ gem "rack-uri_sanitizer"
 gem "omniauth"
 gem "omniauth-facebook"
 gem "omniauth-github"
-gem "omniauth-google-oauth2", ">= 0.2.7"
-gem "omniauth-mediawiki", ">= 0.0.3"
+gem "omniauth-google-oauth2", ">= 0.6.0"
+gem "omniauth-mediawiki", ">= 0.0.4"
 gem "omniauth-openid"
 gem "omniauth-windowslive"
 
 # Markdown formatting support
-gem "redcarpet"
+gem "kramdown"
 
 # For status transitions of Issues
 gem "aasm"
@@ -111,6 +116,21 @@ gem "canonical-rails"
 # Used to generate logstash friendly log files
 gem "logstasher"
 
+# Used to generate images for traces
+gem "bzip2-ffi"
+gem "ffi-libarchive"
+gem "gd2-ffij", ">= 0.4.0"
+gem "mimemagic"
+
+# Used for browser detection
+gem "browser"
+
+# Used for S3 object storage
+gem "aws-sdk-s3"
+
+# Used to resize user images
+gem "mini_magick"
+
 # Gems useful for development
 group :development do
   gem "annotate"
@@ -122,9 +142,12 @@ end
 
 # Gems needed for running tests
 group :test do
+  gem "fakefs", :require => "fakefs/safe"
   gem "minitest", "~> 5.1", :platforms => [:ruby_19, :ruby_20]
   gem "rails-controller-testing"
   gem "rubocop"
+  gem "rubocop-performance"
+  gem "rubocop-rails"
   gem "webmock"
 end
 
@@ -132,8 +155,8 @@ end
 group :development, :test do
   gem "capybara", "~> 2.13"
   gem "coveralls", :require => false
+  gem "erb_lint", :require => false
   gem "factory_bot_rails"
-  gem "jshint"
   gem "poltergeist"
   gem "puma", "~> 3.7"
 end
index 2fd53888211747c2d0957a1ff115288b8b9aa96d..a4104c53625bb0822be5448ec7c09b8b1c5db4f6 100644 (file)
@@ -2,72 +2,104 @@ GEM
   remote: https://rubygems.org/
   specs:
     SystemTimer (1.2.3)
-    aasm (4.12.3)
+    aasm (5.0.5)
       concurrent-ruby (~> 1.0)
-    actioncable (5.2.0)
-      actionpack (= 5.2.0)
+    actioncable (5.2.3)
+      actionpack (= 5.2.3)
       nio4r (~> 2.0)
       websocket-driver (>= 0.6.1)
-    actionmailer (5.2.0)
-      actionpack (= 5.2.0)
-      actionview (= 5.2.0)
-      activejob (= 5.2.0)
+    actionmailer (5.2.3)
+      actionpack (= 5.2.3)
+      actionview (= 5.2.3)
+      activejob (= 5.2.3)
       mail (~> 2.5, >= 2.5.4)
       rails-dom-testing (~> 2.0)
-    actionpack (5.2.0)
-      actionview (= 5.2.0)
-      activesupport (= 5.2.0)
+    actionpack (5.2.3)
+      actionview (= 5.2.3)
+      activesupport (= 5.2.3)
       rack (~> 2.0)
       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-page_caching (1.1.1)
       actionpack (>= 4.0.0, < 6)
-    actionview (5.2.0)
-      activesupport (= 5.2.0)
+    actionview (5.2.3)
+      activesupport (= 5.2.3)
       builder (~> 3.1)
       erubi (~> 1.4)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.0, >= 1.0.3)
-    activejob (5.2.0)
-      activesupport (= 5.2.0)
+    active_record_union (1.3.0)
+      activerecord (>= 4.0)
+    activejob (5.2.3)
+      activesupport (= 5.2.3)
       globalid (>= 0.3.6)
-    activemodel (5.2.0)
-      activesupport (= 5.2.0)
-    activerecord (5.2.0)
-      activemodel (= 5.2.0)
-      activesupport (= 5.2.0)
+    activemodel (5.2.3)
+      activesupport (= 5.2.3)
+    activerecord (5.2.3)
+      activemodel (= 5.2.3)
+      activesupport (= 5.2.3)
       arel (>= 9.0)
-    activestorage (5.2.0)
-      actionpack (= 5.2.0)
-      activerecord (= 5.2.0)
+    activerecord-import (1.0.2)
+      activerecord (>= 3.2)
+    activestorage (5.2.3)
+      actionpack (= 5.2.3)
+      activerecord (= 5.2.3)
       marcel (~> 0.3.1)
-    activesupport (5.2.0)
+    activesupport (5.2.3)
       concurrent-ruby (~> 1.0, >= 1.0.2)
       i18n (>= 0.7, < 2)
       minitest (~> 5.1)
       tzinfo (~> 1.1)
-    addressable (2.5.2)
+    addressable (2.6.0)
       public_suffix (>= 2.0.2, < 4.0)
-    annotate (2.7.4)
-      activerecord (>= 3.2, < 6.0)
+    annotate (2.7.5)
+      activerecord (>= 3.2, < 7.0)
       rake (>= 10.4, < 13.0)
     arel (9.0.0)
     ast (2.4.0)
-    autoprefixer-rails (8.6.3)
+    autoprefixer-rails (8.6.5)
       execjs
-    better_errors (2.4.0)
+    aws-eventstream (1.0.3)
+    aws-partitions (1.206.0)
+    aws-sdk-core (3.64.0)
+      aws-eventstream (~> 1.0, >= 1.0.2)
+      aws-partitions (~> 1.0)
+      aws-sigv4 (~> 1.1)
+      jmespath (~> 1.0)
+    aws-sdk-kms (1.24.0)
+      aws-sdk-core (~> 3, >= 3.61.1)
+      aws-sigv4 (~> 1.1)
+    aws-sdk-s3 (1.46.0)
+      aws-sdk-core (~> 3, >= 3.61.1)
+      aws-sdk-kms (~> 1)
+      aws-sigv4 (~> 1.1)
+    aws-sigv4 (1.1.0)
+      aws-eventstream (~> 1.0, >= 1.0.2)
+    better_errors (2.5.1)
       coderay (>= 1.0.0)
       erubi (>= 1.0.0)
       rack (>= 0.9.0)
+    better_html (1.0.14)
+      actionview (>= 4.0)
+      activesupport (>= 4.0)
+      ast (~> 2.0)
+      erubi (~> 1.4)
+      html_tokenizer (~> 0.0.6)
+      parser (>= 2.4)
+      smart_properties
     bigdecimal (1.1.0)
     binding_of_caller (0.8.0)
       debug_inspector (>= 0.0.1)
-    bootsnap (1.3.0)
+    bootsnap (1.4.4)
       msgpack (~> 1.0)
+    browser (2.6.1)
     builder (3.2.3)
-    canonical-rails (0.2.3)
-      rails (>= 4.1, < 5.3)
+    bzip2-ffi (1.0.0)
+      ffi (~> 1.0)
+    cancancan (3.0.1)
+    canonical-rails (0.2.6)
+      rails (>= 4.1, < 6.1)
     capybara (2.18.0)
       addressable
       mini_mime (>= 0.1.3)
@@ -75,7 +107,6 @@ GEM
       rack (>= 1.0.0)
       rack-test (>= 0.5.4)
       xpath (>= 2.0, < 4.0)
-    climate_control (0.2.0)
     cliver (0.3.2)
     coderay (1.1.2)
     coffee-rails (4.2.2)
@@ -85,142 +116,190 @@ GEM
       coffee-script-source
       execjs
     coffee-script-source (1.12.2)
-    composite_primary_keys (11.0.3)
-      activerecord (~> 5.2.0)
-    concurrent-ruby (1.0.5)
-    coveralls (0.8.21)
+    composite_primary_keys (11.1.0)
+      activerecord (~> 5.2.1)
+    concurrent-ruby (1.1.5)
+    config (2.0.0)
+      activesupport (>= 4.2)
+      deep_merge (~> 1.2, >= 1.2.1)
+      dry-schema (~> 1.0)
+    coveralls (0.8.23)
       json (>= 1.8, < 3)
-      simplecov (~> 0.14.1)
+      simplecov (~> 0.16.1)
       term-ansicolor (~> 1.3)
-      thor (~> 0.19.4)
+      thor (>= 0.19.4, < 2.0)
       tins (~> 1.6)
     crack (0.4.3)
       safe_yaml (~> 1.0.0)
     crass (1.0.4)
-    dalli (2.7.8)
+    dalli (2.7.10)
     debug_inspector (0.0.3)
-    docile (1.1.5)
+    deep_merge (1.2.1)
+    delayed_job (4.1.8)
+      activesupport (>= 3.0, < 6.1)
+    delayed_job_active_record (4.1.4)
+      activerecord (>= 3.0, < 6.1)
+      delayed_job (>= 3.0, < 5)
+    docile (1.3.2)
+    dry-configurable (0.8.3)
+      concurrent-ruby (~> 1.0)
+      dry-core (~> 0.4, >= 0.4.7)
+    dry-container (0.7.2)
+      concurrent-ruby (~> 1.0)
+      dry-configurable (~> 0.1, >= 0.1.3)
+    dry-core (0.4.9)
+      concurrent-ruby (~> 1.0)
+    dry-equalizer (0.2.2)
+    dry-inflector (0.1.2)
+    dry-initializer (3.0.1)
+    dry-logic (1.0.3)
+      concurrent-ruby (~> 1.0)
+      dry-core (~> 0.2)
+      dry-equalizer (~> 0.2)
+    dry-schema (1.3.3)
+      concurrent-ruby (~> 1.0)
+      dry-configurable (~> 0.8, >= 0.8.3)
+      dry-core (~> 0.4)
+      dry-equalizer (~> 0.2)
+      dry-initializer (~> 3.0)
+      dry-logic (~> 1.0)
+      dry-types (~> 1.0)
+    dry-types (1.1.1)
+      concurrent-ruby (~> 1.0)
+      dry-container (~> 0.3)
+      dry-core (~> 0.4, >= 0.4.4)
+      dry-equalizer (~> 0.2, >= 0.2.2)
+      dry-inflector (~> 0.1, >= 0.1.2)
+      dry-logic (~> 1.0, >= 1.0.2)
     dynamic_form (1.1.4)
-    erubi (1.7.1)
+    erb_lint (0.0.29)
+      activesupport
+      better_html (~> 1.0.7)
+      html_tokenizer
+      rainbow
+      rubocop (~> 0.51)
+      smart_properties
+    erubi (1.8.0)
     execjs (2.7.0)
-    exifr (1.3.4)
-    factory_bot (4.10.0)
-      activesupport (>= 3.0.0)
-    factory_bot_rails (4.10.0)
-      factory_bot (~> 4.10.0)
-      railties (>= 3.0.0)
-    faraday (0.12.2)
+    exifr (1.3.6)
+    factory_bot (5.0.2)
+      activesupport (>= 4.2.0)
+    factory_bot_rails (5.0.2)
+      factory_bot (~> 5.0.2)
+      railties (>= 4.2.0)
+    fakefs (0.20.1)
+    faraday (0.15.4)
       multipart-post (>= 1.2, < 3)
-    ffi (1.9.25)
-    fspath (3.1.0)
+    ffi (1.11.1)
+    ffi-libarchive (0.4.10)
+      ffi (~> 1.0)
+    fspath (3.1.2)
+    gd2-ffij (0.4.0)
+      ffi (>= 1.0.0)
     geoip (1.6.4)
-    globalid (0.4.1)
+    globalid (0.4.2)
       activesupport (>= 4.2.0)
-    hashdiff (0.3.7)
-    hashie (3.5.7)
+    hashdiff (1.0.0)
+    hashie (3.6.0)
+    html_tokenizer (0.0.7)
     htmlentities (4.3.4)
     http_accept_language (2.0.5)
     i18n (0.9.5)
       concurrent-ruby (~> 1.0)
-    i18n-js (3.0.9)
-      i18n (>= 0.6.6, < 2)
-    image_optim (0.26.1)
+    i18n-js (3.3.0)
+      i18n (>= 0.6.6)
+    image_optim (0.26.5)
       exifr (~> 1.2, >= 1.2.2)
       fspath (~> 3.0)
-      image_size (~> 1.5)
+      image_size (>= 1.5, < 3)
       in_threads (~> 1.3)
       progress (~> 3.0, >= 3.0.1)
-    image_optim_rails (0.4.1)
+    image_optim_rails (0.4.3)
       image_optim (~> 0.24)
       rails
       sprockets
-    image_size (1.5.0)
-    in_threads (1.5.0)
-    jaro_winkler (1.5.1)
-    jquery-rails (4.3.3)
+    image_size (2.0.2)
+    in_threads (1.5.3)
+    jaro_winkler (1.5.3)
+    jmespath (1.4.0)
+    jquery-rails (4.3.5)
       rails-dom-testing (>= 1, < 3)
       railties (>= 4.2.0)
       thor (>= 0.14, < 2.0)
-    jshint (1.5.0)
-      execjs (>= 1.4.0)
-      multi_json (~> 1.0)
-      therubyracer (~> 0.12.1)
-    json (2.1.0)
+    json (2.2.0)
     jsonify (0.3.1)
       multi_json (~> 1.0)
     jsonify-rails (0.3.2)
       actionpack
       jsonify (< 0.4.0)
-    jwt (1.5.6)
+    jwt (2.2.1)
     kgio (2.11.2)
-    libv8 (3.16.14.19)
+    kramdown (2.1.0)
     libxml-ruby (3.1.0)
     listen (3.1.5)
       rb-fsevent (~> 0.9, >= 0.9.4)
       rb-inotify (~> 0.9, >= 0.9.7)
       ruby_dep (~> 1.2)
     logstash-event (1.2.02)
-    logstasher (1.2.2)
+    logstasher (1.3.0)
       activesupport (>= 4.0)
       logstash-event (~> 1.2.0)
       request_store
-    loofah (2.2.2)
+    loofah (2.2.3)
       crass (~> 1.0.2)
       nokogiri (>= 1.5.9)
-    mail (2.7.0)
+    mail (2.7.1)
       mini_mime (>= 0.1.1)
-    marcel (0.3.2)
+    marcel (0.3.3)
       mimemagic (~> 0.3.2)
-    method_source (0.9.0)
-    mime-types (3.1)
-      mime-types-data (~> 3.2015)
-    mime-types-data (3.2016.0521)
-    mimemagic (0.3.2)
-    mini_mime (1.0.0)
-    mini_portile2 (2.3.0)
+    method_source (0.9.2)
+    mimemagic (0.3.3)
+    mini_magick (4.9.5)
+    mini_mime (1.0.2)
+    mini_portile2 (2.4.0)
     minitest (5.11.3)
-    msgpack (1.2.4)
+    msgpack (1.3.1)
     multi_json (1.13.1)
     multi_xml (0.6.0)
-    multipart-post (2.0.0)
-    nio4r (2.3.1)
-    nokogiri (1.8.3)
-      mini_portile2 (~> 2.3.0)
-    nokogumbo (1.5.0)
-      nokogiri
+    multipart-post (2.1.1)
+    nio4r (2.4.0)
+    nokogiri (1.10.4)
+      mini_portile2 (~> 2.4.0)
+    nokogumbo (2.0.1)
+      nokogiri (~> 1.8, >= 1.8.4)
     oauth (0.4.7)
     oauth-plugin (0.5.1)
       multi_json
       oauth (~> 0.4.4)
       oauth2 (>= 0.5.0)
       rack
-    oauth2 (1.4.0)
-      faraday (>= 0.8, < 0.13)
-      jwt (~> 1.0)
+    oauth2 (1.4.1)
+      faraday (>= 0.8, < 0.16.0)
+      jwt (>= 1.0, < 3.0)
       multi_json (~> 1.3)
       multi_xml (~> 0.5)
       rack (>= 1.2, < 3)
-    omniauth (1.8.1)
-      hashie (>= 3.4.6, < 3.6.0)
+    omniauth (1.9.0)
+      hashie (>= 3.4.6, < 3.7.0)
       rack (>= 1.6.2, < 3)
     omniauth-facebook (5.0.0)
       omniauth-oauth2 (~> 1.2)
     omniauth-github (1.3.0)
       omniauth (~> 1.5)
       omniauth-oauth2 (>= 1.4.0, < 2.0)
-    omniauth-google-oauth2 (0.5.3)
-      jwt (>= 1.5)
+    omniauth-google-oauth2 (0.8.0)
+      jwt (>= 2.0)
       omniauth (>= 1.1.1)
-      omniauth-oauth2 (>= 1.5)
-    omniauth-mediawiki (0.0.3)
-      jwt (~> 1.0)
+      omniauth-oauth2 (>= 1.6)
+    omniauth-mediawiki (0.0.4)
+      jwt (~> 2.0)
       omniauth-oauth (~> 1.0)
     omniauth-oauth (1.1.0)
       oauth
       omniauth (~> 1.0)
-    omniauth-oauth2 (1.5.0)
+    omniauth-oauth2 (1.6.0)
       oauth2 (~> 1.1)
-      omniauth (~> 1.2)
+      omniauth (~> 1.9)
     omniauth-openid (1.0.1)
       omniauth (~> 1.0)
       rack-openid (~> 1.3.1)
@@ -228,112 +307,107 @@ GEM
       multi_json (~> 1.12)
       omniauth-oauth2 (~> 1.4)
     openstreetmap-deadlock_retry (1.3.0)
-    paperclip (5.3.0)
-      activemodel (>= 4.2.0)
-      activesupport (>= 4.2.0)
-      mime-types
-      mimemagic (~> 0.3.0)
-      terrapin (~> 0.6.0)
-    parallel (1.12.1)
-    parser (2.5.1.0)
+    parallel (1.17.0)
+    parser (2.6.3.0)
       ast (~> 2.4.0)
-    pg (0.21.0)
+    pg (1.1.4)
     poltergeist (1.18.1)
       capybara (>= 2.1, < 4)
       cliver (~> 0.3.1)
       websocket-driver (>= 0.2.0)
-    powerpack (0.1.2)
-    progress (3.4.0)
-    psych (3.0.2)
-    public_suffix (3.0.2)
-    puma (3.11.4)
+    progress (3.5.2)
+    psych (3.1.0)
+    public_suffix (3.1.1)
+    puma (3.12.1)
     quad_tile (1.0.1)
     r2 (0.2.7)
-    rack (2.0.5)
-    rack-cors (1.0.2)
+    rack (2.0.7)
+    rack-cors (1.0.3)
     rack-openid (1.3.1)
       rack (>= 1.1.0)
       ruby-openid (>= 2.1.8)
-    rack-test (1.0.0)
+    rack-test (1.1.0)
       rack (>= 1.0, < 3)
     rack-uri_sanitizer (0.0.2)
-    rails (5.2.0)
-      actioncable (= 5.2.0)
-      actionmailer (= 5.2.0)
-      actionpack (= 5.2.0)
-      actionview (= 5.2.0)
-      activejob (= 5.2.0)
-      activemodel (= 5.2.0)
-      activerecord (= 5.2.0)
-      activestorage (= 5.2.0)
-      activesupport (= 5.2.0)
+    rails (5.2.3)
+      actioncable (= 5.2.3)
+      actionmailer (= 5.2.3)
+      actionpack (= 5.2.3)
+      actionview (= 5.2.3)
+      activejob (= 5.2.3)
+      activemodel (= 5.2.3)
+      activerecord (= 5.2.3)
+      activestorage (= 5.2.3)
+      activesupport (= 5.2.3)
       bundler (>= 1.3.0)
-      railties (= 5.2.0)
+      railties (= 5.2.3)
       sprockets-rails (>= 2.0.0)
-    rails-controller-testing (1.0.2)
-      actionpack (~> 5.x, >= 5.0.1)
-      actionview (~> 5.x, >= 5.0.1)
-      activesupport (~> 5.x)
+    rails-controller-testing (1.0.4)
+      actionpack (>= 5.0.1.x)
+      actionview (>= 5.0.1.x)
+      activesupport (>= 5.0.1.x)
     rails-dom-testing (2.0.3)
       activesupport (>= 4.2.0)
       nokogiri (>= 1.6)
-    rails-html-sanitizer (1.0.4)
+    rails-html-sanitizer (1.2.0)
       loofah (~> 2.2, >= 2.2.2)
     rails-i18n (4.0.2)
       i18n (~> 0.6)
       rails (>= 4.0)
-    railties (5.2.0)
-      actionpack (= 5.2.0)
-      activesupport (= 5.2.0)
+    railties (5.2.3)
+      actionpack (= 5.2.3)
+      activesupport (= 5.2.3)
       method_source
       rake (>= 0.8.7)
-      thor (>= 0.18.1, < 2.0)
+      thor (>= 0.19.0, < 2.0)
     rainbow (3.0.0)
-    rake (12.3.1)
+    rake (12.3.3)
     rb-fsevent (0.10.3)
-    rb-inotify (0.9.10)
-      ffi (>= 0.5.0, < 2)
+    rb-inotify (0.10.0)
+      ffi (~> 1.0)
     record_tag_helper (1.0.0)
       actionview (~> 5.x)
-    redcarpet (3.4.0)
-    ref (2.0.0)
     request_store (1.4.1)
       rack (>= 1.4)
-    rinku (2.0.4)
-    rotp (3.3.1)
-    rubocop (0.57.2)
+    rinku (2.0.6)
+    rotp (5.1.0)
+      addressable (~> 2.5)
+    rubocop (0.74.0)
       jaro_winkler (~> 1.5.1)
       parallel (~> 1.10)
-      parser (>= 2.5)
-      powerpack (~> 0.1)
+      parser (>= 2.6)
       rainbow (>= 2.2.2, < 4.0)
       ruby-progressbar (~> 1.7)
-      unicode-display_width (~> 1.0, >= 1.0.1)
+      unicode-display_width (>= 1.4.0, < 1.7)
+    rubocop-performance (1.4.1)
+      rubocop (>= 0.71.0)
+    rubocop-rails (2.3.1)
+      rack (>= 1.1)
+      rubocop (>= 0.72.0)
     ruby-openid (2.7.0)
-    ruby-progressbar (1.9.0)
+    ruby-progressbar (1.10.1)
     ruby_dep (1.5.0)
-    safe_yaml (1.0.4)
-    sanitize (4.6.5)
+    safe_yaml (1.0.5)
+    sanitize (5.0.0)
       crass (~> 1.0.2)
-      nokogiri (>= 1.4.4)
-      nokogumbo (~> 1.4)
-    sass (3.5.6)
-      sass-listen (~> 4.0.0)
-    sass-listen (4.0.0)
-      rb-fsevent (~> 0.9, >= 0.9.4)
-      rb-inotify (~> 0.9, >= 0.9.7)
-    sass-rails (5.0.7)
-      railties (>= 4.0.0, < 6)
-      sass (~> 3.1)
-      sprockets (>= 2.8, < 4.0)
-      sprockets-rails (>= 2.0, < 4.0)
-      tilt (>= 1.1, < 3)
-    secure_headers (6.0.0)
-    simplecov (0.14.1)
-      docile (~> 1.1.0)
+      nokogiri (>= 1.8.0)
+      nokogumbo (~> 2.0)
+    sassc (2.0.1)
+      ffi (~> 1.9)
+      rake
+    sassc-rails (2.1.2)
+      railties (>= 4.0.0)
+      sassc (>= 2.0)
+      sprockets (> 3.0)
+      sprockets-rails
+      tilt
+    secure_headers (6.1.1)
+    simplecov (0.16.1)
+      docile (~> 1.1)
       json (>= 1.8, < 3)
       simplecov-html (~> 0.10.0)
     simplecov-html (0.10.2)
+    smart_properties (1.15.0)
     sprockets (3.7.2)
       concurrent-ruby (~> 1.0)
       rack (> 1, < 3)
@@ -341,33 +415,30 @@ GEM
       actionpack (>= 4.0)
       activesupport (>= 4.0)
       sprockets (>= 3.0.0)
-    term-ansicolor (1.6.0)
+    strong_migrations (0.4.1)
+      activerecord (>= 5)
+    term-ansicolor (1.7.1)
       tins (~> 1.0)
-    terrapin (0.6.0)
-      climate_control (>= 0.0.3, < 1.0)
-    therubyracer (0.12.3)
-      libv8 (~> 3.16.14.15)
-      ref
-    thor (0.19.4)
+    thor (0.20.3)
     thread_safe (0.3.6)
-    tilt (2.0.8)
-    tins (1.16.3)
+    tilt (2.0.9)
+    tins (1.21.1)
     tzinfo (1.2.5)
       thread_safe (~> 0.1)
-    uglifier (4.1.12)
+    uglifier (4.1.20)
       execjs (>= 0.3.0, < 3)
-    unicode-display_width (1.4.0)
+    unicode-display_width (1.6.0)
     validates_email_format_of (1.6.3)
       i18n
-    vendorer (0.1.16)
-    webmock (3.4.2)
+    vendorer (0.2.0)
+    webmock (3.6.2)
       addressable (>= 2.3.6)
       crack (>= 0.3.2)
-      hashdiff
-    websocket-driver (0.7.0)
+      hashdiff (>= 0.4.0, < 2.0.0)
+    websocket-driver (0.7.1)
       websocket-extensions (>= 0.1.0)
-    websocket-extensions (0.1.3)
-    xpath (3.1.0)
+    websocket-extensions (0.1.4)
+    xpath (3.2.0)
       nokogiri (~> 1.8)
 
 PLATFORMS
@@ -377,46 +448,59 @@ DEPENDENCIES
   SystemTimer (>= 1.1.3)
   aasm
   actionpack-page_caching
+  active_record_union
+  activerecord-import
   annotate
-  autoprefixer-rails
+  autoprefixer-rails (~> 8.6.3)
+  aws-sdk-s3
   better_errors
   bigdecimal (~> 1.1.0)
   binding_of_caller
   bootsnap (>= 1.1.0)
+  browser
+  bzip2-ffi
+  cancancan
   canonical-rails
   capybara (~> 2.13)
   coffee-rails (~> 4.2)
-  composite_primary_keys (~> 11.0.0)
+  composite_primary_keys (~> 11.1.0)
+  config
   coveralls
   dalli
+  delayed_job_active_record
   dynamic_form
+  erb_lint
   factory_bot_rails
+  fakefs
   faraday
+  ffi-libarchive
+  gd2-ffij (>= 0.4.0)
   geoip
   htmlentities
   http_accept_language (~> 2.0.0)
   i18n-js (>= 3.0.0)
   image_optim_rails
   jquery-rails
-  jshint
   json
   jsonify-rails
   kgio
+  kramdown
   libxml-ruby (>= 2.0.5)
   listen
   logstasher
+  mimemagic
+  mini_magick
   minitest (~> 5.1)
   oauth-plugin (>= 0.5.1)
   omniauth
   omniauth-facebook
   omniauth-github
-  omniauth-google-oauth2 (>= 0.2.7)
-  omniauth-mediawiki (>= 0.0.3)
+  omniauth-google-oauth2 (>= 0.6.0)
+  omniauth-mediawiki (>= 0.0.4)
   omniauth-openid
   omniauth-windowslive
   openstreetmap-deadlock_retry (>= 1.3.0)
-  paperclip (~> 5.2)
-  pg (~> 0.18)
+  pg
   poltergeist
   psych
   puma (~> 3.7)
@@ -424,21 +508,23 @@ DEPENDENCIES
   r2 (~> 0.2.7)
   rack-cors
   rack-uri_sanitizer
-  rails (= 5.2.0)
+  rails (= 5.2.3)
   rails-controller-testing
   rails-i18n (~> 4.0.0)
   record_tag_helper
-  redcarpet
-  rinku (>= 1.2.2)
+  rinku (>= 2.0.6)
   rotp
   rubocop
+  rubocop-performance
+  rubocop-rails
   sanitize
-  sass-rails (~> 5.0)
+  sassc-rails
   secure_headers
+  strong_migrations
   uglifier (>= 1.3.0)
   validates_email_format_of (>= 1.5.1)
   vendorer
   webmock
 
 BUNDLED WITH
-   1.16.2
+   1.17.2
index 768cbd540c430a3d998ed40fca36052f2dd4ed84..2b1b4b5dead268f05bda85a3004a153fdbf1ac64 100644 (file)
@@ -5,7 +5,7 @@ If you want to deploy the software for your own project, then see the notes at t
 
 You can install the software directly on your machine, which is the traditional and probably best-supported approach. However, there is an alternative which may be easier: Vagrant. This installs the software into a virtual machine, which makes it easier to get a consistent development environment and may avoid installation difficulties. For Vagrant instructions, see [VAGRANT.md](VAGRANT.md).
 
-These instructions are based on Ubuntu 12.04 LTS, which is the platform used by the OSMF servers.
+These instructions are based on Ubuntu 18.04 LTS, which is the platform used by the OSMF servers.
 The instructions also work, with only minor amendments, for all other current Ubuntu releases, Fedora and MacOSX
 
 We don't recommend attempting to develop or deploy this software on Windows. If you need to use Windows, then try developing this software using Ubuntu in a virtual machine, or use [Vagrant](VAGRANT.md).
@@ -18,22 +18,22 @@ of packages required before you can get the various gems installed.
 
 ## Minimum requirements
 
-* Ruby 2.3
-* RubyGems 1.3.1+
+* Ruby 2.5+
 * PostgreSQL 9.1+
 * ImageMagick
 * Bundler
 * Javascript Runtime
 
-These can be installed on Ubuntu 16.04 or later with:
+These can be installed on Ubuntu 18.04 or later with:
 
 ```
-sudo apt-get install ruby2.3 libruby2.3 ruby2.3-dev \
+sudo apt-get update
+sudo apt-get install ruby2.5 libruby2.5 ruby2.5-dev bundler \
                      libmagickwand-dev libxml2-dev libxslt1-dev nodejs \
-                     apache2 apache2-dev build-essential git-core \
+                     apache2 apache2-dev build-essential git-core phantomjs \
                      postgresql postgresql-contrib libpq-dev postgresql-server-dev-all \
-                     libsasl2-dev imagemagick libffi-dev
-sudo gem2.3 install bundler
+                     libsasl2-dev imagemagick libffi-dev libgd-dev libarchive-dev libbz2-dev
+sudo gem2.5 install bundler
 ```
 
 ### Alternative platforms
@@ -43,11 +43,12 @@ sudo gem2.3 install bundler
 For Fedora, you can install the minimum requirements with:
 
 ```
-sudo yum install ruby ruby-devel rubygem-rdoc rubygem-bundler rubygems \
+sudo dnf install ruby ruby-devel rubygem-rdoc rubygem-bundler rubygems \
                  libxml2-devel js \
                  gcc gcc-c++ git \
                  postgresql postgresql-server postgresql-contrib postgresql-devel \
-                 perl-podlators ImageMagick libffi-devel
+                 perl-podlators ImageMagick libffi-devel gd-devel libarchive-devel \
+                 bzip2-devel nodejs-yarn
 ```
 
 If you didn't already have PostgreSQL installed then create a PostgreSQL instance and start the server:
@@ -115,15 +116,22 @@ cd openstreetmap-website
 bundle install
 ```
 
-## Application setup
+## Node.js modules
 
-We need to create the `config/application.yml` file from the example template. This contains various configuration options.
+We use [Yarn](https://yarnpkg.com/) to manage the Node.js modules required for the project.
 
 ```
-cp config/example.application.yml config/application.yml
+bundle exec rake yarn:install
 ```
 
-You can customize your installation of The Rails Port by changing the values in `config/application.yml`
+## Storage setup
+
+The Rails port needs to be configured with an object storage facility - for
+development and testing purposes you can use the example configuration:
+
+```
+cp config/example.storage.yml config/storage.yml
+```
 
 ## Database setup
 
@@ -210,7 +218,7 @@ Rails comes with a built-in webserver, so that you can test on your own machine
 bundle exec rails server
 ```
 
-You can now view the site in your favourite web-browser at `http://localhost:3000/`
+You can now view the site in your favourite web-browser at [http://localhost:3000/](http://localhost:3000/)
 
 Note that the OSM map tiles you see aren't created from your local database - they are just the standard map tiles.
 
index 44d914d75a1816c9b5f7591274c70e96e182f54e..fcb4790fef74461c0f028afc5c1a6d8032426522 100644 (file)
@@ -4,22 +4,26 @@
 Vagrant.configure("2") do |config|
   # use official ubuntu image for virtualbox
   config.vm.provider "virtualbox" do |vb, override|
-    override.vm.box = "ubuntu/xenial64"
+    override.vm.box = "ubuntu/bionic64"
     override.vm.synced_folder ".", "/srv/openstreetmap-website"
     vb.customize ["modifyvm", :id, "--memory", "1024"]
     vb.customize ["modifyvm", :id, "--cpus", "2"]
+    vb.customize ["modifyvm", :id, "--uartmode1", "disconnected"]
   end
 
-  # use third party image and NFS sharing for lxc
+  # Use sshfs sharing if available, otherwise NFS sharing
+  sharing_type = Vagrant.has_plugin?("vagrant-sshfs") ? "sshfs" : "nfs"
+
+  # use third party image and sshfs or NFS sharing for lxc
   config.vm.provider "lxc" do |_, override|
-    override.vm.box = "generic/ubuntu1604"
-    override.vm.synced_folder ".", "/srv/openstreetmap-website", :type => "nfs"
+    override.vm.box = "generic/ubuntu1804"
+    override.vm.synced_folder ".", "/srv/openstreetmap-website", :type => sharing_type
   end
 
-  # use third party image and NFS sharing for libvirt
+  # use third party image and sshfs or NFS sharing for libvirt
   config.vm.provider "libvirt" do |_, override|
-    override.vm.box = "generic/ubuntu1604"
-    override.vm.synced_folder ".", "/srv/openstreetmap-website", :type => "nfs"
+    override.vm.box = "generic/ubuntu1804"
+    override.vm.synced_folder ".", "/srv/openstreetmap-website", :type => sharing_type
   end
 
   # configure shared package cache if possible
index 8ca4342d75fffd1cbd61775dd3b806f24990166e..ad59f91ebea6aef14b73f8295c84aeeb14993c05 100644 (file)
@@ -11,13 +11,13 @@ folder 'vendor/assets' do
   end
 
   folder 'leaflet' do
-    file 'leaflet.js', 'https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js'
-    file 'leaflet.css', 'https://unpkg.com/leaflet@1.3.1/dist/leaflet.css'
+    file 'leaflet.js', 'https://unpkg.com/leaflet@1.5.1/dist/leaflet-src.js'
+    file 'leaflet.css', 'https://unpkg.com/leaflet@1.5.1/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.3.1/dist/images/#{image}"
+      file "images/#{image}", "https://unpkg.com/leaflet@1.5.1/dist/images/#{image}"
     end
 
     from 'git://github.com/aratcliffe/Leaflet.contextmenu.git', :tag => 'v1.5.0' do
@@ -31,7 +31,7 @@ folder 'vendor/assets' do
       folder 'img', 'src/img'
     end
 
-    from 'git://github.com/domoritz/leaflet-locatecontrol.git', :tag => 'v0.62.0' do
+    from 'git://github.com/domoritz/leaflet-locatecontrol.git', :tag => 'v0.66.0' do
       file 'leaflet.locate.js', 'src/L.Control.Locate.js'
     end
 
@@ -67,9 +67,14 @@ folder 'vendor/assets' do
     end
   end
 
+  folder 'polyfill' do
+    file 'es5.js', 'https://polyfill.io/v3/polyfill.js?features=es5&flags=gated,always'
+    file 'es6.js', 'https://polyfill.io/v3/polyfill.js?features=es6&flags=gated,always'
+  end
+
   folder 'javascripts' do
     file 'html5shiv.js', 'https://raw.githubusercontent.com/aFarkas/html5shiv/master/src/html5shiv.js'
-    file 'bowser.js', 'https://github.com/lancedikson/bowser/releases/download/1.9.3/bowser.js'
+    file 'bowser.js', 'https://github.com/lancedikson/bowser/releases/download/1.9.4/bowser.js'
   end
 
   folder 'swfobject' do
diff --git a/app/abilities/ability.rb b/app/abilities/ability.rb
new file mode 100644 (file)
index 0000000..c34f357
--- /dev/null
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+class Ability
+  include CanCan::Ability
+
+  def initialize(user)
+    can [:relation, :relation_history, :way, :way_history, :node, :node_history,
+         :changeset, :note, :new_note, :query], :browse
+    can :search, :direction
+    can [:index, :permalink, :edit, :help, :fixthemap, :offline, :export, :about, :preview, :copyright, :key, :id], :site
+    can [:finish, :embed], :export
+    can [:search, :search_latlon, :search_ca_postcode, :search_osm_nominatim,
+         :search_geonames, :search_osm_nominatim_reverse, :search_geonames_reverse], :geocoder
+    can [:token, :request_token, :access_token, :test_request], :oauth
+
+    if Settings.status != "database_offline"
+      can [:index, :feed], Changeset
+      can :index, ChangesetComment
+      can [:index, :rss, :show, :comments], DiaryEntry
+      can [:mine], Note
+      can [:index, :show], Redaction
+      can [:index, :show, :data, :georss, :picture, :icon], Trace
+      can [:terms, :login, :logout, :new, :create, :save, :confirm, :confirm_resend, :confirm_email, :lost_password, :reset_password, :show, :auth_success, :auth_failure], User
+      can [:index, :show, :blocks_on, :blocks_by], UserBlock
+      can [:index, :show], Node
+      can [:index, :show, :full, :ways_for_node], Way
+      can [:index, :show, :full, :relations_for_node, :relations_for_way, :relations_for_relation], Relation
+      can [:history, :version], OldNode
+      can [:history, :version], OldWay
+      can [:history, :version], OldRelation
+    end
+
+    if user
+      can :welcome, :site
+      can [:revoke, :authorize], :oauth
+
+      if Settings.status != "database_offline"
+        can [:index, :new, :create, :show, :edit, :update, :destroy], ClientApplication
+        can [:new, :create, :edit, :update, :comment, :subscribe, :unsubscribe], DiaryEntry
+        can [:new, :create, :reply, :show, :inbox, :outbox, :mark, :destroy], Message
+        can [:close, :reopen], Note
+        can [:new, :create], Report
+        can [:mine, :new, :create, :edit, :update, :delete], Trace
+        can [:account, :go_public, :make_friend, :remove_friend], User
+
+        if user.moderator?
+          can [:hide, :hidecomment], DiaryEntry
+          can [:index, :show, :resolve, :ignore, :reopen], Issue
+          can :create, IssueComment
+          can [:new, :create, :edit, :update, :destroy], Redaction
+          can [:new, :edit, :create, :update, :revoke], UserBlock
+        end
+
+        if user.administrator?
+          can [:hide, :unhide, :hidecomment, :unhidecomment], DiaryEntry
+          can [:index, :show, :resolve, :ignore, :reopen], Issue
+          can :create, IssueComment
+          can [:set_status, :delete, :index], User
+          can [:grant, :revoke], UserRole
+        end
+      end
+    end
+
+    # Define abilities for the passed in user here. For example:
+    #
+    #   user ||= User.new # guest user (not logged in)
+    #   if user.admin?
+    #     can :manage, :all
+    #   else
+    #     can :read, :all
+    #   end
+    #
+    # The first argument to `can` is the action you are giving the user
+    # permission to do.
+    # If you pass :manage it will apply to every action. Other common actions
+    # here are :read, :create, :update and :destroy.
+    #
+    # The second argument is the resource the user can perform the action on.
+    # If you pass :all it will apply to every resource. Otherwise pass a Ruby
+    # class of the resource.
+    #
+    # The third argument is an optional hash of conditions to further filter the
+    # objects.
+    # For example, here the user can only update published articles.
+    #
+    #   can :update, Article, :published => true
+    #
+    # See the wiki for details:
+    # https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
+  end
+end
diff --git a/app/abilities/api_ability.rb b/app/abilities/api_ability.rb
new file mode 100644 (file)
index 0000000..80245ee
--- /dev/null
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+class ApiAbility
+  include CanCan::Ability
+
+  def initialize(user)
+    can :show, :capability
+    can :index, :change
+    can :index, :map
+    can :show, :permission
+    can [:search_all, :search_nodes, :search_ways, :search_relations], :search
+    can :show, :version
+
+    if Settings.status != "database_offline"
+      can [:show, :download, :query], Changeset
+      can [:index, :create, :comment, :feed, :show, :search], Note
+      can :index, Tracepoint
+      can [:index, :show], User
+      can [:index, :show], Node
+      can [:index, :show, :full, :ways_for_node], Way
+      can [:index, :show, :full, :relations_for_node, :relations_for_way, :relations_for_relation], Relation
+      can [:history, :version], OldNode
+      can [:history, :version], OldWay
+      can [:history, :version], OldRelation
+    end
+
+    if user
+      can :welcome, :site
+      can [:revoke, :authorize], :oauth
+
+      if Settings.status != "database_offline"
+        can [:index, :new, :create, :show, :edit, :update, :destroy], ClientApplication
+        can [:new, :create, :reply, :show, :inbox, :outbox, :mark, :destroy], Message
+        can [:close, :reopen], Note
+        can [:new, :create], Report
+        can [:create, :show, :update, :destroy, :data], Trace
+        can [:details, :gpx_files], User
+        can [:read, :read_one, :update, :update_one, :delete_one], UserPreference
+
+        if user.terms_agreed?
+          can [:create, :update, :upload, :close, :subscribe, :unsubscribe, :expand_bbox], Changeset
+          can :create, ChangesetComment
+          can [:create, :update, :delete], Node
+          can [:create, :update, :delete], Way
+          can [:create, :update, :delete], Relation
+        end
+
+        if user.moderator?
+          can [:destroy, :restore], ChangesetComment
+          can :destroy, Note
+
+          if user.terms_agreed?
+            can :redact, OldNode
+            can :redact, OldWay
+            can :redact, OldRelation
+          end
+        end
+      end
+    end
+
+    # Define abilities for the passed in user here. For example:
+    #
+    #   user ||= User.new # guest user (not logged in)
+    #   if user.admin?
+    #     can :manage, :all
+    #   else
+    #     can :read, :all
+    #   end
+    #
+    # The first argument to `can` is the action you are giving the user
+    # permission to do.
+    # If you pass :manage it will apply to every action. Other common actions
+    # here are :read, :create, :update and :destroy.
+    #
+    # The second argument is the resource the user can perform the action on.
+    # If you pass :all it will apply to every resource. Otherwise pass a Ruby
+    # class of the resource.
+    #
+    # The third argument is an optional hash of conditions to further filter the
+    # objects.
+    # For example, here the user can only update published articles.
+    #
+    #   can :update, Article, :published => true
+    #
+    # See the wiki for details:
+    # https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
+  end
+end
diff --git a/app/abilities/api_capability.rb b/app/abilities/api_capability.rb
new file mode 100644 (file)
index 0000000..7d8a133
--- /dev/null
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+class ApiCapability
+  include CanCan::Ability
+
+  def initialize(token)
+    if Settings.status != "database_offline"
+      can [:create, :comment, :close, :reopen], Note if capability?(token, :allow_write_notes)
+      can [:show, :data], Trace if capability?(token, :allow_read_gpx)
+      can [:create, :update, :destroy], Trace if capability?(token, :allow_write_gpx)
+      can [:details], User if capability?(token, :allow_read_prefs)
+      can [:gpx_files], User if capability?(token, :allow_read_gpx)
+      can [:read, :read_one], UserPreference if capability?(token, :allow_read_prefs)
+      can [:update, :update_one, :delete_one], UserPreference if capability?(token, :allow_write_prefs)
+
+      if token&.user&.terms_agreed?
+        can [:create, :update, :upload, :close, :subscribe, :unsubscribe, :expand_bbox], Changeset if capability?(token, :allow_write_api)
+        can :create, ChangesetComment if capability?(token, :allow_write_api)
+        can [:create, :update, :delete], Node if capability?(token, :allow_write_api)
+        can [:create, :update, :delete], Way if capability?(token, :allow_write_api)
+        can [:create, :update, :delete], Relation if capability?(token, :allow_write_api)
+      end
+
+      if token&.user&.moderator?
+        can [:destroy, :restore], ChangesetComment if capability?(token, :allow_write_api)
+        can :destroy, Note if capability?(token, :allow_write_notes)
+        if token&.user&.terms_agreed?
+          can :redact, OldNode if capability?(token, :allow_write_api)
+          can :redact, OldWay if capability?(token, :allow_write_api)
+          can :redact, OldRelation if capability?(token, :allow_write_api)
+        end
+      end
+    end
+  end
+
+  private
+
+  def capability?(token, cap)
+    token&.read_attribute(cap)
+  end
+end
diff --git a/app/assets/images/banners/saveyourinternet.png b/app/assets/images/banners/saveyourinternet.png
new file mode 100644 (file)
index 0000000..4263396
Binary files /dev/null and b/app/assets/images/banners/saveyourinternet.png differ
index 4461c5ab71cc950e43a0c5ae5ac82003e0874840..fbc76e4a8db29f442dccfeafd0904d51437f096e 100644 (file)
@@ -5,30 +5,28 @@
 //= require jquery.throttle-debounce
 //= require bootstrap.tooltip
 //= require bootstrap.dropdown
-//= require augment
 //= require osm
 //= require leaflet
 //= require leaflet.osm
 //= require leaflet.map
 //= require leaflet.zoom
 //= require leaflet.locationfilter
-//= require i18n/translations
+//= require i18n
 //= require oauth
 //= require piwik
 //= require richtext
 //= require querystring
 
-var querystring = require('querystring-component');
-
 /*
  * Called as the user scrolls/zooms around to maniplate hrefs of the
  * view tab and various other links
  */
 window.updateLinks = function (loc, zoom, layers, object) {
-  $(".geolink").each(function(index, link) {
-    var href = link.href.split(/[?#]/)[0],
-      args = querystring.parse(link.search.substring(1)),
-      editlink = $(link).hasClass("editlink");
+  $(".geolink").each(function (index, link) {
+    var querystring = require("querystring-component"),
+        href = link.href.split(/[?#]/)[0],
+        args = querystring.parse(link.search.substring(1)),
+        editlink = $(link).hasClass("editlink");
 
     delete args.node;
     delete args.way;
@@ -40,11 +38,11 @@ window.updateLinks = function (loc, zoom, layers, object) {
     }
 
     var query = querystring.stringify(args);
-    if (query) href += '?' + query;
+    if (query) href += "?" + query;
 
     args = {
       lat: loc.lat,
-      lon: 'lon' in loc ? loc.lon : loc.lng,
+      lon: "lon" in loc ? loc.lon : loc.lng,
       zoom: zoom
     };
 
@@ -58,13 +56,13 @@ window.updateLinks = function (loc, zoom, layers, object) {
   });
 
   var editDisabled = zoom < 13;
-  $('#edit_tab')
-    .tooltip({placement: 'bottom'})
-    .off('click.minzoom')
-    .on('click.minzoom', function() { return !editDisabled; })
-    .toggleClass('disabled', editDisabled)
-    .attr('data-original-title', editDisabled ?
-      I18n.t('javascripts.site.edit_disabled_tooltip') : '');
+  $("#edit_tab")
+    .tooltip({ placement: "bottom" })
+    .off("click.minzoom")
+    .on("click.minzoom", function () { return !editDisabled; })
+    .toggleClass("disabled", editDisabled)
+    .attr("data-original-title", editDisabled ?
+      I18n.t("javascripts.site.edit_disabled_tooltip") : "");
 };
 
 window.maximiseMap = function () {
@@ -98,13 +96,13 @@ $(document).ready(function () {
    * to defer the measurement slightly as a workaround.
    */
   setTimeout(function () {
-    $("header").children(":visible").each(function (i,e) {
+    $("header").children(":visible").each(function (i, e) {
       headerWidth = headerWidth + $(e).outerWidth();
     });
 
     $("body").addClass("compact");
 
-    $("header").children(":visible").each(function (i,e) {
+    $("header").children(":visible").each(function (i, e) {
       compactWidth = compactWidth + $(e).outerWidth();
     });
 
@@ -115,12 +113,12 @@ $(document).ready(function () {
     $(window).resize(updateHeader);
   }, 0);
 
-  $("#menu-icon").on("click", function(e) {
+  $("#menu-icon").on("click", function (e) {
     e.preventDefault();
     $("header").toggleClass("closed");
   });
 
-  $("nav.primary li a").on("click", function() {
+  $("nav.primary li a").on("click", function () {
     $("header").toggleClass("closed");
   });
 
index b513057c148d8908fc167b05b271034c7c8a7c54..625d43a5228f0b07a391f988a43cae3327364e67 100644 (file)
@@ -9,8 +9,8 @@ $(document).ready(function () {
       map.removeLayer(marker);
     }
 
-    marker = L.marker(e.latlng, {icon: OSM.getUserIcon()}).addTo(map)
-      .bindPopup(I18n.t('diary_entry.edit.marker_text'));
+    marker = L.marker(e.latlng, { icon: OSM.getUserIcon() }).addTo(map)
+      .bindPopup(I18n.t("diary_entries.edit.marker_text"));
   }
 
   $("#usemap").click(function (e) {
@@ -21,21 +21,21 @@ $(document).ready(function () {
 
     var params = $("#map").data();
     var centre = [params.lat, params.lon];
-    var position = $('html').attr('dir') === 'rtl' ? 'topleft' : 'topright';
+    var position = $("html").attr("dir") === "rtl" ? "topleft" : "topright";
 
     map = L.map("map", {
       attributionControl: false,
       zoomControl: false
     }).addLayer(new L.OSM.Mapnik());
 
-    L.OSM.zoom({position: position})
+    L.OSM.zoom({ position: position })
       .addTo(map);
 
     map.setView(centre, params.zoom);
 
     if ($("#latitude").val() && $("#longitude").val()) {
-      marker = L.marker(centre, {icon: OSM.getUserIcon()}).addTo(map)
-        .bindPopup(I18n.t('diary_entry.edit.marker_text'));
+      marker = L.marker(centre, { icon: OSM.getUserIcon() }).addTo(map)
+        .bindPopup(I18n.t("diary_entries.edit.marker_text"));
     }
 
     map.on("click", setLocation);
index a85fcef457f98271606c692985d1227ad191a7bc..23726519ec53ab5a60b1a0bcc9635e749b30dcce 100644 (file)
@@ -1,4 +1,7 @@
+//= require querystring
+
 $(document).ready(function () {
+  var querystring = require("querystring-component");
   var id = $("#id-embed");
 
   if (id.data("key")) {
@@ -20,10 +23,14 @@ $(document).ready(function () {
 
     if (hashParams.background) params.background = hashParams.background;
     if (hashParams.comment) params.comment = hashParams.comment;
-    if (hashParams.hashtags) params.hashtags = hashParams.hashtags;
-    if (hashParams.source) params.source = hashParams.source;
     if (hashParams.disable_features) params.disable_features = hashParams.disable_features;
+    if (hashParams.hashtags) params.hashtags = hashParams.hashtags;
+    if (hashParams.locale) params.locale = hashParams.locale;
+    if (hashParams.maprules) params.maprules = hashParams.maprules;
     if (hashParams.offset) params.offset = hashParams.offset;
+    if (hashParams.photo_overlay) params.photo_overlay = hashParams.photo_overlay;
+    if (hashParams.presets) params.presets = hashParams.presets;
+    if (hashParams.source) params.source = hashParams.source;
     if (hashParams.walkthrough) params.walkthrough = hashParams.walkthrough;
 
     if (id.data("gpx")) {
index 15839a2ecbc4af23102a608c0804a4b988d92916..ceb488f987681871e05c87476e5a464de126c79d 100644 (file)
@@ -1,6 +1,7 @@
 //= require leaflet
 //= require leaflet.osm
-//= require i18n/translations
+//= require i18n
+//= require i18n/embed
 
 window.onload = function () {
   if (navigator.languages) {
@@ -19,8 +20,8 @@ window.onload = function () {
   }
 
   var thunderforestOptions = {
-<% if defined?(THUNDERFOREST_KEY) %>
-    apikey: <%= THUNDERFOREST_KEY.to_json %>
+<% if Settings.key?(:thunderforest_key) %>
+    apikey: <%= Settings.thunderforest_key.to_json %>
 <% end %>
   };
 
index e2a503ad319ba06d3541eb376a433d3e4c69fccb..47ba9baf4da556ea4b30dfd38d173575dec960f3 100644 (file)
@@ -1,12 +1,12 @@
-$(document).ready(function() {
+$(document).ready(function () {
   var params = OSM.params();
 
-  var url = '/note/new';
+  var url = "/note/new";
   if (params.lat && params.lon) {
     params.lat = parseFloat(params.lat);
     params.lon = parseFloat(params.lon);
     params.zoom = params.zoom || 17;
     url += OSM.formatHash(params);
   }
-  $('.icon.note').attr('href', url);
+  $(".icon.note").attr("href", url);
 });
index dd7cd3325f10f293311e79435cec6633a3d1f8ac..ba16d9df2451a394d79bb5f726b0fc4d7d22b71b 100644 (file)
@@ -2,14 +2,14 @@
 
 /* globals iD */
 
-document.addEventListener("DOMContentLoaded", function() {
+document.addEventListener("DOMContentLoaded", function () {
   var container = document.getElementById("id-container");
 
-  if (typeof iD === 'undefined' || !iD.Detect().support) {
-    container.innerHTML = 'This editor is supported ' +
-      'in Firefox, Chrome, Safari, Opera, Edge, and Internet Explorer 11. ' +
-      'Please upgrade your browser or use Potlatch 2 to edit the map.';
-    container.className = 'unsupported';
+  if (typeof iD === "undefined" || !iD.Detect().support) {
+    container.innerHTML = "This editor is supported " +
+      "in Firefox, Chrome, Safari, Opera, Edge, and Internet Explorer 11. " +
+      "Please upgrade your browser or use Potlatch 2 to edit the map.";
+    container.className = "unsupported";
   } else {
     var id = iD.Context()
       .embed(true)
@@ -24,11 +24,11 @@ document.addEventListener("DOMContentLoaded", function() {
         oauth_token_secret: container.dataset.tokenSecret
       });
 
-    id.map().on('move.embed', parent.$.throttle(250, function() {
+    id.map().on("move.embed", parent.$.throttle(250, function () {
       if (id.inIntro()) return;
       var zoom = ~~id.map().zoom(),
-        center = id.map().center(),
-        llz = { lon: center[0], lat: center[1], zoom: zoom };
+          center = id.map().center(),
+          llz = { lon: center[0], lat: center[1], zoom: zoom };
 
       parent.updateLinks(llz, zoom);
 
@@ -46,7 +46,7 @@ document.addEventListener("DOMContentLoaded", function() {
 
       // 0ms timeout to avoid iframe JS context weirdness.
       // http://bl.ocks.org/jfirebaugh/5439412
-      setTimeout(function() {
+      setTimeout(function () {
         id.map().centerZoom(
           [data.lon, data.lat],
           Math.max(data.zoom || 15, 13));
index ccf4e561c98ceacd14d0e612f77e408fc6bac734..2c7d70e11ad99603056546396c017cc7e1711ddc 100644 (file)
 //= require index/query
 //= require router
 //= require bowser
+//= require querystring
 
 $(document).ready(function () {
+  var querystring = require("querystring-component");
+
   var loaderTimeout;
 
-  OSM.loadSidebarContent = function(path, callback) {
+  var map = new L.OSM.Map("map", {
+    zoomControl: false,
+    layerControl: false,
+    contextmenu: true
+  });
+
+  OSM.loadSidebarContent = function (path, callback) {
+    var content_path = path;
+
     map.setSidebarOverlaid(false);
 
     clearTimeout(loaderTimeout);
 
-    loaderTimeout = setTimeout(function() {
-      $('#sidebar_loader').show();
+    loaderTimeout = setTimeout(function () {
+      $("#sidebar_loader").show();
     }, 200);
 
     // IE<10 doesn't respect Vary: X-Requested-With header, so
     // prevent caching the XHR response as a full-page URL.
-    if (path.indexOf('?') >= 0) {
-      path += '&xhr=1';
+    if (content_path.indexOf("?") >= 0) {
+      content_path += "&xhr=1";
     } else {
-      path += '?xhr=1';
+      content_path += "?xhr=1";
     }
 
-    $('#sidebar_content')
+    $("#sidebar_content")
       .empty();
 
     $.ajax({
-      url: path,
+      url: content_path,
       dataType: "html",
-      complete: function(xhr) {
+      complete: function (xhr) {
         clearTimeout(loaderTimeout);
-        $('#flash').empty();
-        $('#sidebar_loader').hide();
+        $("#flash").empty();
+        $("#sidebar_loader").hide();
 
         var content = $(xhr.responseText);
 
-        if (xhr.getResponseHeader('X-Page-Title')) {
-          var title = xhr.getResponseHeader('X-Page-Title');
+        if (xhr.getResponseHeader("X-Page-Title")) {
+          var title = xhr.getResponseHeader("X-Page-Title");
           document.title = decodeURIComponent(title);
         }
 
-        $('head')
-          .find('link[type="application/atom+xml"]')
+        $("head")
+          .find("link[type=\"application/atom+xml\"]")
           .remove();
 
-        $('head')
-          .append(content.filter('link[type="application/atom+xml"]'));
+        $("head")
+          .append(content.filter("link[type=\"application/atom+xml\"]"));
 
-        $('#sidebar_content').html(content.not('link[type="application/atom+xml"]'));
+        $("#sidebar_content").html(content.not("link[type=\"application/atom+xml\"]"));
 
         if (callback) {
           callback();
@@ -78,13 +89,7 @@ $(document).ready(function () {
 
   var params = OSM.mapParams();
 
-  var map = new L.OSM.Map("map", {
-    zoomControl: false,
-    layerControl: false,
-    contextmenu: true
-  });
-
-  map.attributionControl.setPrefix('');
+  map.attributionControl.setPrefix("");
 
   map.updateLayers(params.layers);
 
@@ -94,32 +99,32 @@ $(document).ready(function () {
     }
   });
 
-  var position = $('html').attr('dir') === 'rtl' ? 'topleft' : 'topright';
+  var position = $("html").attr("dir") === "rtl" ? "topleft" : "topright";
 
-  L.OSM.zoom({position: position})
+  L.OSM.zoom({ position: position })
     .addTo(map);
 
   var locate = L.control.locate({
     position: position,
-    icon: 'icon geolocate',
-    iconLoading: 'icon geolocate',
+    icon: "icon geolocate",
+    iconLoading: "icon geolocate",
     strings: {
-      title: I18n.t('javascripts.map.locate.title'),
-      popup: I18n.t('javascripts.map.locate.popup')
+      title: I18n.t("javascripts.map.locate.title"),
+      popup: I18n.t("javascripts.map.locate.popup")
     }
   }).addTo(map);
 
   var locateContainer = locate.getContainer();
 
   $(locateContainer)
-    .removeClass('leaflet-control-locate leaflet-bar')
-    .addClass('control-locate')
+    .removeClass("leaflet-control-locate leaflet-bar")
+    .addClass("control-locate")
     .children("a")
-    .attr('href', '#')
-    .removeClass('leaflet-bar-part leaflet-bar-part-single')
-    .addClass('control-button');
+    .attr("href", "#")
+    .removeClass("leaflet-bar-part leaflet-bar-part-single")
+    .addClass("control-button");
 
-  var sidebar = L.OSM.sidebar('#map-ui')
+  var sidebar = L.OSM.sidebar("#map-ui")
     .addTo(map);
 
   L.OSM.layers({
@@ -134,9 +139,9 @@ $(document).ready(function () {
   }).addTo(map);
 
   L.OSM.share({
-    position: position,
-    sidebar: sidebar,
-    short: true
+    "position": position,
+    "sidebar": sidebar,
+    "short": true
   }).addTo(map);
 
   L.OSM.note({
@@ -154,7 +159,7 @@ $(document).ready(function () {
 
   OSM.initializeContextMenu(map);
 
-  if (OSM.STATUS !== 'api_offline' && OSM.STATUS !== 'database_offline') {
+  if (OSM.STATUS !== "api_offline" && OSM.STATUS !== "database_offline") {
     OSM.initializeNotes(map);
     if (params.layers.indexOf(map.noteLayer.options.code) >= 0) {
       map.addLayer(map.noteLayer);
@@ -170,51 +175,51 @@ $(document).ready(function () {
     }
   }
 
-  var placement = $('html').attr('dir') === 'rtl' ? 'right' : 'left';
-  $('.leaflet-control .control-button').tooltip({placement: placement, container: 'body'});
+  var placement = $("html").attr("dir") === "rtl" ? "right" : "left";
+  $(".leaflet-control .control-button").tooltip({ placement: placement, container: "body" });
 
   var expiry = new Date();
   expiry.setYear(expiry.getFullYear() + 10);
 
-  map.on('moveend layeradd layerremove', function() {
+  map.on("moveend layeradd layerremove", function () {
     updateLinks(
       map.getCenter().wrap(),
       map.getZoom(),
       map.getLayersCode(),
       map._object);
 
-    $.removeCookie('_osm_location');
-    $.cookie('_osm_location', OSM.locationCookie(map), { expires: expiry, path: '/' });
+    $.removeCookie("_osm_location");
+    $.cookie("_osm_location", OSM.locationCookie(map), { expires: expiry, path: "/" });
   });
 
-  if ($.cookie('_osm_welcome') === 'hide') {
-    $('.welcome').hide();
+  if ($.cookie("_osm_welcome") !== "hide") {
+    $(".welcome").addClass("visible");
   }
 
-  $('.welcome .close-wrap').on('click', function() {
-    $('.welcome').hide();
-    $.cookie('_osm_welcome', 'hide', { expires: expiry, path: '/' });
+  $(".welcome .close-wrap").on("click", function () {
+    $(".welcome").removeClass("visible");
+    $.cookie("_osm_welcome", "hide", { expires: expiry, path: "/" });
   });
 
   var bannerExpiry = new Date();
   bannerExpiry.setYear(bannerExpiry.getFullYear() + 1);
 
-  $('#banner .close-wrap').on('click', function(e) {
+  $("#banner .close-wrap").on("click", function (e) {
     var cookieId = e.target.id;
-    $('#banner').hide();
+    $("#banner").hide();
     e.preventDefault();
     if (cookieId) {
-      $.cookie(cookieId, 'hide', { expires: bannerExpiry, path: '/' });
+      $.cookie(cookieId, "hide", { expires: bannerExpiry, path: "/" });
     }
   });
 
   if (OSM.PIWIK) {
-    map.on('layeradd', function (e) {
+    map.on("layeradd", function (e) {
       if (e.layer.options) {
         var goal = OSM.PIWIK.goals[e.layer.options.keyid];
 
         if (goal) {
-          $('body').trigger('piwikgoal', goal);
+          $("body").trigger("piwikgoal", goal);
         }
       }
     });
@@ -230,14 +235,14 @@ $(document).ready(function () {
     L.marker([params.mlat, params.mlon]).addTo(map);
   }
 
-  $("#homeanchor").on("click", function(e) {
+  $("#homeanchor").on("click", function (e) {
     e.preventDefault();
 
     var data = $(this).data(),
-      center = L.latLng(data.lat, data.lon);
+        center = L.latLng(data.lat, data.lon);
 
     map.setView(center, data.zoom);
-    L.marker(center, {icon: OSM.getUserIcon()}).addTo(map);
+    L.marker(center, { icon: OSM.getUserIcon() }).addTo(map);
   });
 
   function remoteEditHandler(bbox, object) {
@@ -250,8 +255,8 @@ $(document).ready(function () {
           bottom: bbox.getSouth() - 0.0001
         };
 
-    if (location.protocol === 'http' ||
-        bowser.check({chrome: "53", firefox: "55"})) {
+    if (location.protocol === "http" ||
+        bowser.check({ chrome: "53", firefox: "55" })) {
       url = "http://127.0.0.1:8111/load_and_zoom?";
     } else {
       url = "https://127.0.0.1:8112/load_and_zoom?";
@@ -259,18 +264,18 @@ $(document).ready(function () {
 
     if (object) query.select = object.type + object.id;
 
-    var iframe = $('<iframe>')
-        .hide()
-        .appendTo('body')
-        .attr("src", url + querystring.stringify(query))
-        .on('load', function() {
-          $(this).remove();
-          loaded = true;
-        });
+    var iframe = $("<iframe>")
+      .hide()
+      .appendTo("body")
+      .attr("src", url + querystring.stringify(query))
+      .on("load", function () {
+        $(this).remove();
+        loaded = true;
+      });
 
     setTimeout(function () {
       if (!loaded) {
-        alert(I18n.t('site.index.remote_failed'));
+        alert(I18n.t("site.index.remote_failed"));
         iframe.remove();
       }
     }, 1000);
@@ -278,35 +283,35 @@ $(document).ready(function () {
     return false;
   }
 
-  $("a[data-editor=remote]").click(function(e) {
+  $("a[data-editor=remote]").click(function (e) {
     var params = OSM.mapParams(this.search);
     remoteEditHandler(map.getBounds(), params.object);
     e.preventDefault();
   });
 
   if (OSM.params().edit_help) {
-    $('#editanchor')
-      .removeAttr('title')
+    $("#editanchor")
+      .removeAttr("title")
       .tooltip({
-        placement: 'bottom',
-        title: I18n.t('javascripts.edit_help')
+        placement: "bottom",
+        title: I18n.t("javascripts.edit_help")
       })
-      .tooltip('show');
+      .tooltip("show");
 
-    $('body').one('click', function() {
-      $('#editanchor').tooltip('hide');
+    $("body").one("click", function () {
+      $("#editanchor").tooltip("hide");
     });
   }
 
-  OSM.Index = function(map) {
+  OSM.Index = function (map) {
     var page = {};
 
-    page.pushstate = page.popstate = function() {
+    page.pushstate = page.popstate = function () {
       map.setSidebarOverlaid(true);
-      document.title = I18n.t('layouts.project_name.title');
+      document.title = I18n.t("layouts.project_name.title");
     };
 
-    page.load = function() {
+    page.load = function () {
       var params = querystring.parse(location.search.substring(1));
       if (params.query) {
         $("#sidebar .search_form input[name=query]").value(params.query);
@@ -320,21 +325,21 @@ $(document).ready(function () {
     return page;
   };
 
-  OSM.Browse = function(map, type) {
+  OSM.Browse = function (map, type) {
     var page = {};
 
-    page.pushstate = page.popstate = function(path, id) {
-      OSM.loadSidebarContent(path, function() {
+    page.pushstate = page.popstate = function (path, id) {
+      OSM.loadSidebarContent(path, function () {
         addObject(type, id);
       });
     };
 
-    page.load = function(path, id) {
+    page.load = function (path, id) {
       addObject(type, id, true);
     };
 
     function addObject(type, id, center) {
-      map.addObject({type: type, id: parseInt(id)}, function(bounds) {
+      map.addObject({ type: type, id: parseInt(id, 10) }, function (bounds) {
         if (!window.location.hash && bounds.isValid() &&
             (center || !map.getBounds().contains(bounds))) {
           OSM.router.withoutMoveListener(function () {
@@ -344,7 +349,7 @@ $(document).ready(function () {
       });
     }
 
-    page.unload = function() {
+    page.unload = function () {
       map.removeObject();
     };
 
@@ -354,21 +359,21 @@ $(document).ready(function () {
   var history = OSM.History(map);
 
   OSM.router = OSM.Router(map, {
-    "/":                           OSM.Index(map),
-    "/search":                     OSM.Search(map),
-    "/directions":                 OSM.Directions(map),
-    "/export":                     OSM.Export(map),
-    "/note/new":                   OSM.NewNote(map),
-    "/history/friends":            history,
-    "/history/nearby":             history,
-    "/history":                    history,
+    "/": OSM.Index(map),
+    "/search": OSM.Search(map),
+    "/directions": OSM.Directions(map),
+    "/export": OSM.Export(map),
+    "/note/new": OSM.NewNote(map),
+    "/history/friends": history,
+    "/history/nearby": history,
+    "/history": history,
     "/user/:display_name/history": history,
-    "/note/:id":                   OSM.Note(map),
-    "/node/:id(/history)":         OSM.Browse(map, 'node'),
-    "/way/:id(/history)":          OSM.Browse(map, 'way'),
-    "/relation/:id(/history)":     OSM.Browse(map, 'relation'),
-    "/changeset/:id":              OSM.Changeset(map),
-    "/query":                      OSM.Query(map)
+    "/note/:id": OSM.Note(map),
+    "/node/:id(/history)": OSM.Browse(map, "node"),
+    "/way/:id(/history)": OSM.Browse(map, "way"),
+    "/relation/:id(/history)": OSM.Browse(map, "relation"),
+    "/changeset/:id": OSM.Changeset(map),
+    "/query": OSM.Query(map)
   });
 
   if (OSM.preferred_editor === "remote" && document.location.pathname === "/edit") {
@@ -378,19 +383,23 @@ $(document).ready(function () {
 
   OSM.router.load();
 
-  $(document).on("click", "a", function(e) {
-    if (e.isDefaultPrevented() || e.isPropagationStopped())
+  $(document).on("click", "a", function (e) {
+    if (e.isDefaultPrevented() || e.isPropagationStopped()) {
       return;
+    }
 
     // Open links in a new tab as normal.
-    if (e.which > 1 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey)
+    if (e.which > 1 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
       return;
+    }
 
     // Ignore cross-protocol and cross-origin links.
-    if (location.protocol !== this.protocol || location.host !== this.host)
+    if (location.protocol !== this.protocol || location.host !== this.host) {
       return;
+    }
 
-    if (OSM.router.route(this.pathname + this.search + this.hash))
+    if (OSM.router.route(this.pathname + this.search + this.hash)) {
       e.preventDefault();
+    }
   });
 });
index 28a830858f2534168629fb1f86385b0d19285a69..6309444110a1206f7f22e57a2d54f02c3d5422ee 100644 (file)
@@ -26,17 +26,17 @@ OSM.initializeBrowse = function (map) {
     onSelect(e.layer);
   });
 
-  map.on('layeradd', function (e) {
+  map.on("layeradd", function (e) {
     if (e.layer === dataLayer) {
       map.on("moveend", updateData);
       updateData();
     }
   });
 
-  map.on('layerremove', function (e) {
+  map.on("layerremove", function (e) {
     if (e.layer === dataLayer) {
       map.off("moveend", updateData);
-      $('#browse_status').empty();
+      $("#browse_status").empty();
     }
   });
 
@@ -48,7 +48,7 @@ OSM.initializeBrowse = function (map) {
   }
 
   function displayFeatureWarning(count, limit, add, cancel) {
-    $('#browse_status').html(
+    $("#browse_status").html(
       $("<p class='warning'></p>")
         .text(I18n.t("browse.start_rjs.feature_warning", { num_features: count, max_features: limit }))
         .prepend(
@@ -56,7 +56,7 @@ OSM.initializeBrowse = function (map) {
             .click(cancel))
         .append(
           $("<input type='submit'>")
-            .val(I18n.t('browse.start_rjs.load_data'))
+            .val(I18n.t("browse.start_rjs.load_data"))
             .click(add)));
   }
 
@@ -92,13 +92,13 @@ OSM.initializeBrowse = function (map) {
         var features = dataLayer.buildFeatures(xml);
 
         function addFeatures() {
-          $('#browse_status').empty();
+          $("#browse_status").empty();
           dataLayer.addData(features);
           browseBounds = bounds;
         }
 
         function cancelAddFeatures() {
-          $('#browse_status').empty();
+          $("#browse_status").empty();
         }
 
         if (features.length < maxFeatures) {
@@ -120,9 +120,9 @@ OSM.initializeBrowse = function (map) {
 
     // Redraw in selected style
     layer.originalStyle = layer.options;
-    layer.setStyle({color: '#0000ff', weight: 8});
+    layer.setStyle({ color: "#0000ff", weight: 8 });
 
-    OSM.router.route('/' + layer.feature.type + '/' + layer.feature.id);
+    OSM.router.route("/" + layer.feature.type + "/" + layer.feature.id);
 
     // Stash the currently drawn feature
     selectedLayer = layer;
index fa9e1874d92e86fa26d005b1636fce64f1542c37..9e38917afeda29892b0ebcfa4df68c172234ceeb 100644 (file)
@@ -1,23 +1,22 @@
 OSM.Changeset = function (map) {
   var page = {},
-    content = $('#sidebar_content'),
-    currentChangesetId;
+      content = $("#sidebar_content"),
+      currentChangesetId;
 
-  page.pushstate = page.popstate = function(path, id) {
-    OSM.loadSidebarContent(path, function() {
+  page.pushstate = page.popstate = function (path, id) {
+    OSM.loadSidebarContent(path, function () {
       page.load(path, id);
     });
   };
 
-  page.load = function(path, id) {
-    if(id)
-      currentChangesetId = id;
+  page.load = function (path, id) {
+    if (id) currentChangesetId = id;
     initialize();
     addChangeset(currentChangesetId, true);
   };
 
   function addChangeset(id, center) {
-    map.addObject({type: 'changeset', id: parseInt(id)}, function(bounds) {
+    map.addObject({ type: "changeset", id: parseInt(id, 10) }, function (bounds) {
       if (!window.location.hash && bounds.isValid() &&
           (center || !map.getBounds().contains(bounds))) {
         OSM.router.withoutMoveListener(function () {
@@ -32,8 +31,8 @@ OSM.Changeset = function (map) {
 
     $(form).find("input[type=submit]").prop("disabled", true);
 
-    if(include_data) {
-      data = {text: $(form.text).val()};
+    if (include_data) {
+      data = { text: $(form.text).val() };
     } else {
       data = {};
     }
@@ -72,10 +71,10 @@ OSM.Changeset = function (map) {
       }
     });
 
-    content.find("textarea").val('').trigger("input");
+    content.find("textarea").val("").trigger("input");
   }
 
-  page.unload = function() {
+  page.unload = function () {
     map.removeObject();
   };
 
index 1ee703e604579d01444a880ec12d7e5f26dcc9be..fdde8dec470d7e487f2f0cf05ee81661c61f67d3 100644 (file)
@@ -1,4 +1,8 @@
+//= require querystring
+
 OSM.initializeContextMenu = function (map) {
+  var querystring = require("querystring-component");
+
   map.contextmenu.addItem({
     text: I18n.t("javascripts.context.directions_from"),
     callback: function directionsFromHere(e) {
@@ -49,7 +53,7 @@ OSM.initializeContextMenu = function (map) {
           lat = latlng.lat.toFixed(precision),
           lng = latlng.lng.toFixed(precision);
 
-      OSM.router.route("/search?query=" + encodeURIComponent(lat + "," + lng));
+      OSM.router.route("/search?whereami=1&query=" + encodeURIComponent(lat + "," + lng));
     }
   });
 
@@ -77,7 +81,7 @@ OSM.initializeContextMenu = function (map) {
     else map.contextmenu.enable();
   });
 
-  var updateMenu = function updateMenu () {
+  var updateMenu = function updateMenu() {
     map.contextmenu.setDisabled(2, map.getZoom() < 12);
     map.contextmenu.setDisabled(4, map.getZoom() < 14);
   };
index 8a80328cc05c3767813ac7ff3823330001095d9e..4c39d6781e1673d61d3e7c28aa186bb509acd464 100644 (file)
@@ -1,21 +1,24 @@
 //= require_self
 //= require_tree ./directions
+//= require querystring
 
 OSM.Directions = function (map) {
+  var querystring = require("querystring-component");
+
   var awaitingGeocode; // true if the user has requested a route, but we're waiting on a geocode result
-  var awaitingRoute;   // true if we've asked the engine for a route and are waiting to hear back
+  var awaitingRoute; // true if we've asked the engine for a route and are waiting to hear back
   var chosenEngine;
 
-  var popup = L.popup({autoPanPadding: [100, 100]});
+  var popup = L.popup({ autoPanPadding: [100, 100] });
 
   var polyline = L.polyline([], {
-    color: '#03f',
+    color: "#03f",
     opacity: 0.3,
     weight: 10
   });
 
   var highlight = L.polyline([], {
-    color: '#ff0',
+    color: "#ff0",
     opacity: 0.5,
     weight: 12
   });
@@ -28,6 +31,20 @@ OSM.Directions = function (map) {
   var expiry = new Date();
   expiry.setYear(expiry.getFullYear() + 10);
 
+  var engines = OSM.Directions.engines;
+
+  engines.sort(function (a, b) {
+    var localised_a = I18n.t("javascripts.directions.engines." + a.id),
+        localised_b = I18n.t("javascripts.directions.engines." + b.id);
+    return localised_a.localeCompare(localised_b);
+  });
+
+  var select = $("select.routing_engines");
+
+  engines.forEach(function (engine, i) {
+    select.append("<option value='" + i + "'>" + I18n.t("javascripts.directions.engines." + engine.id) + "</option>");
+  });
+
   function Endpoint(input, iconUrl) {
     var endpoint = {};
 
@@ -44,8 +61,8 @@ OSM.Directions = function (map) {
       autoPan: true
     });
 
-    endpoint.marker.on('drag dragend', function (e) {
-      var dragging = (e.type === 'drag');
+    endpoint.marker.on("drag dragend", function (e) {
+      var dragging = (e.type === "drag");
       if (dragging && !chosenEngine.draggable) return;
       if (dragging && awaitingRoute) return;
       endpoint.setLatLng(e.target.getLatLng());
@@ -54,19 +71,19 @@ OSM.Directions = function (map) {
       }
     });
 
-    input.on("keydown", function() {
+    input.on("keydown", function () {
       input.removeClass("error");
     });
 
     input.on("change", function (e) {
       awaitingGeocode = true;
-      
+
       // make text the same in both text boxes
       var value = e.target.value;
       endpoint.setValue(value);
     });
 
-    endpoint.setValue = function(value, latlng) {
+    endpoint.setValue = function (value, latlng) {
       endpoint.value = value;
       delete endpoint.latlng;
       input.removeClass("error");
@@ -79,7 +96,7 @@ OSM.Directions = function (map) {
       }
     };
 
-    endpoint.getGeocode = function() {
+    endpoint.getGeocode = function () {
       // if no one has entered a value yet, then we can't geocode, so don't
       // even try.
       if (!endpoint.value) {
@@ -88,12 +105,14 @@ OSM.Directions = function (map) {
 
       endpoint.awaitingGeocode = true;
 
-      $.getJSON(OSM.NOMINATIM_URL + 'search?q=' + encodeURIComponent(endpoint.value) + '&format=json', function (json) {
+      var viewbox = map.getBounds().toBBoxString(); // <sw lon>,<sw lat>,<ne lon>,<ne lat>
+
+      $.getJSON(OSM.NOMINATIM_URL + "search?q=" + encodeURIComponent(endpoint.value) + "&format=json&viewbox=" + viewbox, function (json) {
         endpoint.awaitingGeocode = false;
         endpoint.hasGeocode = true;
         if (json.length === 0) {
           input.addClass("error");
-          alert(I18n.t('javascripts.directions.errors.no_place', {place: endpoint.value}));
+          alert(I18n.t("javascripts.directions.errors.no_place", { place: endpoint.value }));
           return;
         }
 
@@ -121,7 +140,7 @@ OSM.Directions = function (map) {
     return endpoint;
   }
 
-  $(".directions_form .reverse_directions").on("click", function() {
+  $(".directions_form .reverse_directions").on("click", function () {
     var from = endpoints[0].latlng,
         to = endpoints[1].latlng;
 
@@ -132,7 +151,7 @@ OSM.Directions = function (map) {
     }));
   });
 
-  $(".directions_form .close").on("click", function(e) {
+  $(".directions_form .close").on("click", function (e) {
     e.preventDefault();
     var route_from = endpoints[0].value;
     if (route_from) {
@@ -156,18 +175,20 @@ OSM.Directions = function (map) {
     var m = Math.round(s / 60);
     var h = Math.floor(m / 60);
     m -= h * 60;
-    return h + ":" + (m < 10 ? '0' : '') + m;
+    return h + ":" + (m < 10 ? "0" : "") + m;
   }
 
-  function setEngine(id) {
-    engines.forEach(function(engine, i) {
-      if (engine.id === id) {
-        chosenEngine = engine;
-        select.val(i);
-      }
+  function findEngine(id) {
+    return engines.findIndex(function (engine) {
+      return engine.id === id;
     });
   }
 
+  function setEngine(index) {
+    chosenEngine = engines[index];
+    select.val(index);
+  }
+
   function getRoute(fitRoute, reportErrors) {
     // Cancel any route that is already in progress
     if (awaitingRoute) awaitingRoute.abort();
@@ -196,14 +217,14 @@ OSM.Directions = function (map) {
 
     OSM.router.replace("/directions?" + querystring.stringify({
       engine: chosenEngine.id,
-      route: o.lat.toFixed(precision) + ',' + o.lng.toFixed(precision) + ';' +
-             d.lat.toFixed(precision) + ',' + d.lng.toFixed(precision)
+      route: o.lat.toFixed(precision) + "," + o.lng.toFixed(precision) + ";" +
+             d.lat.toFixed(precision) + "," + d.lng.toFixed(precision)
     }));
 
     // copy loading item to sidebar and display it. we copy it, rather than
     // just using it in-place and replacing it in case it has to be used
     // again.
-    $('#sidebar_content').html($('.directions_form .loader_copy').html());
+    $("#sidebar_content").html($(".directions_form .loader_copy").html());
     map.setSidebarOverlaid(false);
 
     awaitingRoute = chosenEngine.getRoute([o, d], function (err, route) {
@@ -213,7 +234,7 @@ OSM.Directions = function (map) {
         map.removeLayer(polyline);
 
         if (reportErrors) {
-          $('#sidebar_content').html('<p class="search_results_error">' + I18n.t('javascripts.directions.errors.no_route') + '</p>');
+          $("#sidebar_content").html("<p class=\"search_results_error\">" + I18n.t("javascripts.directions.errors.no_route") + "</p>");
         }
 
         return;
@@ -227,42 +248,39 @@ OSM.Directions = function (map) {
         map.fitBounds(polyline.getBounds().pad(0.05));
       }
 
-      var html = '<h2><a class="geolink" href="#">' +
-        '<span class="icon close"></span></a>' + I18n.t('javascripts.directions.directions') +
-        '</h2><p id="routing_summary">' +
-        I18n.t('javascripts.directions.distance') + ': ' + formatDistance(route.distance) + '. ' +
-        I18n.t('javascripts.directions.time') + ': ' + formatTime(route.time) + '.';
-      if (typeof route.ascend !== 'undefined' && typeof route.descend !== 'undefined') {
-        html += '<br />' +
-          I18n.t('javascripts.directions.ascend') + ': ' + Math.round(route.ascend) + 'm. ' +
-          I18n.t('javascripts.directions.descend') + ': ' + Math.round(route.descend) +'m.';
+      var html = "<h2><a class=\"geolink\" href=\"#\">" +
+        "<span class=\"icon close\"></span></a>" + I18n.t("javascripts.directions.directions") +
+        "</h2><p id=\"routing_summary\">" +
+        I18n.t("javascripts.directions.distance") + ": " + formatDistance(route.distance) + ". " +
+        I18n.t("javascripts.directions.time") + ": " + formatTime(route.time) + ".";
+      if (typeof route.ascend !== "undefined" && typeof route.descend !== "undefined") {
+        html += "<br />" +
+          I18n.t("javascripts.directions.ascend") + ": " + Math.round(route.ascend) + "m. " +
+          I18n.t("javascripts.directions.descend") + ": " + Math.round(route.descend) + "m.";
       }
-      html += '</p><table id="turnbyturn" />';
+      html += "</p><table id=\"turnbyturn\" />";
 
-      $('#sidebar_content')
+      $("#sidebar_content")
         .html(html);
 
       // Add each row
-      var cumulative = 0;
       route.steps.forEach(function (step) {
-        var ll        = step[0],
-          direction   = step[1],
-          instruction = step[2],
-          dist        = step[3],
-          lineseg     = step[4];
-
-        cumulative += dist;
+        var ll = step[0],
+            direction = step[1],
+            instruction = step[2],
+            dist = step[3],
+            lineseg = step[4];
 
         if (dist < 5) {
           dist = "";
         } else if (dist < 200) {
-          dist = Math.round(dist / 10) * 10 + "m";
+          dist = String(Math.round(dist / 10) * 10) + "m";
         } else if (dist < 1500) {
-          dist = Math.round(dist / 100) * 100 + "m";
+          dist = String(Math.round(dist / 100) * 100) + "m";
         } else if (dist < 5000) {
-          dist = Math.round(dist / 100) / 10 + "km";
+          dist = String(Math.round(dist / 100) / 10) + "km";
         } else {
-          dist = Math.round(dist / 1000) + "km";
+          dist = String(Math.round(dist / 1000)) + "km";
         }
 
         var row = $("<tr class='turn'/>");
@@ -270,7 +288,7 @@ OSM.Directions = function (map) {
         row.append("<td class='instruction'>" + instruction);
         row.append("<td class='distance'>" + dist);
 
-        row.on('click', function () {
+        row.on("click", function () {
           popup
             .setLatLng(ll)
             .setContent("<p>" + instruction + "</p>")
@@ -285,61 +303,47 @@ OSM.Directions = function (map) {
           map.removeLayer(highlight);
         });
 
-        $('#turnbyturn').append(row);
+        $("#turnbyturn").append(row);
       });
 
-      $('#sidebar_content').append('<p id="routing_credit">' +
-        I18n.t('javascripts.directions.instructions.courtesy', {link: chosenEngine.creditline}) +
-        '</p>');
+      $("#sidebar_content").append("<p id=\"routing_credit\">" +
+        I18n.t("javascripts.directions.instructions.courtesy", { link: chosenEngine.creditline }) +
+        "</p>");
 
-      $('#sidebar_content a.geolink').on('click', function(e) {
+      $("#sidebar_content a.geolink").on("click", function (e) {
         e.preventDefault();
         map.removeLayer(polyline);
-        $('#sidebar_content').html('');
+        $("#sidebar_content").html("");
         map.setSidebarOverlaid(true);
         // TODO: collapse width of sidebar back to previous
       });
     });
   }
 
-  var engines = OSM.Directions.engines;
-
-  engines.sort(function (a, b) {
-    a = I18n.t('javascripts.directions.engines.' + a.id);
-    b = I18n.t('javascripts.directions.engines.' + b.id);
-    return a.localeCompare(b);
-  });
-
-  var select = $('select.routing_engines');
-
-  engines.forEach(function(engine, i) {
-    select.append("<option value='" + i + "'>" + I18n.t('javascripts.directions.engines.' + engine.id) + "</option>");
-  });
-
-  var chosenEngineId = $.cookie('_osm_directions_engine');
-  if(!chosenEngineId) {
-    chosenEngineId = 'osrm_car';
+  var chosenEngineIndex = findEngine("fossgis_osrm_car");
+  if ($.cookie("_osm_directions_engine")) {
+    chosenEngineIndex = findEngine($.cookie("_osm_directions_engine"));
   }
-  setEngine(chosenEngineId);
+  setEngine(chosenEngineIndex);
 
   select.on("change", function (e) {
     chosenEngine = engines[e.target.selectedIndex];
-    $.cookie('_osm_directions_engine', chosenEngine.id, { expires: expiry, path: '/' });
+    $.cookie("_osm_directions_engine", chosenEngine.id, { expires: expiry, path: "/" });
     if (map.hasLayer(polyline)) {
       getRoute(true, true);
     }
   });
 
-  $(".directions_form").on("submit", function(e) {
+  $(".directions_form").on("submit", function (e) {
     e.preventDefault();
     getRoute(true, true);
   });
 
-  $(".routing_marker").on('dragstart', function (e) {
+  $(".routing_marker").on("dragstart", function (e) {
     var dt = e.originalEvent.dataTransfer;
-    dt.effectAllowed = 'move';
-    var dragData = { type: $(this).data('type') };
-    dt.setData('text', JSON.stringify(dragData));
+    dt.effectAllowed = "move";
+    var dragData = { type: $(this).data("type") };
+    dt.setData("text", JSON.stringify(dragData));
     if (dt.setDragImage) {
       var img = $("<img>").attr("src", $(e.originalEvent.target).attr("src"));
       dt.setDragImage(img.get(0), 12, 21);
@@ -348,33 +352,37 @@ OSM.Directions = function (map) {
 
   var page = {};
 
-  page.pushstate = page.popstate = function() {
+  page.pushstate = page.popstate = function () {
     $(".search_form").hide();
     $(".directions_form").show();
 
-    $("#map").on('dragend dragover', function (e) {
+    $("#map").on("dragend dragover", function (e) {
       e.preventDefault();
     });
 
-    $("#map").on('drop', function (e) {
+    $("#map").on("drop", function (e) {
       e.preventDefault();
       var oe = e.originalEvent;
-      var dragData = JSON.parse(oe.dataTransfer.getData('text'));
+      var dragData = JSON.parse(oe.dataTransfer.getData("text"));
       var type = dragData.type;
-      var pt = L.DomEvent.getMousePosition(oe, map.getContainer());  // co-ordinates of the mouse pointer at present
+      var pt = L.DomEvent.getMousePosition(oe, map.getContainer()); // co-ordinates of the mouse pointer at present
       pt.y += 20;
       var ll = map.containerPointToLatLng(pt);
-      endpoints[type === 'from' ? 0 : 1].setLatLng(ll);
+      endpoints[type === "from" ? 0 : 1].setLatLng(ll);
       getRoute(true, true);
     });
 
     var params = querystring.parse(location.search.substring(1)),
-        route = (params.route || '').split(';'),
-        from = route[0] && L.latLng(route[0].split(',')),
-        to = route[1] && L.latLng(route[1].split(','));
+        route = (params.route || "").split(";"),
+        from = route[0] && L.latLng(route[0].split(",")),
+        to = route[1] && L.latLng(route[1].split(","));
 
     if (params.engine) {
-      setEngine(params.engine);
+      var engineIndex = findEngine(params.engine);
+
+      if (engineIndex >= 0) {
+        setEngine(engineIndex);
+      }
     }
 
     endpoints[0].setValue(params.from || "", from);
@@ -385,14 +393,14 @@ OSM.Directions = function (map) {
     getRoute(true, true);
   };
 
-  page.load = function() {
+  page.load = function () {
     page.pushstate();
   };
 
-  page.unload = function() {
+  page.unload = function () {
     $(".search_form").show();
     $(".directions_form").hide();
-    $("#map").off('dragend dragover drop');
+    $("#map").off("dragend dragover drop");
 
     map
       .removeLayer(popup)
diff --git a/app/assets/javascripts/index/directions/fossgis.js b/app/assets/javascripts/index/directions/fossgis.js
new file mode 100644 (file)
index 0000000..8e5e8e6
--- /dev/null
@@ -0,0 +1,213 @@
+// FOSSGIS engine (OSRM based)
+// Doesn't yet support hints
+
+function FOSSGISEngine(id, vehicleType) {
+  var cachedHints = [];
+
+  return {
+    id: id,
+    creditline: "<a href=\"https://routing.openstreetmap.de/about.html\" target=\"_blank\">FOSSGIS Routing Service</a>",
+    draggable: true,
+
+    _transformSteps: function (input_steps, line) {
+      var INSTRUCTION_TEMPLATE = {
+        "continue": "javascripts.directions.instructions.continue",
+        "merge right": "javascripts.directions.instructions.merge_right",
+        "merge left": "javascripts.directions.instructions.merge_left",
+        "off ramp right": "javascripts.directions.instructions.offramp_right",
+        "off ramp left": "javascripts.directions.instructions.offramp_left",
+        "on ramp right": "javascripts.directions.instructions.onramp_right",
+        "on ramp left": "javascripts.directions.instructions.onramp_left",
+        "fork right": "javascripts.directions.instructions.fork_right",
+        "fork left": "javascripts.directions.instructions.fork_left",
+        "end of road right": "javascripts.directions.instructions.endofroad_right",
+        "end of road left": "javascripts.directions.instructions.endofroad_left",
+        "turn straight": "javascripts.directions.instructions.continue",
+        "turn slight right": "javascripts.directions.instructions.slight_right",
+        "turn right": "javascripts.directions.instructions.turn_right",
+        "turn sharp right": "javascripts.directions.instructions.sharp_right",
+        "turn uturn": "javascripts.directions.instructions.uturn",
+        "turn sharp left": "javascripts.directions.instructions.sharp_left",
+        "turn left": "javascripts.directions.instructions.turn_left",
+        "turn slight left": "javascripts.directions.instructions.slight_left",
+        "roundabout": "javascripts.directions.instructions.roundabout",
+        "rotary": "javascripts.directions.instructions.roundabout",
+        "exit roundabout": "javascripts.directions.instructions.exit_roundabout",
+        "exit rotary": "javascripts.directions.instructions.exit_roundabout",
+        "depart": "javascripts.directions.instructions.start",
+        "arrive": "javascripts.directions.instructions.destination"
+      };
+      var ICON_MAP = {
+        "continue": 0,
+        "merge right": 21,
+        "merge left": 20,
+        "off ramp right": 24,
+        "off ramp left": 25,
+        "on ramp right": 2,
+        "on ramp left": 6,
+        "fork right": 18,
+        "fork left": 19,
+        "end of road right": 22,
+        "end of road left": 23,
+        "turn straight": 0,
+        "turn slight right": 1,
+        "turn right": 2,
+        "turn sharp right": 3,
+        "turn uturn": 4,
+        "turn slight left": 5,
+        "turn left": 6,
+        "turn sharp left": 7,
+        "roundabout": 10,
+        "rotary": 10,
+        "exit roundabout": 10,
+        "exit rotary": 10,
+        "depart": 8,
+        "arrive": 14
+      };
+      var numToWord = function (num) {
+        return ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth"][num - 1];
+      };
+      var transformed_steps = input_steps.map(function (step, idx) {
+        var maneuver_id;
+
+        // special case handling
+        switch (step.maneuver.type) {
+          case "on ramp":
+          case "off ramp":
+          case "merge":
+          case "end of road":
+          case "fork":
+            maneuver_id = step.maneuver.type + " " + (step.maneuver.modifier.indexOf("left") >= 0 ? "left" : "right");
+            break;
+          case "depart":
+          case "arrive":
+          case "roundabout":
+          case "rotary":
+          case "exit roundabout":
+          case "exit rotary":
+            maneuver_id = step.maneuver.type;
+            break;
+          case "roundabout turn":
+          case "turn":
+            maneuver_id = "turn " + step.maneuver.modifier;
+            break;
+          // for unknown types the fallback is turn
+          default:
+            maneuver_id = "turn " + step.maneuver.modifier;
+            break;
+        }
+        var template = INSTRUCTION_TEMPLATE[maneuver_id];
+
+        // convert lat,lng pairs to LatLng objects
+        var step_geometry = L.PolylineUtil.decode(step.geometry, { precision: 5 }).map(function (a) { return L.latLng(a); });
+        // append step_geometry on line
+        Array.prototype.push.apply(line, step_geometry);
+
+        var instText = "<b>" + (idx + 1) + ".</b> ";
+        var destinations = "<b>" + step.destinations + "</b>";
+        var namedRoad = true;
+        var name;
+
+        if (step.name && step.ref) {
+          name = "<b>" + step.name + " (" + step.ref + ")</b>";
+        } else if (step.name) {
+          name = "<b>" + step.name + "</b>";
+        } else if (step.ref) {
+          name = "<b>" + step.ref + "</b>";
+        } else {
+          name = I18n.t("javascripts.directions.instructions.unnamed");
+          namedRoad = false;
+        }
+
+        if (step.maneuver.type.match(/^exit (rotary|roundabout)$/)) {
+          instText += I18n.t(template, { name: name });
+        } else if (step.maneuver.type.match(/^(rotary|roundabout)$/)) {
+          if (step.maneuver.exit) {
+            if (step.maneuver.exit <= 10) {
+              instText += I18n.t(template + "_with_exit_ordinal", { exit: I18n.t("javascripts.directions.instructions.exit_counts." + numToWord(step.maneuver.exit)), name: name });
+            } else {
+              instText += I18n.t(template + "_with_exit", { exit: step.maneuver.exit, name: name });
+            }
+          } else {
+            instText += I18n.t(template + "_without_exit", { name: name });
+          }
+        } else if (step.maneuver.type.match(/^(on ramp|off ramp)$/)) {
+          var params = {};
+          if (step.exits && step.maneuver.type.match(/^(off ramp)$/)) params.exit = step.exits;
+          if (step.destinations) params.directions = destinations;
+          if (namedRoad) params.directions = name;
+          if (Object.keys(params).length > 0) {
+            template = template + "_with_" + Object.keys(params).join("_");
+          }
+          instText += I18n.t(template, params);
+        } else {
+          instText += I18n.t(template + "_without_exit", { name: name });
+        }
+        return [[step.maneuver.location[1], step.maneuver.location[0]], ICON_MAP[maneuver_id], instText, step.distance, step_geometry];
+      });
+
+      return transformed_steps;
+    },
+
+    getRoute: function (points, callback) {
+      var params = [
+        { name: "overview", value: "false" },
+        { name: "geometries", value: "polyline" },
+        { name: "steps", value: true }
+      ];
+
+
+      if (cachedHints.length === points.length) {
+        params.push({ name: "hints", value: cachedHints.join(";") });
+      } else {
+        // invalidate cache
+        cachedHints = [];
+      }
+
+      var encoded_coords = points.map(function (p) {
+        return p.lng + "," + p.lat;
+      }).join(";");
+
+      var req_url = OSM.FOSSGIS_OSRM_URL + "routed-" + vehicleType + "/route/v1/driving/" + encoded_coords;
+
+      var onResponse = function (data) {
+        if (data.code !== "Ok") {
+          return callback(true);
+        }
+
+        cachedHints = data.waypoints.map(function (wp) {
+          return wp.hint;
+        });
+
+        var line = [];
+        var transformLeg = function (leg) {
+          return this._transformSteps(leg.steps, line);
+        };
+
+        var steps = [].concat.apply([], data.routes[0].legs.map(transformLeg.bind(this)));
+
+        callback(false, {
+          line: line,
+          steps: steps,
+          distance: data.routes[0].distance,
+          time: data.routes[0].duration
+        });
+      };
+
+      return $.ajax({
+        url: req_url,
+        data: params,
+        dataType: "json",
+        success: onResponse.bind(this),
+        error: function () {
+          callback(true);
+        }
+      });
+    }
+  };
+}
+
+OSM.Directions.addEngine(new FOSSGISEngine("fossgis_osrm_car", "car"), true);
+OSM.Directions.addEngine(new FOSSGISEngine("fossgis_osrm_bike", "bike"), true);
+OSM.Directions.addEngine(new FOSSGISEngine("fossgis_osrm_foot", "foot"), true);
+
index ce568409d5052628aa8532b148ab56354ca88849..6bd430c06021612ccb086a8b58b6c14f97a9d6af 100644 (file)
@@ -3,18 +3,18 @@ function GraphHopperEngine(id, vehicleType) {
     "-3": 7, // sharp left
     "-2": 6, // left
     "-1": 5, // slight left
-    0: 0, // straight
-    1: 1, // slight right
-    2: 2, // right
-    3: 3, // sharp right
-    4: 14, // finish reached
-    5: 14, // via reached
-    6: 10 // roundabout
+    "0": 0, // straight
+    "1": 1, // slight right
+    "2": 2, // right
+    "3": 3, // sharp right
+    "4": 14, // finish reached
+    "5": 14, // via reached
+    "6": 10 // roundabout
   };
 
   return {
     id: id,
-    creditline: '<a href="https://www.graphhopper.com/" target="_blank">Graphhopper</a>',
+    creditline: "<a href=\"https://www.graphhopper.com/\" target=\"_blank\">Graphhopper</a>",
     draggable: false,
 
     getRoute: function (points, callback) {
@@ -23,19 +23,20 @@ function GraphHopperEngine(id, vehicleType) {
       return $.ajax({
         url: OSM.GRAPHHOPPER_URL,
         data: {
-          vehicle: vehicleType,
-          locale: I18n.currentLocale(),
-          key: "LijBPDQGfu7Iiq80w3HzwB4RUDJbMbhs6BU0dEnn",
+          "vehicle": vehicleType,
+          "locale": I18n.currentLocale(),
+          "key": "LijBPDQGfu7Iiq80w3HzwB4RUDJbMbhs6BU0dEnn",
           "ch.disable": vehicleType === "car",
-          elevation: false,
-          instructions: true,
-          point: points.map(function (p) { return p.lat + "," + p.lng; })
+          "elevation": false,
+          "instructions": true,
+          "point": points.map(function (p) { return p.lat + "," + p.lng; })
         },
         traditional: true,
         dataType: "json",
         success: function (data) {
-          if (!data.paths || data.paths.length === 0)
+          if (!data.paths || data.paths.length === 0) {
             return callback(true);
+          }
 
           var path = data.paths[0];
           var line = L.PolylineUtil.decode(path.points);
@@ -51,10 +52,10 @@ function GraphHopperEngine(id, vehicleType) {
             var distInMeter = instr.distance;
             var lineseg = [];
             for (var j = instr.interval[0]; j <= instr.interval[1]; j++) {
-              lineseg.push({lat: line[j][0], lng: line[j][1]});
+              lineseg.push({ lat: line[j][0], lng: line[j][1] });
             }
             steps.push([
-              {lat: latLng[0], lng: latLng[1]},
+              { lat: latLng[0], lng: latLng[1] },
               instrCode,
               instrText,
               distInMeter,
diff --git a/app/assets/javascripts/index/directions/mapquest.js b/app/assets/javascripts/index/directions/mapquest.js
deleted file mode 100644 (file)
index 739ce65..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-// For docs, see:
-// https://developer.mapquest.com/web/products/open/directions-service
-// https://open.mapquestapi.com/directions/
-// https://github.com/apmon/openstreetmap-website/blob/21edc353a4558006f0ce23f5ec3930be6a7d4c8b/app/controllers/routing_controller.rb#L153
-
-function MapQuestEngine(id, routeType) {
-  var MQ_SPRITE_MAP = {
-    0: 0, // straight
-    1: 1, // slight right
-    2: 2, // right
-    3: 3, // sharp right
-    4: 4, // reverse
-    5: 7, // sharp left
-    6: 6, // left
-    7: 5, // slight left
-    8: 4, // right U-turn
-    9: 4, // left U-turn
-    10: 21, // right merge
-    11: 20, // left merge
-    12: 21, // right on-ramp
-    13: 20, // left on-ramp
-    14: 24, // right off-ramp
-    15: 25, // left off-ramp
-    16: 18, // right fork
-    17: 19, // left fork
-    18: 0  // straight fork
-  };
-
-  return {
-    id: id,
-    creditline: '<a href="https://www.mapquest.com/" target="_blank">MapQuest</a> <img src="' + document.location.protocol + '//developer.mapquest.com/content/osm/mq_logo.png">',
-    draggable: false,
-
-    getRoute: function (points, callback) {
-      var from = points[0];
-      var to = points[points.length - 1];
-
-      return $.ajax({
-        url: OSM.MAPQUEST_DIRECTIONS_URL,
-        data: {
-          key: OSM.MAPQUEST_KEY,
-          from: from.lat + "," + from.lng,
-          to: to.lat + "," + to.lng,
-          routeType: routeType,
-          // locale: I18n.currentLocale(), //Doesn't actually work. MapQuest requires full locale e.g. "de_DE", but I18n may only provides language, e.g. "de"
-          manMaps: false,
-          shapeFormat: "raw",
-          generalize: 0,
-          unit: "k"
-        },
-        dataType: "jsonp",
-        success: function (data) {
-          if (data.info.statuscode !== 0)
-            return callback(true);
-
-          var i;
-          var line = [];
-          var shape = data.route.shape.shapePoints;
-          for (i = 0; i < shape.length; i += 2) {
-            line.push(L.latLng(shape[i], shape[i + 1]));
-          }
-
-          // data.route.shape.maneuverIndexes links turns to polyline positions
-          // data.route.legs[0].maneuvers is list of turns
-          var steps = [];
-          var mq = data.route.legs[0].maneuvers;
-          for (i = 0; i < mq.length; i++) {
-            var s = mq[i];
-            var d;
-            var linesegstart, linesegend, lineseg;
-            linesegstart = data.route.shape.maneuverIndexes[i];
-            if (i === mq.length - 1) {
-              d = 15;
-              linesegend = linesegstart + 1;
-            } else {
-              d = MQ_SPRITE_MAP[s.turnType];
-              linesegend = data.route.shape.maneuverIndexes[i + 1] + 1;
-            }
-            lineseg = [];
-            for (var j = linesegstart; j < linesegend; j++) {
-              lineseg.push(L.latLng(data.route.shape.shapePoints[j * 2], data.route.shape.shapePoints[j * 2 + 1]));
-            }
-            steps.push([L.latLng(s.startPoint.lat, s.startPoint.lng), d, s.narrative, s.distance * 1000, lineseg]);
-          }
-
-          callback(false, {
-            line: line,
-            steps: steps,
-            distance: data.route.distance * 1000,
-            time: data.route.time
-          });
-        },
-        error: function () {
-          callback(true);
-        }
-      });
-    }
-  };
-}
-
-if (OSM.MAPQUEST_KEY) {
-  OSM.Directions.addEngine(new MapQuestEngine("mapquest_bicycle", "bicycle"), true);
-  OSM.Directions.addEngine(new MapQuestEngine("mapquest_foot", "pedestrian"), true);
-  OSM.Directions.addEngine(new MapQuestEngine("mapquest_car", "fastest"), true);
-}
diff --git a/app/assets/javascripts/index/directions/osrm.js b/app/assets/javascripts/index/directions/osrm.js
deleted file mode 100644 (file)
index 81c62e1..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-// OSRM car engine
-// Doesn't yet support hints
-
-function OSRMEngine() {
-  var cachedHints = [];
-
-  return {
-    id: "osrm_car",
-    creditline: '<a href="http://project-osrm.org/" target="_blank">OSRM</a>',
-    draggable: true,
-
-    _transformSteps: function(input_steps, line) {
-      var INSTRUCTION_TEMPLATE = {
-        'continue': 'javascripts.directions.instructions.continue',
-        'merge right': 'javascripts.directions.instructions.merge_right',
-        'merge left': 'javascripts.directions.instructions.merge_left',
-        'off ramp right': 'javascripts.directions.instructions.offramp_right',
-        'off ramp left': 'javascripts.directions.instructions.offramp_left',
-        'on ramp right': 'javascripts.directions.instructions.onramp_right',
-        'on ramp left': 'javascripts.directions.instructions.onramp_left',
-        'fork right': 'javascripts.directions.instructions.fork_right',
-        'fork left': 'javascripts.directions.instructions.fork_left',
-        'end of road right': 'javascripts.directions.instructions.endofroad_right',
-        'end of road left': 'javascripts.directions.instructions.endofroad_left',
-        'turn straight': 'javascripts.directions.instructions.continue',
-        'turn slight right': 'javascripts.directions.instructions.slight_right',
-        'turn right': 'javascripts.directions.instructions.turn_right',
-        'turn sharp right': 'javascripts.directions.instructions.sharp_right',
-        'turn uturn': 'javascripts.directions.instructions.uturn',
-        'turn sharp left': 'javascripts.directions.instructions.sharp_left',
-        'turn left': 'javascripts.directions.instructions.turn_left',
-        'turn slight left': 'javascripts.directions.instructions.slight_left',
-        'roundabout': 'javascripts.directions.instructions.roundabout',
-        'rotary': 'javascripts.directions.instructions.roundabout',
-        'exit roundabout': 'javascripts.directions.instructions.exit_roundabout',
-        'exit rotary': 'javascripts.directions.instructions.exit_roundabout',
-        'depart': 'javascripts.directions.instructions.start',
-        'arrive': 'javascripts.directions.instructions.destination',
-      };
-      var ICON_MAP = {
-        'continue': 0,
-        'merge right': 21,
-        'merge left': 20,
-        'off ramp right': 24,
-        'off ramp left': 25,
-        'on ramp right': 2,
-        'on ramp left': 6,
-        'fork right': 18,
-        'fork left': 19,
-        'end of road right': 22,
-        'end of road left': 23,
-        'turn straight': 0,
-        'turn slight right': 1,
-        'turn right': 2,
-        'turn sharp right': 3,
-        'turn uturn': 4,
-        'turn slight left': 5,
-        'turn left': 6,
-        'turn sharp left': 7,
-        'roundabout': 10,
-        'rotary': 10,
-        'exit roundabout': 10,
-        'exit rotary': 10,
-        'depart': 8,
-        'arrive': 14
-      };
-      var numToWord = function(num) {
-        return ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth"][num-1];
-      };
-      var transformed_steps = input_steps.map(function(step, idx) {
-        var maneuver_id;
-
-        // special case handling
-        switch (step.maneuver.type) {
-          case 'on ramp':
-          case 'off ramp':
-          case 'merge':
-          case 'end of road':
-          case 'fork':
-            maneuver_id = step.maneuver.type + ' ' + (step.maneuver.modifier.indexOf('left') >= 0 ? 'left' : 'right');
-            break;
-          case 'depart':
-          case 'arrive':
-          case 'roundabout':
-          case 'rotary':
-          case 'exit roundabout':
-          case 'exit rotary':
-            maneuver_id = step.maneuver.type;
-            break;
-          case 'roundabout turn':
-          case 'turn':
-            maneuver_id = "turn " + step.maneuver.modifier;
-            break;
-          // for unknown types the fallback is turn
-          default:
-            maneuver_id = "turn " + step.maneuver.modifier;
-            break;
-        }
-        var template = INSTRUCTION_TEMPLATE[maneuver_id];
-
-        // convert lat,lng pairs to LatLng objects
-        var step_geometry = L.PolylineUtil.decode(step.geometry, { precision: 5 }).map(function(a) { return L.latLng(a); }) ;
-        // append step_geometry on line
-        Array.prototype.push.apply(line, step_geometry);
-
-        var instText = "<b>" + (idx + 1) + ".</b> ";
-        var destinations = "<b>" + step.destinations + "</b>";
-        var namedRoad = true;
-        var name;
-
-        if (step.name && step.ref) {
-          name = "<b>" + step.name + " (" + step.ref + ")</b>";
-        } else if (step.name) {
-          name = "<b>" + step.name + "</b>";
-        } else if (step.ref) {
-          name = "<b>" + step.ref + "</b>";
-        } else {
-          name = I18n.t('javascripts.directions.instructions.unnamed');
-          namedRoad = false;
-        }
-
-        if (step.maneuver.type.match(/exit (rotary|roundabout)/)) {
-          instText += I18n.t(template, { name: name });
-        } else if (step.maneuver.type.match(/rotary|roundabout/)) {
-          if (step.maneuver.exit) {
-            if (step.maneuver.exit <= 10) {
-              instText += I18n.t(template + '_with_exit_ordinal', { exit: I18n.t('javascripts.directions.instructions.exit_counts.' + numToWord(step.maneuver.exit)), name: name });
-            } else {
-              instText += I18n.t(template + '_with_exit', { exit: step.maneuver.exit, name: name });
-            }
-          } else {
-            instText += I18n.t(template + '_without_exit', { name: name });
-          }
-        } else if (step.maneuver.type.match(/on ramp|off ramp/)) {
-          var params = {};
-          if (step.exits && step.maneuver.type.match(/off ramp/)) params.exit = step.exits;
-          if (step.destinations) params.directions = destinations;
-          if (namedRoad) params.directions = name;
-          if (Object.keys(params).length > 0) {
-            template = template + "_with_" + Object.keys(params).join("_");
-          }
-          instText += I18n.t(template, params);
-        } else {
-          instText += I18n.t(template + '_without_exit', { name: name });
-        }
-        return [[step.maneuver.location[1], step.maneuver.location[0]], ICON_MAP[maneuver_id], instText, step.distance, step_geometry];
-      });
-
-      return transformed_steps;
-    },
-
-    getRoute: function (points, callback) {
-
-      var params = [
-        { name: "overview", value: "false" },
-        { name: "geometries", value: "polyline" },
-        { name: "steps", value: true }
-      ];
-
-
-      if (cachedHints.length === points.length) {
-        params.push({name: "hints", value: cachedHints.join(";")});
-      } else {
-        // invalidate cache
-        cachedHints = [];
-      }
-
-      var encoded_coords = points.map(function(p) {
-        return p.lng + ',' + p.lat;
-      }).join(';');
-
-      var req_url = OSM.OSRM_URL + encoded_coords;
-
-      var onResponse = function (data) {
-        if (data.code !== 'Ok')
-          return callback(true);
-
-        cachedHints = data.waypoints.map(function(wp) {
-          return wp.hint;
-        });
-
-        var line = [];
-        var transformLeg = function (leg) {
-          return this._transformSteps(leg.steps, line);
-        };
-
-        var steps = [].concat.apply([], data.routes[0].legs.map(transformLeg.bind(this)));
-
-        callback(false, {
-          line: line,
-          steps: steps,
-          distance: data.routes[0].distance,
-          time: data.routes[0].duration
-        });
-      };
-
-      return $.ajax({
-        url: req_url,
-        data: params,
-        dataType: "json",
-        success: onResponse.bind(this),
-        error: function () {
-          callback(true);
-        }
-      });
-    }
-  };
-}
-
-OSM.Directions.addEngine(new OSRMEngine(), true);
index 48e950b2137870f88e4aac912781cf3b94d17a70..b9050d8a12a01a95f5678841fc57c31c6aad8d10 100644 (file)
@@ -1,4 +1,4 @@
-OSM.Export = function(map) {
+OSM.Export = function (map) {
   var page = {};
 
   var locationFilter = new L.LocationFilter({
@@ -43,9 +43,9 @@ OSM.Export = function(map) {
     $("#maxlat").val(bounds.getNorth().toFixed(precision));
 
     $("#export_overpass").attr("href",
-        "https://overpass-api.de/api/map?bbox=" +
-        $("#minlon").val() + "," + $("#minlat").val() + "," +
-        $("#maxlon").val() + "," + $("#maxlat").val());
+                               "https://overpass-api.de/api/map?bbox=" +
+                               $("#minlon").val() + "," + $("#minlat").val() + "," +
+                               $("#maxlon").val() + "," + $("#maxlat").val());
   }
 
   function validateControls() {
@@ -57,12 +57,12 @@ OSM.Export = function(map) {
     if (getBounds().getSize() > OSM.MAX_REQUEST_AREA) e.preventDefault();
   }
 
-  page.pushstate = page.popstate = function(path) {
+  page.pushstate = page.popstate = function (path) {
     $("#export_tab").addClass("current");
     OSM.loadSidebarContent(path, page.load);
   };
 
-  page.load = function() {
+  page.load = function () {
     map
       .addLayer(locationFilter)
       .on("moveend", update);
@@ -75,7 +75,7 @@ OSM.Export = function(map) {
     return map.getState();
   };
 
-  page.unload = function() {
+  page.unload = function () {
     map
       .removeLayer(locationFilter)
       .off("moveend", update);
index d54928eb812c1ac8f8f54bf93b75f948e6365f1c..80fb68444f6469ee4e41e03d2f09654a337dfe12 100644 (file)
@@ -1,6 +1,6 @@
 //= require jquery.simulate
 
-OSM.History = function(map) {
+OSM.History = function (map) {
   var page = {};
 
   $("#sidebar_content")
@@ -13,13 +13,15 @@ OSM.History = function(map) {
     })
     .on("mousedown", "[data-changeset]", function () {
       var moved = false;
-      $(this).one("click", function (e) {
-        if (!moved && !$(e.target).is('a')) {
-          clickChangeset($(this).data("changeset").id, e);
-        }
-      }).one("mousemove", function () {
-        moved = true;
-      });
+      $(this)
+        .one("click", function (e) {
+          if (!moved && !$(e.target).is("a")) {
+            clickChangeset($(this).data("changeset").id, e);
+          }
+        })
+        .one("mousemove", function () {
+          moved = true;
+        });
     });
 
   var group = L.featureGroup()
@@ -33,17 +35,17 @@ OSM.History = function(map) {
       clickChangeset(e.layer.id, e);
     });
 
-  group.getLayerId = function(layer) {
+  group.getLayerId = function (layer) {
     return layer.id;
   };
 
   function highlightChangeset(id) {
-    group.getLayer(id).setStyle({fillOpacity: 0.3});
+    group.getLayer(id).setStyle({ fillOpacity: 0.3, color: "#FF6600", weight: 3 });
     $("#changeset_" + id).addClass("selected");
   }
 
   function unHighlightChangeset(id) {
-    group.getLayer(id).setStyle({fillOpacity: 0});
+    group.getLayer(id).setStyle({ fillOpacity: 0, color: "#FF9500", weight: 2 });
     $("#changeset_" + id).removeClass("selected");
   }
 
@@ -52,9 +54,9 @@ OSM.History = function(map) {
   }
 
   function update() {
-    var data = {list: '1'};
+    var data = { list: "1" };
 
-    if (window.location.pathname === '/history') {
+    if (window.location.pathname === "/history") {
       data.bbox = map.getBounds().wrap().toBBoxString();
     }
 
@@ -62,16 +64,16 @@ OSM.History = function(map) {
       url: window.location.pathname,
       method: "GET",
       data: data,
-      success: function(html) {
-        $('#sidebar_content .changesets').html(html);
+      success: function (html) {
+        $("#sidebar_content .changesets").html(html);
         updateMap();
       }
     });
 
-    var feedLink = $('link[type="application/atom+xml"]'),
-      feedHref = feedLink.attr('href').split('?')[0];
+    var feedLink = $("link[type=\"application/atom+xml\"]"),
+        feedHref = feedLink.attr("href").split("?")[0];
 
-    feedLink.attr('href', feedHref + '?bbox=' + data.bbox);
+    feedLink.attr("href", feedHref + "?bbox=" + data.bbox);
   }
 
   function loadMore(e) {
@@ -83,25 +85,36 @@ OSM.History = function(map) {
     $(this).hide();
     div.find(".loader").show();
 
-    $.get($(this).attr("href"), function(data) {
+    $.get($(this).attr("href"), function (data) {
       div.replaceWith(data);
       updateMap();
     });
   }
 
-  function updateMap() {
+  var changesets = [];
+
+  function updateBounds() {
     group.clearLayers();
 
-    var changesets = [];
+    changesets.forEach(function (changeset) {
+      var bottomLeft = map.project(L.latLng(changeset.bbox.minlat, changeset.bbox.minlon)),
+          topRight = map.project(L.latLng(changeset.bbox.maxlat, changeset.bbox.maxlon)),
+          width = topRight.x - bottomLeft.x,
+          height = bottomLeft.y - topRight.y,
+          minSize = 20; // Min width/height of changeset in pixels
+
+      if (width < minSize) {
+        bottomLeft.x -= ((minSize - width) / 2);
+        topRight.x += ((minSize - width) / 2);
+      }
 
-    $("[data-changeset]").each(function () {
-      var changeset = $(this).data('changeset');
-      if (changeset.bbox) {
-        changeset.bounds = L.latLngBounds(
-          [changeset.bbox.minlat, changeset.bbox.minlon],
-          [changeset.bbox.maxlat, changeset.bbox.maxlon]);
-        changesets.push(changeset);
+      if (height < minSize) {
+        bottomLeft.y += ((minSize - height) / 2);
+        topRight.y -= ((minSize - height) / 2);
       }
+
+      changeset.bounds = L.latLngBounds(map.unproject(bottomLeft),
+                                        map.unproject(topRight));
     });
 
     changesets.sort(function (a, b) {
@@ -110,34 +123,46 @@ OSM.History = function(map) {
 
     for (var i = 0; i < changesets.length; ++i) {
       var changeset = changesets[i],
-        rect = L.rectangle(changeset.bounds,
-          {weight: 2, color: "#FF9500", opacity: 1, fillColor: "#FFFFBF", fillOpacity: 0});
+          rect = L.rectangle(changeset.bounds,
+                             { weight: 2, color: "#FF9500", opacity: 1, fillColor: "#FFFFAF", fillOpacity: 0 });
       rect.id = changeset.id;
       rect.addTo(group);
     }
+  }
 
-    if (window.location.pathname !== '/history') {
+  function updateMap() {
+    changesets = $("[data-changeset]").map(function (index, element) {
+      return $(element).data("changeset");
+    }).get().filter(function (changeset) {
+      return changeset.bbox;
+    });
+
+    updateBounds();
+
+    if (window.location.pathname !== "/history") {
       var bounds = group.getBounds();
       if (bounds.isValid()) map.fitBounds(bounds);
     }
   }
 
-  page.pushstate = page.popstate = function(path) {
+  page.pushstate = page.popstate = function (path) {
     $("#history_tab").addClass("current");
     OSM.loadSidebarContent(path, page.load);
   };
 
-  page.load = function() {
+  page.load = function () {
     map.addLayer(group);
 
-    if (window.location.pathname === '/history') {
+    if (window.location.pathname === "/history") {
       map.on("moveend", update);
     }
 
+    map.on("zoomend", updateBounds);
+
     update();
   };
 
-  page.unload = function() {
+  page.unload = function () {
     map.removeLayer(group);
     map.off("moveend", update);
 
index 54c0b0db150ff25bb2c36a02b540b55cf612ba83..9d68ab65c8fc62b2a4eb2bb1147bb3f2742b0e31 100644 (file)
@@ -1,10 +1,14 @@
-OSM.NewNote = function(map) {
+//= require querystring
+
+OSM.NewNote = function (map) {
+  var querystring = require("querystring-component");
+
   var noteLayer = map.noteLayer,
-    content = $('#sidebar_content'),
-    page = {},
-    addNoteButton = $(".control-note .control-button"),
-    newNote,
-    halo;
+      content = $("#sidebar_content"),
+      page = {},
+      addNoteButton = $(".control-note .control-button"),
+      newNote,
+      halo;
 
   var noteIcons = {
     "new": L.icon({
@@ -28,9 +32,9 @@ OSM.NewNote = function(map) {
     e.preventDefault();
     e.stopPropagation();
 
-    if ($(this).hasClass('disabled')) return;
+    if ($(this).hasClass("disabled")) return;
 
-    OSM.router.route('/note/new');
+    OSM.router.route("/note/new");
   });
 
   function createNote(marker, form, url) {
@@ -61,7 +65,7 @@ OSM.NewNote = function(map) {
       newNote = null;
       noteLayer.removeLayer(marker);
       addNoteButton.removeClass("active");
-      OSM.router.route('/note/' + feature.properties.id);
+      OSM.router.route("/note/" + feature.properties.id);
     }
   }
 
@@ -83,7 +87,7 @@ OSM.NewNote = function(map) {
   };
 
   function newHalo(loc, a) {
-    if (a === 'dragstart' && map.hasLayer(halo)) {
+    if (a === "dragstart" && map.hasLayer(halo)) {
       map.removeLayer(halo);
     } else {
       if (map.hasLayer(halo)) map.removeLayer(halo);
@@ -107,40 +111,26 @@ OSM.NewNote = function(map) {
 
     map.addLayer(noteLayer);
 
-    var params = querystring.parse(path.substring(path.indexOf('?') + 1));
+    var params = querystring.parse(path.substring(path.indexOf("?") + 1));
     var markerLatlng;
 
     if (params.lat && params.lon) {
       markerLatlng = L.latLng(params.lat, params.lon);
-
-      var markerPosition = map.latLngToContainerPoint(markerLatlng),
-          mapSize = map.getSize(),
-          panBy = L.point(0, 0);
-
-      if (markerPosition.x < 50) {
-        panBy.x = markerPosition.x - 50;
-      } else if (markerPosition.x > mapSize.x - 50) {
-        panBy.x = 50 - mapSize.x + markerPosition.x;
-      }
-
-      if (markerPosition.y < 50) {
-        panBy.y = markerPosition.y - 50;
-      } else if (markerPosition.y > mapSize.y - 50) {
-        panBy.y = 50 - mapSize.y + markerPosition.y;
-      }
-
-      map.panBy(panBy);
     } else {
       markerLatlng = map.getCenter();
     }
 
+    map.panInside(markerLatlng, {
+      padding: [50, 50]
+    });
+
     newNote = L.marker(markerLatlng, {
-      icon: noteIcons["new"],
+      icon: noteIcons.new,
       opacity: 0.9,
       draggable: true
     });
 
-    newNote.on("dragstart dragend", function(a) {
+    newNote.on("dragstart dragend", function (a) {
       newHalo(newNote.getLatLng(), a.type);
     });
 
@@ -149,7 +139,7 @@ OSM.NewNote = function(map) {
 
     newNote.on("remove", function () {
       addNoteButton.removeClass("active");
-    }).on("dragstart",function () {
+    }).on("dragstart", function () {
       $(newNote).stopTime("removenote");
     }).on("dragend", function () {
       content.find("textarea").focus();
@@ -163,9 +153,9 @@ OSM.NewNote = function(map) {
       $(e.target.form.add).prop("disabled", $(e.target).val() === "");
     }
 
-    content.find('input[type=submit]').on('click', function (e) {
+    content.find("input[type=submit]").on("click", function (e) {
       e.preventDefault();
-      createNote(newNote, e.target.form, '/api/0.6/notes.json');
+      createNote(newNote, e.target.form, "/api/0.6/notes.json");
     });
 
     return map.getState();
index 3973420bdd3d3536682aa0b87b6720c65b7e9874..3793c573e6122d5165df17181e545e99701dd7d0 100644 (file)
@@ -1,7 +1,7 @@
 OSM.Note = function (map) {
-  var content = $('#sidebar_content'),
-    page = {},
-    halo, currentNote;
+  var content = $("#sidebar_content"),
+      page = {},
+      halo, currentNote;
 
   var noteIcons = {
     "new": L.icon({
@@ -28,7 +28,7 @@ OSM.Note = function (map) {
       url: url,
       type: method,
       oauth: true,
-      data: {text: $(form.text).val()},
+      data: { text: $(form.text).val() },
       success: function () {
         OSM.loadSidebarContent(window.location.pathname, page.load);
       }
@@ -36,16 +36,16 @@ OSM.Note = function (map) {
   }
 
   page.pushstate = page.popstate = function (path) {
-    OSM.loadSidebarContent(path, function() {
-      initialize(function() {
-        var data = $('.details').data(),
-          latLng = L.latLng(data.coordinates.split(','));
-        if (!map.getBounds().contains(latLng)) moveToNote();        
+    OSM.loadSidebarContent(path, function () {
+      initialize(function () {
+        var data = $(".details").data(),
+            latLng = L.latLng(data.coordinates.split(","));
+        if (!map.getBounds().contains(latLng)) moveToNote();
       });
     });
   };
 
-  page.load = function() {
+  page.load = function () {
     initialize(moveToNote);
   };
 
@@ -68,10 +68,10 @@ OSM.Note = function (map) {
       }
     });
 
-    content.find("textarea").val('').trigger("input");
+    content.find("textarea").val("").trigger("input");
 
-    var data = $('.details').data(),
-      latLng = L.latLng(data.coordinates.split(','));
+    var data = $(".details").data(),
+        latLng = L.latLng(data.coordinates.split(","));
 
     if (!map.hasLayer(halo)) {
       halo = L.circleMarker(latLng, {
@@ -96,12 +96,12 @@ OSM.Note = function (map) {
   }
 
   function moveToNote() {
-    var data = $('.details').data(),
-      latLng = L.latLng(data.coordinates.split(','));
+    var data = $(".details").data(),
+        latLng = L.latLng(data.coordinates.split(","));
 
     if (!window.location.hash || window.location.hash.match(/^#?c[0-9]+$/)) {
       OSM.router.withoutMoveListener(function () {
-        map.setView(latLng, 15, {reset: true});
+        map.setView(latLng, 15, { reset: true });
       });
     }
   }
index 9feee888c1daca1820ad5cb3baee03b6f30c27e8..5d553e970c4be49aa9a05f0c6984c1e0361429d3 100644 (file)
+++ b/