Update to iD v1.3.0
authorJohn Firebaugh <john.firebaugh@gmail.com>
Thu, 24 Oct 2013 16:11:57 +0000 (09:11 -0700)
committerJohn Firebaugh <john.firebaugh@gmail.com>
Thu, 24 Oct 2013 16:12:36 +0000 (09:12 -0700)
45 files changed:
vendor/assets/iD/iD.css.erb
vendor/assets/iD/iD.js
vendor/assets/iD/iD/img/sprite.svg
vendor/assets/iD/iD/locales/af.json
vendor/assets/iD/iD/locales/ar-AA.json [new file with mode: 0644]
vendor/assets/iD/iD/locales/ar.json
vendor/assets/iD/iD/locales/ast.json
vendor/assets/iD/iD/locales/bg-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/cs.json
vendor/assets/iD/iD/locales/da.json
vendor/assets/iD/iD/locales/de.json
vendor/assets/iD/iD/locales/el.json
vendor/assets/iD/iD/locales/en-GB.json
vendor/assets/iD/iD/locales/en.json
vendor/assets/iD/iD/locales/es.json
vendor/assets/iD/iD/locales/et.json
vendor/assets/iD/iD/locales/fa.json [new file with mode: 0644]
vendor/assets/iD/iD/locales/fi.json
vendor/assets/iD/iD/locales/fr.json
vendor/assets/iD/iD/locales/hr.json
vendor/assets/iD/iD/locales/hu.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/ko.json
vendor/assets/iD/iD/locales/lt.json
vendor/assets/iD/iD/locales/lv.json
vendor/assets/iD/iD/locales/nl.json
vendor/assets/iD/iD/locales/no.json
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/ru.json
vendor/assets/iD/iD/locales/sk.json
vendor/assets/iD/iD/locales/sr.json
vendor/assets/iD/iD/locales/sv.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/zh-TW.json
vendor/assets/iD/iD/locales/zh.json

index 44176cdf5633a9c487e4afa1ff2dea4ef9dcdc6f..a79d63b4b50666d6d6429a9478989e16ef25e196 100644 (file)
@@ -1396,7 +1396,6 @@ input[type=email] {
     width: 100%;
     border-radius:4px;
     text-overflow: ellipsis;
-    overflow: hidden;
     -webkit-transition: all 200ms;
        -moz-transition: all 200ms;
          -o-transition: all 200ms;
@@ -1464,17 +1463,11 @@ table.tags, table.tags td, table.tags th {
 
 ul li { list-style: none;}
 
-.toggle-list {
-    border-radius: 4px;
-    border: 1px solid #CCC;
-}
-
 .toggle-list > label {
     position: relative;
     padding: 5px 10px;
-    display:block;
+    display: block;
     height: 30px;
-    border-bottom: 1px solid #ccc;
     background-color: white;
     color: #7092FF;
     cursor: pointer;
@@ -1487,34 +1480,21 @@ ul li { list-style: none;}
     background-color: #ececec;
 }
 
-.toggle-list > label:first-child {
-    border-radius: 3px 3px 0 0;
+.toggle-list > label:not(:last-child) {
+    border-bottom: 1px solid #ccc;
 }
 
 .toggle-list > label:last-child {
     border-radius: 0 0 3px 3px;
-    border-bottom-width: 0;
 }
 
-.toggle-list > label:only-child {
-    border-radius: 3px;
-}
-
-.toggle-list label > span { 
+.toggle-list label > span {
     display: block;
     overflow: hidden;
     white-space: nowrap;
     text-overflow: ellipsis;
 }
 
-.toggle-list > label.remove span.icon {
-    display: block;
-    width: 14px;
-    float: left;
-    margin-right: 5px;
-    background-position: -204px 0;
-}
-
 .toggle-list > label.active {
     background: #E8EBFF;
 }
@@ -1781,6 +1761,7 @@ button.save.has-count .count::before {
 .icon.relation    { background-position: -520px 0;}
 .icon.relation.route         { background-position: -540px 0;}
 .icon.relation.multipolygon  { background-position: -560px 0;}
+.icon.vertex     { background-position: -580px 0;}
 
 .icon.inspect.light    { background-position: -220px -20px;}
 .icon.plus.light       { background-position: -240px -20px;}
@@ -1815,6 +1796,18 @@ button[disabled] .icon.layers     { background-position: -300px -40px;}
 button[disabled] .icon.avatar     { background-position: -320px -40px;}
 button[disabled] .icon.nearby     { background-position: -340px -40px;}
 
+.icon.point.deleted  { background-position: -302px -80px;}
+.icon.line.deleted   { background-position: -320px -80px;}
+.icon.area.deleted   { background-position: -340px -80px;}
+
+.icon.point.created  { background-position: -302px -100px;}
+.icon.line.created   { background-position: -320px -100px;}
+.icon.area.created   { background-position: -340px -100px;}
+
+.icon.point.modified  { background-position: -24px 0; }
+
+.icon.modified { opacity: .5; }
+
 /* Out link is special */
 
 .icon.out-link   { height: 14px; width: 14px; background-position: -500px 0;}
@@ -1959,6 +1952,10 @@ a:hover .icon.out-link   { background-position: -500px -14px;}
     top: 60px;
 }
 
+.selection-list-pane .inspector-body {
+    top: 60px;
+}
+
 .inspector-inner {
     padding: 20px;
     position: relative;
@@ -2104,6 +2101,15 @@ a:hover .icon.out-link   { background-position: -500px -14px;}
     height: 100%;
     border: 1px solid #CCC;
     border-radius: 0 3px 3px 0;
+    position: absolute;
+    top: 0;
+    right: 0;
+    width: 10%;
+    background: #fafafa;
+}
+
+.preset-list-item button.tag-reference-button .icon {
+    opacity: .5;
 }
 
 .current .preset-list-button,
@@ -2232,26 +2238,39 @@ a:hover .icon.out-link   { background-position: -500px -14px;}
     background: #f6f6f6;
     display: block;
     border-radius: 4px 4px 0 0;
+    overflow: hidden;
 }
 
-.form-label button {
-    border-left: 1px solid #CCC;
+.form-label-button-wrap {
+    position: absolute;
+    top: 0;
+    right: 0;
+    height: 100%;
+    width: 100%;
+    background: transparent;
+    text-align: right;
 }
 
-.form-label .modified-icon {
-    border-right: 0;
-    opacity: 0;
-    z-index: -10;
-    right: 10%;
+.form-label-button-wrap .icon {
+    opacity: .5;
 }
 
-.modified .form-label .modified-icon {
-    opacity: 1;
-    z-index: 1;
+.form-label button {
+    border-left: 1px solid #CCC;
+    width: 10%;
+    height: 100%;
+    border-radius: 0;
+    background: #fafafa;
 }
 
-.form-label button.tag-reference-button {
-    border-top-right-radius: 3px;
+.form-label .modified-icon,
+.form-field .remove-icon {
+    display: none;
+}
+
+.modified .form-label .modified-icon,
+.present .form-label .remove-icon {
+    display: inline-block;
 }
 
 .form-field > input,
@@ -2261,17 +2280,12 @@ a:hover .icon.out-link   { background-position: -500px -14px;}
     min-height: 30px;
     border-top: 0;
     border-radius: 0 0 4px 4px;
-    overflow: hidden;
 }
 
 .form-field textarea {
     height: 65px;
 }
 
-.form-field button.remove {
-    border-radius: 0 0 4px 0;
-}
-
 .inspector-border {
     border-bottom: 1px solid #CCC
 }
@@ -2294,7 +2308,7 @@ a:hover .icon.out-link   { background-position: -500px -14px;}
 .inspector-hidden,
 .inspector-hover label input[type="checkbox"],
 .inspector-hover label input[type="radio"],
-.inspector-hover .toggle-list label:not(.active),
+.inspector-hover .toggle-list label,
 .inspector-hover .toggle-list label span,
 .inspector-hover .inspector-inner .add-tag,
 .inspector-hover .inspector-inner .add-relation,
@@ -2309,13 +2323,14 @@ a:hover .icon.out-link   { background-position: -500px -14px;}
 }
 
 /* hide but preserve in layout */
-.inspector-hover .modified .form-label .modified-icon,
 .inspector-hover .entity-editor-pane button.minor,
-.inspector-hover .combobox-carat,
+.inspector-hover .combobox-caret,
 .inspector-hover .entity-editor-pane .header button,
 .inspector-hover .spin-control,
 .inspector-hover .hide-toggle:before,
 .inspector-hover .more-buttons,
+.inspector-hover .form-label-button-wrap,
+.inspector-hover .tag-reference-button,
 .inspector-hover .view-on-osm {
     opacity: 0;
 }
@@ -2403,9 +2418,8 @@ input,
             transition: opacity 200ms 200ms, width 200ms 200ms, margin-right 200ms 200ms;
 }
 
-.modified .form-label .modified-icon,
 .entity-editor-pane button.minor,
-.combobox-carat,
+.combobox-caret,
 .entity-editor-pane .header button,
 .toggle-list label span,
 .spin-control,
@@ -2634,7 +2648,7 @@ input[type=number] {
     padding-right: 10%;
 }
 
-.form-field .wiki-title ~ .combobox-carat {
+.form-field .wiki-title ~ .combobox-caret {
     margin-left: -18%;
     margin-right: 9%;
 }
@@ -2708,11 +2722,14 @@ input[type=number] {
 }
 
 .form-field .localized-wrap .entry .localized-value {
-    padding-right: 10%;
     border-top-width: 0;
     border-radius: 0 0 4px 4px;
 }
 
+.form-field .localized-wrap .form-label button {
+    border-top-right-radius: 3px;
+}
+
 /* Preset form address */
 
 .form-field .addr-housename {
@@ -2782,10 +2799,21 @@ div.combobox {
     border-top: 0;
 }
 
-.combobox-carat {
-    margin-left: -20px;
-    margin-right: 10px;
-    display:inline-block;
+.combobox-caret {
+    display: inline-block;
+    position: relative;
+    height: 30px;
+    width: 30px;
+    margin-left: -30px;
+    vertical-align: top;
+}
+
+.combobox-caret::after {
+    content:"";
+    height: 0; width: 0;
+    position: absolute;
+    left: 0; right: 0; bottom: 0; top: 0;
+    margin: auto;
     border-top: 5px solid #ccc;
     border-left: 5px solid transparent;
     border-right: 5px solid transparent;
@@ -2871,6 +2899,10 @@ div.combobox {
 
 .tag-row .tag-reference-button {
     right: 0;
+    border-radius: 0;
+    width: 10%;
+    top: 0;
+    background: #fafafa;
 }
 
 /* Adding form fields to tag editor */
@@ -2978,6 +3010,10 @@ img.wiki-image {
     padding-left: 10px;
 }
 
+.member-incomplete .member-delete {
+    display: none;
+}
+
 .member-row-new .member-entity-input {
     border-radius: 4px 4px 0 0;
     border: 1px solid #cfcfcf;
@@ -3038,16 +3074,10 @@ img.wiki-image {
 
 /* Background Settings */
 
-
-.toggle-list.layer-list {
-    margin-bottom: 10px;
-}
-
 .background-control button {
     border-radius: 4px 0 0 0;
 }
 
-
 .background-control button.active {
     border-radius: 0;
 }
@@ -3074,6 +3104,56 @@ img.wiki-image {
     padding-bottom: 10px;
 }
 
+.layer-list {
+    margin-bottom: 10px;
+    border: 1px solid #CCC;
+    border-radius: 4px;
+}
+
+.layer-list li {
+    position: relative;
+    height: 30px;
+    background-color: white;
+    color: #7092FF;
+}
+
+.layer-list > li:first-child {
+    border-radius: 3px 3px 0 0;
+}
+
+.layer-list > li:last-child {
+    border-radius: 0 0 3px 3px;
+}
+
+.layer-list > li:only-child {
+    border-radius: 3px;
+}
+
+.layer-list li:not(:last-child) {
+    border-bottom: 1px solid #ccc;
+}
+
+.layer-list li:hover {
+    background-color: #ececec;
+}
+
+.layer-list li.active {
+    background: #E8EBFF;
+}
+
+.layer-list label {
+    display: block;
+    padding: 5px 10px;
+    cursor: pointer;
+}
+
+.layer-list label > span {
+    display: block;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+
 .hide-toggle {
     display: block;
     padding-left:12px;
@@ -3146,7 +3226,7 @@ img.wiki-image {
 .opacity-options {
     background: url(<%= asset_path("iD/img/background-pattern-opacity.png") %>) 0 0 repeat;
     height:20px;
-    width:62px;
+    width:82px;
     position: absolute;
     right: 10px;
     top: 10px;
@@ -3185,13 +3265,20 @@ img.wiki-image {
     height:18px;
 }
 
-.background-control .layer-toggle-gpx .layer-extent {
+.background-control .layer-toggle-gpx button {
+    float: right;
+    height: 100%;
+    width: 10%;
     border-left: 1px solid #CCC;
-    border-radius: 0 4px 4px 0;
+    border-radius: 0;
 }
 
-.background-control .layer-toggle-gpx.selected .layer-extent {
-    display:inline-block;
+.background-control .layer-toggle-gpx button .icon {
+    opacity: 0.5;
+}
+
+.background-control .layer-toggle-gpx button.layer-extent {
+    border-radius: 0 3px 3px 0;
 }
 
 /* Geolocator */
@@ -3361,12 +3448,24 @@ img.wiki-image {
 }
 
 /* Attribution overlay */
-.attribution {
+.base-layer-attribution,
+.overlay-layer-attribution {
     position: absolute;
     bottom: 35px;
-    left:10px;
-    color:#888;
-    font-size:10px;
+    color: #888;
+    font-size: 10px;
+}
+
+.base-layer-attribution {
+    left: 10px;
+}
+
+.overlay-layer-attribution {
+    right: 10px;
+}
+
+.overlay-layer-attribution .attribution:not(:last-child):after {
+    content: '; ';
 }
 
 .source-image {
@@ -3558,6 +3657,8 @@ img.wiki-image {
     float: none;
     margin: auto;
     display: block;
+    color: white;
+    font-size: 14px;
 }
 
 .mode-save .user-info img {
@@ -3578,12 +3679,15 @@ img.wiki-image {
     color:#fff;
 }
 
+.mode-save .commit-info {
+    margin-bottom: 10px;
+}
+
 .mode-save .changeset-list {
     overflow: auto;
     border:1px solid #ccc;
     border-radius: 4px;
     background:#fff;
-    max-height: 160px;
 }
 
 .mode-save .warning-section .changeset-list button {
@@ -3594,6 +3698,15 @@ img.wiki-image {
     position: relative;
     border-top:1px solid #ccc;
     padding:5px 10px;
+    cursor: pointer;
+}
+
+.mode-save .changeset-list li:hover {
+    background-color: #ececec;
+}
+
+.mode-save .changeset-list .alert {
+    opacity: 0.5;
 }
 
 .changeset-list li span.count {
@@ -3601,6 +3714,10 @@ img.wiki-image {
     color:#555;
 }
 
+.mode-save .commit-section .changeset-list button {
+    border-left: 1px solid #CCC;
+}
+
 .changeset-list li span.count:before { content: '('; }
 
 .changeset-list li span.count:after { content: ')'; }
@@ -3838,7 +3955,7 @@ img.wiki-image {
 }
 /* Move over tooltips that are near the edge of screen */
 .add-point .tooltip {
-    left: 33.3333% !important; 
+    left: 33.3333% !important;
 }
 
 .curtain-tooltip.intro-points-add .tooltip-arrow,
index 6c0845b7ce7e703bc5fbb6006fd1bbea9cdf1330..0b0a390080fc3b31f53a16cabf8319ae4ef7a199 100644 (file)
 
 })(this);
 d3 = (function(){
-  var d3 = {version: "3.2.7"}; // semver
+  var d3 = {version: "3.3.8"}; // semver
 d3.ascending = function(a, b) {
   return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
 };
@@ -313,12 +313,15 @@ d3.shuffle = function(array) {
   return array;
 };
 d3.permute = function(array, indexes) {
-  var permutes = [],
-      i = -1,
-      n = indexes.length;
-  while (++i < n) permutes[i] = array[indexes[i]];
+  var i = indexes.length, permutes = new Array(i);
+  while (i--) permutes[i] = array[indexes[i]];
   return permutes;
 };
+d3.pairs = function(array) {
+  var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n);
+  while (i < n) pairs[i] = [p0 = p1, p1 = array[++i]];
+  return pairs;
+};
 
 d3.zip = function() {
   if (!(n = arguments.length)) return [];
@@ -353,8 +356,28 @@ d3.entries = function(map) {
   return entries;
 };
 d3.merge = function(arrays) {
-  return Array.prototype.concat.apply([], arrays);
+  var n = arrays.length,
+      m,
+      i = -1,
+      j = 0,
+      merged,
+      array;
+
+  while (++i < n) j += arrays[i].length;
+  merged = new Array(j);
+
+  while (--n >= 0) {
+    array = arrays[n];
+    m = array.length;
+    while (--m >= 0) {
+      merged[--j] = array[m];
+    }
+  }
+
+  return merged;
 };
+var abs = Math.abs;
+
 d3.range = function(start, stop, step) {
   if (arguments.length < 3) {
     step = 1;
@@ -365,7 +388,7 @@ d3.range = function(start, stop, step) {
   }
   if ((stop - start) / step === Infinity) throw new Error("infinite range");
   var range = [],
-       k = d3_range_integerScale(Math.abs(step)),
+       k = d3_range_integerScale(abs(step)),
        i = -1,
        j;
   start *= k, stop *= k, step *= k;
@@ -394,7 +417,8 @@ function d3_class(ctor, properties) {
 
 d3.map = function(object) {
   var map = new d3_Map;
-  for (var key in object) map.set(key, object[key]);
+  if (object instanceof d3_Map) object.forEach(function(key, value) { map.set(key, value); });
+  else for (var key in object) map.set(key, object[key]);
   return map;
 };
 
@@ -538,8 +562,8 @@ d3.nest = function() {
 };
 
 d3.set = function(array) {
-  var set = new d3_Set();
-  if (array) for (var i = 0; i < array.length; i++) set.add(array[i]);
+  var set = new d3_Set;
+  if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]);
   return set;
 };
 
@@ -573,9 +597,23 @@ d3_class(d3_Set, {
   }
 });
 d3.behavior = {};
+var d3_arraySlice = [].slice,
+    d3_array = function(list) { return d3_arraySlice.call(list); }; // conversion for NodeLists
+
 var d3_document = document,
     d3_documentElement = d3_document.documentElement,
     d3_window = window;
+
+// Redefine d3_array if the browser doesn’t support slice-based conversion.
+try {
+  d3_array(d3_documentElement.childNodes)[0].nodeType;
+} catch(e) {
+  d3_array = function(list) {
+    var i = list.length, array = new Array(i);
+    while (i--) array[i] = list[i];
+    return array;
+  };
+}
 // Copies a variable number of methods from source to target.
 d3.rebind = function(target, source) {
   var i = 1, n = arguments.length, method;
@@ -603,24 +641,6 @@ function d3_vendorSymbol(object, name) {
 }
 
 var d3_vendorPrefixes = ["webkit", "ms", "moz", "Moz", "o", "O"];
-
-var d3_array = d3_arraySlice; // conversion for NodeLists
-
-function d3_arrayCopy(pseudoarray) {
-  var i = -1, n = pseudoarray.length, array = [];
-  while (++i < n) array.push(pseudoarray[i]);
-  return array;
-}
-
-function d3_arraySlice(pseudoarray) {
-  return Array.prototype.slice.call(pseudoarray);
-}
-
-try {
-  d3_array(d3_documentElement.childNodes)[0].nodeType;
-} catch(e) {
-  d3_array = d3_arrayCopy;
-}
 function d3_noop() {}
 
 d3.dispatch = function() {
@@ -1118,15 +1138,15 @@ d3_selectionPrototype.append = function(name) {
 
 function d3_selection_creator(name) {
   return typeof name === "function" ? name
-      : (name = d3.ns.qualify(name)).local ? function() { return d3_document.createElementNS(name.space, name.local); }
-      : function() { return d3_document.createElementNS(this.namespaceURI, name); };
+      : (name = d3.ns.qualify(name)).local ? function() { return this.ownerDocument.createElementNS(name.space, name.local); }
+      : function() { return this.ownerDocument.createElementNS(this.namespaceURI, name); };
 }
 
 d3_selectionPrototype.insert = function(name, before) {
   name = d3_selection_creator(name);
   before = d3_selection_selector(before);
   return this.select(function() {
-    return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments));
+    return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null);
   });
 };
 
@@ -1310,7 +1330,7 @@ d3_selectionPrototype.sort = function(comparator) {
 function d3_selection_sortComparator(comparator) {
   if (!arguments.length) comparator = d3.ascending;
   return function(a, b) {
-    return (!a - !b) || comparator(a.__data__, b.__data__);
+    return a && b ? comparator(a.__data__, b.__data__) : !a - !b;
   };
 }
 
@@ -1415,6 +1435,8 @@ function d3_selection_enterInsertBefore(enter) {
   };
 }
 
+// import "../transition/transition";
+
 d3_selectionPrototype.transition = function() {
   var id = d3_transitionInheritId || ++d3_transitionId,
       subgroups = [],
@@ -1432,6 +1454,16 @@ d3_selectionPrototype.transition = function() {
 
   return d3_transition(subgroups, id);
 };
+// import "../transition/transition";
+
+d3_selectionPrototype.interrupt = function() {
+  return this.each(d3_selection_interrupt);
+};
+
+function d3_selection_interrupt() {
+  var lock = this.__transition__;
+  if (lock) ++lock.active;
+}
 
 // TODO fast singleton implementation?
 d3.select = function(node) {
@@ -1578,6 +1610,7 @@ d3.mouse = function(container) {
 var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0;
 
 function d3_mousePoint(container, e) {
+  if (e.changedTouches) e = e.changedTouches[0];
   var svg = container.ownerSVGElement || container;
   if (svg.createSVGPoint) {
     var point = svg.createSVGPoint();
@@ -1594,13 +1627,8 @@ function d3_mousePoint(container, e) {
       d3_mouse_bug44083 = !(ctm.f || ctm.e);
       svg.remove();
     }
-    if (d3_mouse_bug44083) {
-      point.x = e.pageX;
-      point.y = e.pageY;
-    } else {
-      point.x = e.clientX;
-      point.y = e.clientY;
-    }
+    if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY;
+    else point.x = e.clientX, point.y = e.clientY;
     point = point.matrixTransform(container.getScreenCTM().inverse());
     return [point.x, point.y];
   }
@@ -1616,47 +1644,180 @@ d3.touches = function(container, touches) {
     return point;
   }) : [];
 };
+var π = Math.PI,
+    τ = 2 * π,
+    halfπ = π / 2,
+    ε = 1e-6,
+    ε2 = ε * ε,
+    d3_radians = π / 180,
+    d3_degrees = 180 / π;
+
+function d3_sgn(x) {
+  return x > 0 ? 1 : x < 0 ? -1 : 0;
+}
+
+function d3_acos(x) {
+  return x > 1 ? 0 : x < -1 ? π : Math.acos(x);
+}
+
+function d3_asin(x) {
+  return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x);
+}
+
+function d3_sinh(x) {
+  return ((x = Math.exp(x)) - 1 / x) / 2;
+}
+
+function d3_cosh(x) {
+  return ((x = Math.exp(x)) + 1 / x) / 2;
+}
+
+function d3_tanh(x) {
+  return ((x = Math.exp(2 * x)) - 1) / (x + 1);
+}
+
+function d3_haversin(x) {
+  return (x = Math.sin(x / 2)) * x;
+}
+
+var ρ = Math.SQRT2,
+    ρ2 = 2,
+    ρ4 = 4;
+
+// p0 = [ux0, uy0, w0]
+// p1 = [ux1, uy1, w1]
+d3.interpolateZoom = function(p0, p1) {
+  var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
+      ux1 = p1[0], uy1 = p1[1], w1 = p1[2];
+
+  var dx = ux1 - ux0,
+      dy = uy1 - uy0,
+      d2 = dx * dx + dy * dy,
+      d1 = Math.sqrt(d2),
+      b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1),
+      b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1),
+      r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
+      r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1),
+      dr = r1 - r0,
+      S = (dr || Math.log(w1 / w0)) / ρ;
+
+  function interpolate(t) {
+    var s = t * S;
+    if (dr) {
+      // General case.
+      var coshr0 = d3_cosh(r0),
+          u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0));
+      return [
+        ux0 + u * dx,
+        uy0 + u * dy,
+        w0 * coshr0 / d3_cosh(ρ * s + r0)
+      ];
+    }
+    // Special case for u0 ~= u1.
+    return [
+      ux0 + t * dx,
+      uy0 + t * dy,
+      w0 * Math.exp(ρ * s)
+    ];
+  }
+
+  interpolate.duration = S * 1000;
+
+  return interpolate;
+};
 
 d3.behavior.zoom = function() {
-  var translate = [0, 0],
+  var view = {x: 0, y: 0, k: 1},
       translate0, // translate when we started zooming (to avoid drift)
-      scale = 1,
+      center, // desired position of translate0 after zooming
+      size = [960, 500], // viewport size; required for zoom interpolation
       scaleExtent = d3_behavior_zoomInfinity,
       mousedown = "mousedown.zoom",
       mousemove = "mousemove.zoom",
       mouseup = "mouseup.zoom",
-      event = d3_eventDispatch(zoom, "zoom"),
+      mousewheelTimer,
+      touchstart = "touchstart.zoom",
+      touchtime, // time of last touchstart (to detect double-tap)
+      event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"),
       x0,
       x1,
       y0,
-      y1,
-      touchtime; // time of last touchstart (to detect double-tap)
+      y1;
 
-  function zoom() {
-    this.on(mousedown, mousedowned)
+  function zoom(g) {
+    g   .on(mousedown, mousedowned)
         .on(d3_behavior_zoomWheel + ".zoom", mousewheeled)
         .on(mousemove, mousewheelreset)
         .on("dblclick.zoom", dblclicked)
-        .on("touchstart.zoom", touchstarted);
+        .on(touchstart, touchstarted);
   }
 
-  zoom.translate = function(x) {
-    if (!arguments.length) return translate;
-    translate = x.map(Number);
+  zoom.event = function(g) {
+    g.each(function() {
+      var event_ = event.of(this, arguments),
+          view1 = view;
+      if (d3_transitionInheritId) {
+          d3.select(this).transition()
+              .each("start.zoom", function() {
+                view = this.__chart__ || {x: 0, y: 0, k: 1}; // pre-transition state
+                zoomstarted(event_);
+              })
+              .tween("zoom:zoom", function() {
+                var dx = size[0],
+                    dy = size[1],
+                    cx = dx / 2,
+                    cy = dy / 2,
+                    i = d3.interpolateZoom(
+                      [(cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k],
+                      [(cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k]
+                    );
+                return function(t) {
+                  var l = i(t), k = dx / l[2];
+                  this.__chart__ = view = {x: cx - l[0] * k, y: cy - l[1] * k, k: k};
+                  zoomed(event_);
+                };
+              })
+              .each("end.zoom", function() {
+                zoomended(event_);
+              });
+      } else {
+        this.__chart__ = view;
+        zoomstarted(event_);
+        zoomed(event_);
+        zoomended(event_);
+      }
+    });
+  }
+
+  zoom.translate = function(_) {
+    if (!arguments.length) return [view.x, view.y];
+    view = {x: +_[0], y: +_[1], k: view.k}; // copy-on-write
     rescale();
     return zoom;
   };
 
-  zoom.scale = function(x) {
-    if (!arguments.length) return scale;
-    scale = +x;
+  zoom.scale = function(_) {
+    if (!arguments.length) return view.k;
+    view = {x: view.x, y: view.y, k: +_}; // copy-on-write
     rescale();
     return zoom;
   };
 
-  zoom.scaleExtent = function(x) {
+  zoom.scaleExtent = function(_) {
     if (!arguments.length) return scaleExtent;
-    scaleExtent = x == null ? d3_behavior_zoomInfinity : x.map(Number);
+    scaleExtent = _ == null ? d3_behavior_zoomInfinity : [+_[0], +_[1]];
+    return zoom;
+  };
+
+  zoom.center = function(_) {
+    if (!arguments.length) return center;
+    center = _ && [+_[0], +_[1]];
+    return zoom;
+  };
+
+  zoom.size = function(_) {
+    if (!arguments.length) return size;
+    size = _ && [+_[0], +_[1]];
     return zoom;
   };
 
@@ -1664,8 +1825,7 @@ d3.behavior.zoom = function() {
     if (!arguments.length) return x1;
     x1 = z;
     x0 = z.copy();
-    translate = [0, 0];
-    scale = 1;
+    view = {x: 0, y: 0, k: 1}; // copy-on-write
     return zoom;
   };
 
@@ -1673,37 +1833,44 @@ d3.behavior.zoom = function() {
     if (!arguments.length) return y1;
     y1 = z;
     y0 = z.copy();
-    translate = [0, 0];
-    scale = 1;
+    view = {x: 0, y: 0, k: 1}; // copy-on-write
     return zoom;
   };
 
   function location(p) {
-    return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
+    return [(p[0] - view.x) / view.k, (p[1] - view.y) / view.k];
   }
 
   function point(l) {
-    return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
+    return [l[0] * view.k + view.x, l[1] * view.k + view.y];
   }
 
   function scaleTo(s) {
-    scale = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s));
+    view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s));
   }
 
   function translateTo(p, l) {
     l = point(l);
-    translate[0] += p[0] - l[0];
-    translate[1] += p[1] - l[1];
+    view.x += p[0] - l[0];
+    view.y += p[1] - l[1];
   }
 
   function rescale() {
-    if (x1) x1.domain(x0.range().map(function(x) { return (x - translate[0]) / scale; }).map(x0.invert));
-    if (y1) y1.domain(y0.range().map(function(y) { return (y - translate[1]) / scale; }).map(y0.invert));
+    if (x1) x1.domain(x0.range().map(function(x) { return (x - view.x) / view.k; }).map(x0.invert));
+    if (y1) y1.domain(y0.range().map(function(y) { return (y - view.y) / view.k; }).map(y0.invert));
+  }
+
+  function zoomstarted(event) {
+    event({type: "zoomstart"});
   }
 
-  function dispatch(event) {
+  function zoomed(event) {
     rescale();
-    event({type: "zoom", scale: scale, translate: translate});
+    event({type: "zoom", scale: view.k, translate: [view.x, view.y]});
+  }
+
+  function zoomended(event) {
+    event({type: "zoomend"});
   }
 
   function mousedowned() {
@@ -1715,62 +1882,92 @@ d3.behavior.zoom = function() {
         l = location(d3.mouse(target)),
         dragRestore = d3_event_dragSuppress();
 
+    d3_selection_interrupt.call(target);
+    zoomstarted(event_);
+
     function moved() {
       dragged = 1;
       translateTo(d3.mouse(target), l);
-      dispatch(event_);
+      zoomed(event_);
     }
 
     function ended() {
       w.on(mousemove, d3_window === target ? mousewheelreset : null).on(mouseup, null);
       dragRestore(dragged && d3.event.target === eventTarget);
+      zoomended(event_);
     }
   }
 
+  // These closures persist for as long as at least one touch is active.
   function touchstarted() {
     var target = this,
         event_ = event.of(target, arguments),
-        touches = d3.touches(target),
-        locations = {},
+        locations0 = {}, // touchstart locations
         distance0 = 0, // distance² between initial touches
-        scale0 = scale, // scale when we started touching
-        now = Date.now(),
-        name = "zoom-" + d3.event.changedTouches[0].identifier,
-        touchmove = "touchmove." + name,
-        touchend = "touchend." + name,
+        scale0, // scale when we started touching
+        eventId = d3.event.changedTouches[0].identifier,
+        touchmove = "touchmove.zoom-" + eventId,
+        touchend = "touchend.zoom-" + eventId,
         w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended),
-        t = d3.select(target).on(mousedown, null), // prevent duplicate events
+        t = d3.select(target).on(mousedown, null).on(touchstart, started), // prevent duplicate events
         dragRestore = d3_event_dragSuppress();
 
-    touches.forEach(function(t) { locations[t.identifier] = location(t); });
+    d3_selection_interrupt.call(target);
+    started();
+    zoomstarted(event_);
+
+    // Updates locations of any touches in locations0.
+    function relocate() {
+      var touches = d3.touches(target);
+      scale0 = view.k;
+      touches.forEach(function(t) {
+        if (t.identifier in locations0) locations0[t.identifier] = location(t);
+      });
+      return touches;
+    }
+
+    // Temporarily override touchstart while gesture is active.
+    function started() {
+      // Only track touches started on the target element.
+      var changed = d3.event.changedTouches;
+      for (var i = 0, n = changed.length; i < n; ++i) {
+        locations0[changed[i].identifier] = null;
+      }
+
+      var touches = relocate(),
+          now = Date.now();
 
-    if (touches.length === 1) {
-      if (now - touchtime < 500) { // dbltap
-        var p = touches[0], l = location(touches[0]);
-        scaleTo(scale * 2);
-        translateTo(p, l);
-        d3_eventPreventDefault();
-        dispatch(event_);
+      if (touches.length === 1) {
+        if (now - touchtime < 500) { // dbltap
+          var p = touches[0], l = locations0[p.identifier];
+          scaleTo(view.k * 2);
+          translateTo(p, l);
+          d3_eventPreventDefault();
+          zoomed(event_);
+        }
+        touchtime = now;
+      } else if (touches.length > 1) {
+        var p = touches[0], q = touches[1],
+            dx = p[0] - q[0], dy = p[1] - q[1];
+        distance0 = dx * dx + dy * dy;
       }
-      touchtime = now;
-    } else if (touches.length > 1) {
-      var p = touches[0], q = touches[1],
-          dx = p[0] - q[0], dy = p[1] - q[1];
-      distance0 = dx * dx + dy * dy;
     }
 
     function moved() {
       var touches = d3.touches(target),
-          p0 = touches[0],
-          l0 = locations[p0.identifier];
-
-      if (p1 = touches[1]) {
-        var p1, l1 = locations[p1.identifier],
-            scale1 = d3.event.scale;
-        if (scale1 == null) {
-          var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1;
-          scale1 = distance0 && Math.sqrt(distance1 / distance0);
+          p0, l0,
+          p1, l1;
+      for (var i = 0, n = touches.length; i < n; ++i, l1 = null) {
+        p1 = touches[i];
+        if (l1 = locations0[p1.identifier]) {
+          if (l0) break;
+          p0 = p1, l0 = l1;
         }
+      }
+
+      if (l1) {
+        var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1,
+            scale1 = distance0 && Math.sqrt(distance1 / distance0);
         p0 = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
         l0 = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
         scaleTo(scale1 * scale0);
@@ -1778,22 +1975,42 @@ d3.behavior.zoom = function() {
 
       touchtime = null;
       translateTo(p0, l0);
-      dispatch(event_);
+      zoomed(event_);
     }
 
     function ended() {
+      // If there are any globally-active touches remaining, remove the ended
+      // touches from locations0.
+      if (d3.event.touches.length) {
+        var changed = d3.event.changedTouches;
+        for (var i = 0, n = changed.length; i < n; ++i) {
+          delete locations0[changed[i].identifier];
+        }
+        // If locations0 is not empty, then relocate and continue listening for
+        // touchmove and touchend.
+        for (var identifier in locations0) {
+          return void relocate(); // locations may have detached due to rotation
+        }
+      }
+      // Otherwise, remove touchmove and touchend listeners.
       w.on(touchmove, null).on(touchend, null);
-      t.on(mousedown, mousedowned);
+      t.on(mousedown, mousedowned).on(touchstart, touchstarted);
       dragRestore();
+      zoomended(event_);
     }
   }
 
   function mousewheeled() {
+    var event_ = event.of(this, arguments);
+    if (mousewheelTimer) clearTimeout(mousewheelTimer);
+    else d3_selection_interrupt.call(this), zoomstarted(event_);
+    mousewheelTimer = setTimeout(function() { mousewheelTimer = null; zoomended(event_); }, 50);
     d3_eventPreventDefault();
-    if (!translate0) translate0 = location(d3.mouse(this));
-    scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * scale);
-    translateTo(d3.mouse(this), translate0);
-    dispatch(event.of(this, arguments));
+    var point = center || d3.mouse(this);
+    if (!translate0) translate0 = location(point);
+    scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k);
+    translateTo(point, translate0);
+    zoomed(event_);
   }
 
   function mousewheelreset() {
@@ -1801,10 +2018,15 @@ d3.behavior.zoom = function() {
   }
 
   function dblclicked() {
-    var p = d3.mouse(this), l = location(p), k = Math.log(scale) / Math.LN2;
+    var event_ = event.of(this, arguments),
+        p = d3.mouse(this),
+        l = location(p),
+        k = Math.log(view.k) / Math.LN2;
+    zoomstarted(event_);
     scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1));
     translateTo(p, l);
-    dispatch(event.of(this, arguments));
+    zoomed(event_);
+    zoomended(event_);
   }
 
   return d3.rebind(zoom, event, "on");
@@ -1837,8 +2059,8 @@ d3.timer = function(callback, delay, then) {
   if (n < 3) then = Date.now();
 
   // Add the callback to the tail of the queue.
-  var time = then + delay, timer = {callback: callback, time: time, next: null};
-  if (d3_timer_queueTail) d3_timer_queueTail.next = timer;
+  var time = then + delay, timer = {c: callback, t: time, f: false, n: null};
+  if (d3_timer_queueTail) d3_timer_queueTail.n = timer;
   else d3_timer_queueHead = timer;
   d3_timer_queueTail = timer;
 
@@ -1870,20 +2092,12 @@ d3.timer.flush = function() {
   d3_timer_sweep();
 };
 
-function d3_timer_replace(callback, delay, then) {
-  var n = arguments.length;
-  if (n < 2) delay = 0;
-  if (n < 3) then = Date.now();
-  d3_timer_active.callback = callback;
-  d3_timer_active.time = then + delay;
-}
-
 function d3_timer_mark() {
   var now = Date.now();
   d3_timer_active = d3_timer_queueHead;
   while (d3_timer_active) {
-    if (now >= d3_timer_active.time) d3_timer_active.flush = d3_timer_active.callback(now - d3_timer_active.time);
-    d3_timer_active = d3_timer_active.next;
+    if (now >= d3_timer_active.t) d3_timer_active.f = d3_timer_active.c(now - d3_timer_active.t);
+    d3_timer_active = d3_timer_active.n;
   }
   return now;
 }
@@ -1895,45 +2109,16 @@ function d3_timer_sweep() {
       t1 = d3_timer_queueHead,
       time = Infinity;
   while (t1) {
-    if (t1.flush) {
-      t1 = t0 ? t0.next = t1.next : d3_timer_queueHead = t1.next;
+    if (t1.f) {
+      t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n;
     } else {
-      if (t1.time < time) time = t1.time;
-      t1 = (t0 = t1).next;
+      if (t1.t < time) time = t1.t;
+      t1 = (t0 = t1).n;
     }
   }
   d3_timer_queueTail = t0;
   return time;
 }
-var π = Math.PI,
-    ε = 1e-6,
-    ε2 = ε * ε,
-    d3_radians = π / 180,
-    d3_degrees = 180 / π;
-
-function d3_sgn(x) {
-  return x > 0 ? 1 : x < 0 ? -1 : 0;
-}
-
-function d3_acos(x) {
-  return x > 1 ? 0 : x < -1 ? π : Math.acos(x);
-}
-
-function d3_asin(x) {
-  return x > 1 ? π / 2 : x < -1 ? -π / 2 : Math.asin(x);
-}
-
-function d3_sinh(x) {
-  return (Math.exp(x) - Math.exp(-x)) / 2;
-}
-
-function d3_cosh(x) {
-  return (Math.exp(x) + Math.exp(-x)) / 2;
-}
-
-function d3_haversin(x) {
-  return (x = Math.sin(x / 2)) * x;
-}
 d3.geo = {};
 function d3_identity(d) {
   return d;
@@ -1950,13 +2135,13 @@ function d3_geo_spherical(cartesian) {
 }
 
 function d3_geo_sphericalEqual(a, b) {
-  return Math.abs(a[0] - b[0]) < ε && Math.abs(a[1] - b[1]) < ε;
+  return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε;
 }
 
 // General spherical polygon clipping algorithm: takes a polygon, cuts it into
 // visible line segments and rejoins the segments by interpolating along the
 // clip edge.
-function d3_geo_clipPolygon(segments, compare, inside, interpolate, listener) {
+function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) {
   var subject = [],
       clip = [];
 
@@ -1975,14 +2160,14 @@ function d3_geo_clipPolygon(segments, compare, inside, interpolate, listener) {
       return;
     }
 
-    var a = {point: p0, points: segment, other: null, visited: false, entry: true, subject: true},
-        b = {point: p0, points: [p0], other: a, visited: false, entry: false, subject: false};
-    a.other = b;
+    var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true),
+        b = new d3_geo_clipPolygonIntersection(p0, null, a, false);
+    a.o = b;
     subject.push(a);
     clip.push(b);
-    a = {point: p1, points: [p1], other: null, visited: false, entry: false, subject: true};
-    b = {point: p1, points: [p1], other: a, visited: false, entry: true, subject: false};
-    a.other = b;
+    a = new d3_geo_clipPolygonIntersection(p1, segment, null, false);
+    b = new d3_geo_clipPolygonIntersection(p1, null, a, true);
+    a.o = b;
     subject.push(a);
     clip.push(b);
   });
@@ -1991,41 +2176,42 @@ function d3_geo_clipPolygon(segments, compare, inside, interpolate, listener) {
   d3_geo_clipPolygonLinkCircular(clip);
   if (!subject.length) return;
 
-  if (inside) for (var i = 1, e = !inside(clip[0].point), n = clip.length; i < n; ++i) {
-    clip[i].entry = (e = !e);
+  for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) {
+    clip[i].e = entry = !entry;
   }
 
   var start = subject[0],
-      current,
       points,
       point;
   while (1) {
     // Find first unvisited intersection.
-    current = start;
-    while (current.visited) if ((current = current.next) === start) return;
-    points = current.points;
+    var current = start,
+        isSubject = true;
+    while (current.v) if ((current = current.n) === start) return;
+    points = current.z;
     listener.lineStart();
     do {
-      current.visited = current.other.visited = true;
-      if (current.entry) {
-        if (current.subject) {
-          for (var i = 0; i < points.length; i++) listener.point((point = points[i])[0], point[1]);
+      current.v = current.o.v = true;
+      if (current.e) {
+        if (isSubject) {
+          for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]);
         } else {
-          interpolate(current.point, current.next.point, 1, listener);
+          interpolate(current.x, current.n.x, 1, listener);
         }
-        current = current.next;
+        current = current.n;
       } else {
-        if (current.subject) {
-          points = current.prev.points;
-          for (var i = points.length; --i >= 0;) listener.point((point = points[i])[0], point[1]);
+        if (isSubject) {
+          points = current.p.z;
+          for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]);
         } else {
-          interpolate(current.point, current.prev.point, -1, listener);
+          interpolate(current.x, current.p.x, -1, listener);
         }
-        current = current.prev;
+        current = current.p;
       }
-      current = current.other;
-      points = current.points;
-    } while (!current.visited);
+      current = current.o;
+      points = current.z;
+      isSubject = !isSubject;
+    } while (!current.v);
     listener.lineEnd();
   }
 }
@@ -2037,17 +2223,27 @@ function d3_geo_clipPolygonLinkCircular(array) {
       a = array[0],
       b;
   while (++i < n) {
-    a.next = b = array[i];
-    b.prev = a;
+    a.n = b = array[i];
+    b.p = a;
     a = b;
   }
-  a.next = b = array[0];
-  b.prev = a;
+  a.n = b = array[0];
+  b.p = a;
 }
 
-function d3_geo_clip(pointVisible, clipLine, interpolate, polygonContains) {
-  return function(listener) {
-    var line = clipLine(listener);
+function d3_geo_clipPolygonIntersection(point, points, other, entry) {
+  this.x = point;
+  this.z = points;
+  this.o = other; // another intersection
+  this.e = entry; // is an entry?
+  this.v = false; // visited
+  this.n = this.p = null; // next & previous
+}
+
+function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) {
+  return function(rotate, listener) {
+    var line = clipLine(listener),
+        rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]);
 
     var clip = {
       point: point,
@@ -2067,9 +2263,10 @@ function d3_geo_clip(pointVisible, clipLine, interpolate, polygonContains) {
         clip.lineEnd = lineEnd;
 
         segments = d3.merge(segments);
+        var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon);
         if (segments.length) {
-          d3_geo_clipPolygon(segments, d3_geo_clipSort, null, interpolate, listener);
-        } else if (polygonContains(polygon)) {
+          d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener);
+        } else if (clipStartInside) {
           listener.lineStart();
           interpolate(null, null, 1, listener);
           listener.lineEnd();
@@ -2086,8 +2283,14 @@ function d3_geo_clip(pointVisible, clipLine, interpolate, polygonContains) {
       }
     };
 
-    function point(λ, φ) { if (pointVisible(λ, φ)) listener.point(λ, φ); }
-    function pointLine(λ, φ) { line.point(λ, φ); }
+    function point(λ, φ) {
+      var point = rotate(λ, φ);
+      if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ);
+    }
+    function pointLine(λ, φ) {
+      var point = rotate(λ, φ);
+      line.point(point[0], point[1]);
+    }
     function lineStart() { clip.point = pointLine; line.lineStart(); }
     function lineEnd() { clip.point = point; line.lineEnd(); }
 
@@ -2099,8 +2302,9 @@ function d3_geo_clip(pointVisible, clipLine, interpolate, polygonContains) {
         ring;
 
     function pointRing(λ, φ) {
-      ringListener.point(λ, φ);
       ring.push([λ, φ]);
+      var point = rotate(λ, φ);
+      ringListener.point(point[0], point[1]);
     }
 
     function ringStart() {
@@ -2172,8 +2376,8 @@ function d3_geo_clipBufferListener() {
 // Intersection points are sorted along the clip edge. For both antimeridian
 // cutting and circle clipping, the same comparison is used.
 function d3_geo_clipSort(a, b) {
-  return ((a = a.point)[0] < 0 ? a[1] - π / 2 - ε : π / 2 - a[1])
-       - ((b = b.point)[0] < 0 ? b[1] - π / 2 - ε : π / 2 - b[1]);
+  return ((a = a.x)[0] < 0 ? a[1] - halfπ - ε : halfπ - a[1])
+       - ((b = b.x)[0] < 0 ? b[1] - halfπ - ε : halfπ - b[1]);
 }
 // Adds floating point numbers with twice the normal precision.
 // Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and
@@ -2239,12 +2443,12 @@ var d3_geo_streamGeometryType = {
     listener.sphere();
   },
   Point: function(object, listener) {
-    var coordinate = object.coordinates;
-    listener.point(coordinate[0], coordinate[1]);
+    object = object.coordinates;
+    listener.point(object[0], object[1], object[2]);
   },
   MultiPoint: function(object, listener) {
-    var coordinates = object.coordinates, i = -1, n = coordinates.length, coordinate;
-    while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]);
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]);
   },
   LineString: function(object, listener) {
     d3_geo_streamLine(object.coordinates, listener, 0);
@@ -2269,7 +2473,7 @@ var d3_geo_streamGeometryType = {
 function d3_geo_streamLine(coordinates, listener, closed) {
   var i = -1, n = coordinates.length - closed, coordinate;
   listener.lineStart();
-  while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]);
+  while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]);
   listener.lineEnd();
 }
 
@@ -2394,8 +2598,6 @@ function d3_geo_pointInPolygon(point, polygon) {
       parallel = point[1],
       meridianNormal = [Math.sin(meridian), -Math.cos(meridian), 0],
       polarAngle = 0,
-      polar = false,
-      southPole = false,
       winding = 0;
   d3_geo_areaRingSum.reset();
 
@@ -2418,12 +2620,11 @@ function d3_geo_pointInPolygon(point, polygon) {
           sinφ = Math.sin(φ),
           cosφ = Math.cos(φ),
           dλ = λ - λ0,
-          antimeridian = Math.abs(dλ) > π,
+          antimeridian = abs(dλ) > π,
           k = sinφ0 * sinφ;
       d3_geo_areaRingSum.add(Math.atan2(k * Math.sin(dλ), cosφ0 * cosφ + k * Math.cos(dλ)));
 
-      if (Math.abs(φ) < ε) southPole = true;
-      polarAngle += antimeridian ? dλ + (dλ >= 0 ? 2 : -2) * π : dλ;
+      polarAngle += antimeridian ? dλ + (dλ >= 0 ? τ : -τ): dλ;
 
       // Are the longitudes either side of the point's meridian, and are the
       // latitudes smaller than the parallel?
@@ -2433,34 +2634,34 @@ function d3_geo_pointInPolygon(point, polygon) {
         var intersection = d3_geo_cartesianCross(meridianNormal, arc);
         d3_geo_cartesianNormalize(intersection);
         var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]);
-        if (parallel > φarc) {
+        if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) {
           winding += antimeridian ^ dλ >= 0 ? 1 : -1;
         }
       }
       if (!j++) break;
       λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point;
     }
-    if (Math.abs(polarAngle) > ε) polar = true;
   }
 
   // First, determine whether the South pole is inside or outside:
   //
   // It is inside if:
-  // * the polygon doesn't wind around it, and its area is negative (counter-clockwise).
-  // * otherwise, if the polygon winds around it in a clockwise direction.
+  // * the polygon winds around it in a clockwise direction.
+  // * the polygon does not (cumulatively) wind around it, but has a negative
+  //   (counter-clockwise) area.
   //
   // Second, count the (signed) number of times a segment crosses a meridian
   // from the point to the South pole.  If it is zero, then the point is the
   // same side as the South pole.
 
-  return (!southPole && !polar && d3_geo_areaRingSum < 0 || polarAngle < -ε) ^ (winding & 1);
+  return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ (winding & 1);
 }
 
 var d3_geo_clipAntimeridian = d3_geo_clip(
     d3_true,
     d3_geo_clipAntimeridianLine,
     d3_geo_clipAntimeridianInterpolate,
-    d3_geo_clipAntimeridianPolygonContains);
+    [-π, -π / 2]);
 
 // Takes a line and cuts into visible segments. Return values:
 //   0: there were intersections or the line was empty.
@@ -2480,9 +2681,9 @@ function d3_geo_clipAntimeridianLine(listener) {
     },
     point: function(λ1, φ1) {
       var sλ1 = λ1 > 0 ? π : -π,
-          dλ = Math.abs(λ1 - λ0);
-      if (Math.abs(dλ - π) < ε) { // line crosses a pole
-        listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? π / 2 : -π / 2);
+          dλ = abs(λ1 - λ0);
+      if (abs(dλ - π) < ε) { // line crosses a pole
+        listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfπ : -halfπ);
         listener.point(sλ0, φ0);
         listener.lineEnd();
         listener.lineStart();
@@ -2491,8 +2692,8 @@ function d3_geo_clipAntimeridianLine(listener) {
         clean = 0;
       } else if (sλ0 !== sλ1 && dλ >= π) { // line crosses antimeridian
         // handle degeneracies
-        if (Math.abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε;
-        if (Math.abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε;
+        if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε;
+        if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε;
         φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1);
         listener.point(sλ0, φ0);
         listener.lineEnd();
@@ -2516,7 +2717,7 @@ function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) {
   var cosφ0,
       cosφ1,
       sinλ0_λ1 = Math.sin(λ0 - λ1);
-  return Math.abs(sinλ0_λ1) > ε
+  return abs(sinλ0_λ1) > ε
       ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1)
                  - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0))
                  / (cosφ0 * cosφ1 * sinλ0_λ1))
@@ -2526,7 +2727,7 @@ function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) {
 function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) {
   var φ;
   if (from == null) {
-    φ = direction * π / 2;
+    φ = direction * halfπ;
     listener.point(-π,  φ);
     listener.point( 0,  φ);
     listener.point( π,  φ);
@@ -2536,8 +2737,8 @@ function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) {
     listener.point(-π, -φ);
     listener.point(-π,  0);
     listener.point(-π,  φ);
-  } else if (Math.abs(from[0] - to[0]) > ε) {
-    var s = (from[0] < to[0] ? 1 : -1) * π;
+  } else if (abs(from[0] - to[0]) > ε) {
+    var s = from[0] < to[0] ? π : -π;
     φ = direction * s / 2;
     listener.point(-s, φ);
     listener.point( 0, φ);
@@ -2547,12 +2748,6 @@ function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) {
   }
 }
 
-var d3_geo_clipAntimeridianPoint = [-π, 0];
-
-function d3_geo_clipAntimeridianPolygonContains(polygon) {
-  return d3_geo_pointInPolygon(d3_geo_clipAntimeridianPoint, polygon);
-}
-
 function d3_geo_equirectangular(λ, φ) {
   return [λ, φ];
 }
@@ -2577,17 +2772,23 @@ d3.geo.rotation = function(rotate) {
   return forward;
 };
 
+function d3_geo_identityRotation(λ, φ) {
+  return [λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ];
+}
+
+d3_geo_identityRotation.invert = d3_geo_equirectangular;
+
 // Note: |δλ| must be < 2π
 function d3_geo_rotation(δλ, δφ, δγ) {
   return δλ ? (δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ))
     : d3_geo_rotationλ(δλ))
     : (δφ || δγ ? d3_geo_rotationφγ(δφ, δγ)
-    : d3_geo_equirectangular);
+    : d3_geo_identityRotation);
 }
 
 function d3_geo_forwardRotationλ(δλ) {
   return function(λ, φ) {
-    return λ += δλ, [λ > π ? λ - 2 * π : λ < -π ? λ + 2 * π : λ, φ];
+    return λ += δλ, [λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ];
   };
 }
 
@@ -2678,16 +2879,16 @@ function d3_geo_circleInterpolate(radius, precision) {
   var cr = Math.cos(radius),
       sr = Math.sin(radius);
   return function(from, to, direction, listener) {
+    var step = direction * precision;
     if (from != null) {
       from = d3_geo_circleAngle(cr, from);
       to = d3_geo_circleAngle(cr, to);
-      if (direction > 0 ? from < to: from > to) from += direction * 2 * π;
+      if (direction > 0 ? from < to: from > to) from += direction * τ;
     } else {
-      from = radius + direction * 2 * π;
-      to = radius;
+      from = radius + direction * τ;
+      to = radius - .5 * step;
     }
-    var point;
-    for (var step = direction * precision, t = from; direction > 0 ? t > to : t < to; t -= step) {
+    for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) {
       listener.point((point = d3_geo_spherical([
         cr,
         -sr * Math.cos(t),
@@ -2710,11 +2911,10 @@ function d3_geo_circleAngle(cr, point) {
 function d3_geo_clipCircle(radius) {
   var cr = Math.cos(radius),
       smallRadius = cr > 0,
-      point = [radius, 0],
-      notHemisphere = Math.abs(cr) > ε, // TODO optimise for this common case
+      notHemisphere = abs(cr) > ε, // TODO optimise for this common case
       interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians);
 
-  return d3_geo_clip(visible, clipLine, interpolate, polygonContains);
+  return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-π, radius - π]);
 
   function visible(λ, φ) {
     return Math.cos(λ) * Math.cos(φ) > cr;
@@ -2848,7 +3048,7 @@ function d3_geo_clipCircle(radius) {
         z;
     if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z;
     var δλ = λ1 - λ0,
-        polar = Math.abs(δλ - π) < ε,
+        polar = abs(δλ - π) < ε,
         meridian = polar || δλ < ε;
 
     if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z;
@@ -2856,7 +3056,7 @@ function d3_geo_clipCircle(radius) {
     // Check that the first point is between a and b.
     if (meridian
         ? polar
-          ? φ0 + φ1 > 0 ^ q[1] < (Math.abs(q[0] - λ0) < ε ? φ0 : φ1)
+          ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1)
           : φ0 <= q[1] && q[1] <= φ1
         : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) {
       var q1 = d3_geo_cartesianScale(u, (-w + t) / uu);
@@ -2876,18 +3076,101 @@ function d3_geo_clipCircle(radius) {
     else if (φ > r) code |= 8; // above
     return code;
   }
+}
 
-  function polygonContains(polygon) {
-    return d3_geo_pointInPolygon(point, polygon);
-  }
+// Liang–Barsky line clipping.
+function d3_geom_clipLine(x0, y0, x1, y1) {
+  return function(line) {
+    var a = line.a,
+        b = line.b,
+        ax = a.x,
+        ay = a.y,
+        bx = b.x,
+        by = b.y,
+        t0 = 0,
+        t1 = 1,
+        dx = bx - ax,
+        dy = by - ay,
+        r;
+
+    r = x0 - ax;
+    if (!dx && r > 0) return;
+    r /= dx;
+    if (dx < 0) {
+      if (r < t0) return;
+      if (r < t1) t1 = r;
+    } else if (dx > 0) {
+      if (r > t1) return;
+      if (r > t0) t0 = r;
+    }
+
+    r = x1 - ax;
+    if (!dx && r < 0) return;
+    r /= dx;
+    if (dx < 0) {
+      if (r > t1) return;
+      if (r > t0) t0 = r;
+    } else if (dx > 0) {
+      if (r < t0) return;
+      if (r < t1) t1 = r;
+    }
+
+    r = y0 - ay;
+    if (!dy && r > 0) return;
+    r /= dy;
+    if (dy < 0) {
+      if (r < t0) return;
+      if (r < t1) t1 = r;
+    } else if (dy > 0) {
+      if (r > t1) return;
+      if (r > t0) t0 = r;
+    }
+
+    r = y1 - ay;
+    if (!dy && r < 0) return;
+    r /= dy;
+    if (dy < 0) {
+      if (r > t1) return;
+      if (r > t0) t0 = r;
+    } else if (dy > 0) {
+      if (r < t0) return;
+      if (r < t1) t1 = r;
+    }
+
+    if (t0 > 0) line.a = {x: ax + t0 * dx, y: ay + t0 * dy};
+    if (t1 < 1) line.b = {x: ax + t1 * dx, y: ay + t1 * dy};
+    return line;
+  };
 }
 
-var d3_geo_clipViewMAX = 1e9;
+var d3_geo_clipExtentMAX = 1e9;
+
+d3.geo.clipExtent = function() {
+  var x0, y0, x1, y1,
+      stream,
+      clip,
+      clipExtent = {
+        stream: function(output) {
+          if (stream) stream.valid = false;
+          stream = clip(output);
+          stream.valid = true; // allow caching by d3.geo.path
+          return stream;
+        },
+        extent: function(_) {
+          if (!arguments.length) return [[x0, y0], [x1, y1]];
+          clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]);
+          if (stream) stream.valid = false, stream = null;
+          return clipExtent;
+        }
+      };
+  return clipExtent.extent([[0, 0], [960, 500]]);
+};
 
-function d3_geo_clipView(x0, y0, x1, y1) {
+function d3_geo_clipExtent(x0, y0, x1, y1) {
   return function(listener) {
     var listener_ = listener,
         bufferListener = d3_geo_clipBufferListener(),
+        clipLine = d3_geom_clipLine(x0, y0, x1, y1),
         segments,
         polygon,
         ring;
@@ -2900,28 +3183,30 @@ function d3_geo_clipView(x0, y0, x1, y1) {
         listener = bufferListener;
         segments = [];
         polygon = [];
+        clean = true;
       },
       polygonEnd: function() {
         listener = listener_;
-        if ((segments = d3.merge(segments)).length) {
+        segments = d3.merge(segments);
+        var clipStartInside = insidePolygon([x0, y1]),
+            inside = clean && clipStartInside,
+            visible = segments.length;
+        if (inside || visible) {
           listener.polygonStart();
-          d3_geo_clipPolygon(segments, compare, inside, interpolate, listener);
+          if (inside) {
+            listener.lineStart();
+            interpolate(null, null, 1, listener);
+            listener.lineEnd();
+          }
+          if (visible) {
+            d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener);
+          }
           listener.polygonEnd();
-        } else if (insidePolygon([x0, y0])) {
-          listener.polygonStart(), listener.lineStart();
-          interpolate(null, null, 1, listener);
-          listener.lineEnd(), listener.polygonEnd();
         }
         segments = polygon = ring = null;
       }
     };
 
-    function inside(point) {
-      var a = corner(point, -1),
-          i = insidePolygon([a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0]);
-      return i;
-    }
-
     function insidePolygon(p) {
       var wn = 0, // the winding number counter
           n = polygon.length,
@@ -2958,17 +3243,18 @@ function d3_geo_clipView(x0, y0, x1, y1) {
       }
     }
 
-    function visible(x, y) {
+    function pointVisible(x, y) {
       return x0 <= x && x <= x1 && y0 <= y && y <= y1;
     }
 
     function point(x, y) {
-      if (visible(x, y)) listener.point(x, y);
+      if (pointVisible(x, y)) listener.point(x, y);
     }
 
     var x__, y__, v__, // first point
         x_, y_, v_, // previous point
-        first;
+        first,
+        clean;
 
     function lineStart() {
       clip.point = linePoint;
@@ -2992,9 +3278,9 @@ function d3_geo_clipView(x0, y0, x1, y1) {
     }
 
     function linePoint(x, y) {
-      x = Math.max(-d3_geo_clipViewMAX, Math.min(d3_geo_clipViewMAX, x));
-      y = Math.max(-d3_geo_clipViewMAX, Math.min(d3_geo_clipViewMAX, y));
-      var v = visible(x, y);
+      x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x));
+      y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y));
+      var v = pointVisible(x, y);
       if (polygon) ring.push([x, y]);
       if (first) {
         x__ = x, y__ = y, v__ = v;
@@ -3006,18 +3292,19 @@ function d3_geo_clipView(x0, y0, x1, y1) {
       } else {
         if (v && v_) listener.point(x, y);
         else {
-          var a = [x_, y_],
-              b = [x, y];
-          if (clipLine(a, b)) {
+          var l = {a: {x: x_, y: y_}, b: {x: x, y: y}};
+          if (clipLine(l)) {
             if (!v_) {
               listener.lineStart();
-              listener.point(a[0], a[1]);
+              listener.point(l.a.x, l.a.y);
             }
-            listener.point(b[0], b[1]);
+            listener.point(l.b.x, l.b.y);
             if (!v) listener.lineEnd();
+            clean = false;
           } else if (v) {
             listener.lineStart();
             listener.point(x, y);
+            clean = false;
           }
         }
       }
@@ -3028,14 +3315,14 @@ function d3_geo_clipView(x0, y0, x1, y1) {
   };
 
   function corner(p, direction) {
-    return Math.abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3
-        : Math.abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1
-        : Math.abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0
-        : direction > 0 ? 3 : 2; // Math.abs(p[1] - y1) < ε
+    return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3
+        : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1
+        : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0
+        : direction > 0 ? 3 : 2; // abs(p[1] - y1) < ε
   }
 
   function compare(a, b) {
-    return comparePoints(a.point, b.point);
+    return comparePoints(a.x, b.x);
   }
 
   function comparePoints(a, b) {
@@ -3047,47 +3334,6 @@ function d3_geo_clipView(x0, y0, x1, y1) {
         : ca === 2 ? a[1] - b[1]
         : b[0] - a[0];
   }
-
-  // Liang–Barsky line clipping.
-  function clipLine(a, b) {
-    var dx = b[0] - a[0],
-        dy = b[1] - a[1],
-        t = [0, 1];
-
-    if (Math.abs(dx) < ε && Math.abs(dy) < ε) return x0 <= a[0] && a[0] <= x1 && y0 <= a[1] && a[1] <= y1;
-
-    if (d3_geo_clipViewT(x0 - a[0],  dx, t) &&
-        d3_geo_clipViewT(a[0] - x1, -dx, t) &&
-        d3_geo_clipViewT(y0 - a[1],  dy, t) &&
-        d3_geo_clipViewT(a[1] - y1, -dy, t)) {
-      if (t[1] < 1) {
-        b[0] = a[0] + t[1] * dx;
-        b[1] = a[1] + t[1] * dy;
-      }
-      if (t[0] > 0) {
-        a[0] += t[0] * dx;
-        a[1] += t[0] * dy;
-      }
-      return true;
-    }
-
-    return false;
-  }
-}
-
-function d3_geo_clipViewT(num, denominator, t) {
-  if (Math.abs(denominator) < ε) return num <= 0;
-
-  var u = num / denominator;
-
-  if (denominator > 0) {
-    if (u > t[1]) return false;
-    if (u > t[0]) t[0] = u;
-  } else {
-    if (u < t[0]) return false;
-    if (u < t[1]) t[1] = u;
-  }
-  return true;
 }
 function d3_geo_compose(a, b) {
 
@@ -3330,7 +3576,7 @@ d3.geo.bounds = (function() {
       var dλ = λ - λ_,
           s = dλ > 0 ? 1 : -1,
           λi = inflection[0] * d3_degrees * s,
-          antimeridian = Math.abs(dλ) > 180;
+          antimeridian = abs(dλ) > 180;
       if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) {
         var φi = inflection[1] * d3_degrees;
         if (φi > φ1) φ1 = φi;
@@ -3375,7 +3621,7 @@ d3.geo.bounds = (function() {
   function ringPoint(λ, φ) {
     if (p0) {
       var dλ = λ - λ_;
-      dλSum += Math.abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ;
+      dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ;
     } else λ__ = λ, φ__ = φ;
     d3_geo_area.point(λ, φ);
     linePoint(λ, φ);
@@ -3388,7 +3634,7 @@ d3.geo.bounds = (function() {
   function ringEnd() {
     ringPoint(λ__, φ__);
     d3_geo_area.lineEnd();
-    if (Math.abs(dλSum) > ε) λ0 = -(λ1 = 180);
+    if (abs(dλSum) > ε) λ0 = -(λ1 = 180);
     range[0] = λ0, range[1] = λ1;
     p0 = null;
   }
@@ -3601,7 +3847,7 @@ var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = {
   },
   polygonEnd: function() {
     d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop;
-    d3_geo_pathAreaSum += Math.abs(d3_geo_pathAreaPolygon / 2);
+    d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2);
   }
 };
 
@@ -3806,7 +4052,7 @@ function d3_geo_pathContext(context) {
 
   function point(x, y) {
     context.moveTo(x, y);
-    context.arc(x, y, pointRadius, 0, 2 * π);
+    context.arc(x, y, pointRadius, 0, τ);
   }
 
   function pointLineStart(x, y) {
@@ -3898,7 +4144,7 @@ function d3_geo_resample(project) {
           c = c0 + c1,
           m = Math.sqrt(a * a + b * b + c * c),
           φ2 = Math.asin(c /= m),
-          λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a),
+          λ2 = abs(abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a),
           p = project(λ2, φ2),
           x2 = p[0],
           y2 = p[1],
@@ -3906,7 +4152,7 @@ function d3_geo_resample(project) {
           dy2 = y2 - y0,
           dz = dy * dx2 - dx * dy2;
       if (dz * dz / d2 > δ2 // perpendicular projected distance
-          || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 // midpoint close to an end
+          || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 // midpoint close to an end
           || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
         resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream);
         stream.point(x2, y2);
@@ -3924,6 +4170,29 @@ function d3_geo_resample(project) {
   return resample;
 }
 
+d3.geo.transform = function(methods) {
+  return {
+    stream: function(stream) {
+      var transform = new d3_geo_transform(stream);
+      for (var k in methods) transform[k] = methods[k];
+      return transform;
+    }
+  };
+};
+
+function d3_geo_transform(stream) {
+  this.stream = stream;
+}
+
+d3_geo_transform.prototype = {
+  point: function(x, y) { this.stream.point(x, y); },
+  sphere: function() { this.stream.sphere(); },
+  lineStart: function() { this.stream.lineStart(); },
+  lineEnd: function() { this.stream.lineEnd(); },
+  polygonStart: function() { this.stream.polygonStart(); },
+  polygonEnd: function() { this.stream.polygonEnd(); }
+};
+
 d3.geo.path = function() {
   var pointRadius = 4.5,
       projection,
@@ -3992,17 +4261,11 @@ d3.geo.path = function() {
 };
 
 function d3_geo_pathProjectStream(project) {
-  var resample = d3_geo_resample(function(λ, φ) { return project([λ * d3_degrees, φ * d3_degrees]); });
+  var resample = d3_geo_resample(function(x, y) { return project([x * d3_degrees, y * d3_degrees]); });
   return function(stream) {
-    stream = resample(stream);
-    return {
-      point: function(λ, φ) { stream.point(λ * d3_radians, φ * d3_radians); },
-      sphere: function() { stream.sphere(); },
-      lineStart: function() { stream.lineStart(); },
-      lineEnd: function() { stream.lineEnd(); },
-      polygonStart: function() { stream.polygonStart(); },
-      polygonEnd: function() { stream.polygonEnd(); }
-    };
+    var transform = new d3_geo_transform(stream = resample(stream));
+    transform.point = function(x, y) { stream.point(x * d3_radians, y * d3_radians); };
+    return transform;
   };
 }
 
@@ -4041,7 +4304,7 @@ function d3_geo_projectionMutator(projectAt) {
 
   projection.stream = function(output) {
     if (stream) stream.valid = false;
-    stream = d3_geo_projectionRadiansRotate(rotate, preclip(projectResample(postclip(output))));
+    stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output))));
     stream.valid = true; // allow caching by d3.geo.path
     return stream;
   };
@@ -4055,7 +4318,7 @@ function d3_geo_projectionMutator(projectAt) {
   projection.clipExtent = function(_) {
     if (!arguments.length) return clipExtent;
     clipExtent = _;
-    postclip = _ == null ? d3_identity : d3_geo_clipView(_[0][0], _[0][1], _[1][0], _[1][1]);
+    postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity;
     return invalidate();
   };
 
@@ -4098,10 +4361,7 @@ function d3_geo_projectionMutator(projectAt) {
   }
 
   function invalidate() {
-    if (stream) {
-      stream.valid = false;
-      stream = null;
-    }
+    if (stream) stream.valid = false, stream = null;
     return projection;
   }
 
@@ -4112,18 +4372,12 @@ function d3_geo_projectionMutator(projectAt) {
   };
 }
 
-function d3_geo_projectionRadiansRotate(rotate, stream) {
-  return {
-    point: function(x, y) {
-      y = rotate(x * d3_radians, y * d3_radians), x = y[0];
-      stream.point(x > π ? x - 2 * π : x < -π ? x + 2 * π : x, y[1]);
-    },
-    sphere: function() { stream.sphere(); },
-    lineStart: function() { stream.lineStart(); },
-    lineEnd: function() { stream.lineEnd(); },
-    polygonStart: function() { stream.polygonStart(); },
-    polygonEnd: function() { stream.polygonEnd(); }
+function d3_geo_projectionRadians(stream) {
+  var transform = new d3_geo_transform(stream);
+  transform.point = function(λ, φ) {
+    stream.point(λ * d3_radians, φ * d3_radians);
   };
+  return transform;
 }
 
 function d3_geo_mercator(λ, φ) {
@@ -4131,7 +4385,7 @@ function d3_geo_mercator(λ, φ) {
 }
 
 d3_geo_mercator.invert = function(x, y) {
-  return [x, 2 * Math.atan(Math.exp(y)) - π / 2];
+  return [x, 2 * Math.atan(Math.exp(y)) - halfπ];
 };
 
 function d3_geo_mercatorProjection(project) {
@@ -4303,7 +4557,7 @@ d3.ease = function(name) {
       m = i >= 0 ? name.substring(i + 1) : "in";
   t = d3_ease.get(t) || d3_ease_default;
   m = d3_ease_mode.get(m) || d3_identity;
-  return d3_ease_clamp(m(t.apply(null, Array.prototype.slice.call(arguments, 1))));
+  return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1))));
 };
 
 function d3_ease_clamp(f) {
@@ -4347,7 +4601,7 @@ function d3_ease_poly(e) {
 }
 
 function d3_ease_sin(t) {
-  return 1 - Math.cos(t * π / 2);
+  return 1 - Math.cos(t * halfπ);
 }
 
 function d3_ease_exp(t) {
@@ -4361,10 +4615,10 @@ function d3_ease_circle(t) {
 function d3_ease_elastic(a, p) {
   var s;
   if (arguments.length < 2) p = 0.45;
-  if (arguments.length) s = p / (2 * π) * Math.asin(1 / a);
+  if (arguments.length) s = p / τ * Math.asin(1 / a);
   else a = 1, s = p / 4;
   return function(t) {
-    return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * π / p);
+    return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * τ / p);
   };
 }
 
@@ -5379,7 +5633,7 @@ function d3_transition_text(b) {
 d3_transitionPrototype.remove = function() {
   return this.each("end.transition", function() {
     var p;
-    if (!this.__transition__ && (p = this.parentNode)) p.removeChild(this);
+    if (this.__transition__.count < 2 && (p = this.parentNode)) p.removeChild(this);
   });
 };
 
@@ -5393,15 +5647,15 @@ d3_transitionPrototype.ease = function(value) {
 d3_transitionPrototype.delay = function(value) {
   var id = this.id;
   return d3_selection_each(this, typeof value === "function"
-      ? function(node, i, j) { node.__transition__[id].delay = value.call(node, node.__data__, i, j) | 0; }
-      : (value |= 0, function(node) { node.__transition__[id].delay = value; }));
+      ? function(node, i, j) { node.__transition__[id].delay = +value.call(node, node.__data__, i, j); }
+      : (value = +value, function(node) { node.__transition__[id].delay = value; }));
 };
 
 d3_transitionPrototype.duration = function(value) {
   var id = this.id;
   return d3_selection_each(this, typeof value === "function"
-      ? function(node, i, j) { node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j) | 0); }
-      : (value = Math.max(1, value | 0), function(node) { node.__transition__[id].duration = value; }));
+      ? function(node, i, j) { node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j)); }
+      : (value = Math.max(1, value), function(node) { node.__transition__[id].duration = value; }));
 };
 
 d3_transitionPrototype.each = function(type, listener) {
@@ -5471,10 +5725,12 @@ function d3_transitionNode(node, i, id, inherit) {
           ease = transition.ease,
           delay = transition.delay,
           duration = transition.duration,
+          timer = d3_timer_active,
           tweened = [];
 
-      if (delay <= elapsed) return start(elapsed);
-      d3_timer_replace(start, delay, time);
+      timer.t = delay + time;
+      if (delay <= elapsed) return start(elapsed - delay);
+      timer.c = start;
 
       function start(elapsed) {
         if (lock.active > id) return stop();
@@ -5487,14 +5743,16 @@ function d3_transitionNode(node, i, id, inherit) {
           }
         });
 
-        if (tick(elapsed)) return 1;
-        d3_timer_replace(tick, 0, time);
+        d3.timer(function() { // defer to end of current frame
+          timer.c = tick(elapsed || 1) ? d3_true : tick;
+          return 1;
+        }, 0, time);
       }
 
       function tick(elapsed) {
         if (lock.active !== id) return stop();
 
-        var t = (elapsed - delay) / duration,
+        var t = elapsed / duration,
             e = ease(t),
             n = tweened.length;
 
@@ -5503,9 +5761,8 @@ function d3_transitionNode(node, i, id, inherit) {
         }
 
         if (t >= 1) {
-          stop();
           transition.event && transition.event.end.call(node, d, i);
-          return 1;
+          return stop();
         }
       }
 
@@ -5529,7 +5786,7 @@ function d3_xhrType(response) {
 
 function d3_xhr(url, mimeType, response, callback) {
   var xhr = {},
-      dispatch = d3.dispatch("progress", "load", "error"),
+      dispatch = d3.dispatch("beforesend", "progress", "load", "error"),
       headers = {},
       request = new XMLHttpRequest,
       responseType = null;
@@ -5611,6 +5868,7 @@ function d3_xhr(url, mimeType, response, callback) {
     if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType);
     if (responseType != null) request.responseType = responseType;
     if (callback != null) xhr.on("error", callback).on("load", function(request) { callback(null, request); });
+    dispatch.beforesend.call(xhr, request);
     request.send(data == null ? null : data);
     return xhr;
   };
@@ -5690,25 +5948,26 @@ d3.combobox = function() {
                 var parent = this.parentNode,
                     sibling = this.nextSibling;
 
-                var carat = d3.select(parent).selectAll('.combobox-carat')
+                var caret = d3.select(parent).selectAll('.combobox-caret')
                     .filter(function(d) { return d === input.node(); })
                     .data([input.node()]);
 
-                carat.enter().insert('div', function() { return sibling; })
-                    .attr('class', 'combobox-carat');
+                caret.enter().insert('div', function() { return sibling; })
+                    .attr('class', 'combobox-caret');
 
-                carat
+                caret
                     .on('mousedown', function () {
                         // prevent the form element from blurring. it blurs
                         // on mousedown
                         d3.event.stopPropagation();
                         d3.event.preventDefault();
                         input.node().focus();
+                        fetch('', render);
                     });
             });
 
         function focus() {
-            fetch(render);
+            fetch(value(), render);
         }
 
         function blur() {
@@ -5798,7 +6057,7 @@ d3.combobox = function() {
         }
 
         function change() {
-            fetch(function() {
+            fetch(value(), function() {
                 autocomplete();
                 render();
             });
@@ -5823,8 +6082,8 @@ d3.combobox = function() {
             return value;
         }
 
-        function fetch(cb) {
-            fetcher.call(input, value(), function(_) {
+        function fetch(v, cb) {
+            fetcher.call(input, v, function(_) {
                 suggestions = _;
                 cb();
             });
@@ -5849,7 +6108,7 @@ d3.combobox = function() {
         }
 
         function render() {
-            if (suggestions.length && document.activeElement === input.node()) {
+            if (suggestions.length > 1 && document.activeElement === input.node()) {
                 show();
             } else {
                 hide();
@@ -15318,9 +15577,52 @@ window.iD = function () {
     };
 
     /* Projection */
-    context.projection = d3.geo.mercator()
-        .scale(512 / Math.PI)
-        .precision(0);
+    function rawMercator() {
+        var project = d3.geo.mercator.raw,
+            k = 512 / Math.PI, // scale
+            x = 0, y = 0, // translate
+            clipExtent = [[0, 0], [0, 0]];
+
+        function projection(point) {
+            point = project(point[0] * Math.PI / 180, point[1] * Math.PI / 180);
+            return [point[0] * k + x, y - point[1] * k];
+        }
+
+        projection.invert = function(point) {
+            point = project.invert((point[0] - x) / k, (y - point[1]) / k);
+            return point && [point[0] * 180 / Math.PI, point[1] * 180 / Math.PI];
+        };
+
+        projection.scale = function(_) {
+            if (!arguments.length) return k;
+            k = +_;
+            return projection;
+        };
+
+        projection.translate = function(_) {
+            if (!arguments.length) return [x, y];
+            x = +_[0];
+            y = +_[1];
+            return projection;
+        };
+
+        projection.clipExtent = function(_) {
+            if (!arguments.length) return clipExtent;
+            clipExtent = _;
+            return projection;
+        };
+
+        projection.stream = d3.geo.transform({
+            point: function(x, y) {
+                x = projection([x, y]);
+                this.stream.point(x[0], x[1]);
+            }
+        }).stream;
+
+        return projection;
+    }
+
+    context.projection = rawMercator();
 
     /* Background */
     var background = iD.Background(context);
@@ -15388,7 +15690,7 @@ window.iD = function () {
     return d3.rebind(context, dispatch, 'on');
 };
 
-iD.version = '1.2.1';
+iD.version = '1.3.0';
 
 (function() {
     var detected = {};
@@ -15774,6 +16076,42 @@ iD.util.wrap = function(index, length) {
         index += Math.ceil(-index/length)*length;
     return index % length;
 };
+// A per-domain session mutex backed by a cookie and dead man's
+// switch. If the session crashes, the mutex will auto-release
+// after 5 seconds.
+
+iD.util.SessionMutex = function(name) {
+    var mutex = {},
+        intervalID;
+
+    function renew() {
+        var expires = new Date();
+        expires.setSeconds(expires.getSeconds() + 5);
+        document.cookie = name + '=1; expires=' + expires.toUTCString();
+    }
+
+    mutex.lock = function() {
+        if (intervalID) return true;
+        var cookie = document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + name + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1");
+        if (cookie) return false;
+        renew();
+        intervalID = window.setInterval(renew, 4000);
+        return true;
+    };
+
+    mutex.unlock = function() {
+        if (!intervalID) return;
+        document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
+        clearInterval(intervalID);
+        intervalID = null;
+    };
+
+    mutex.locked = function() {
+        return !!intervalID;
+    };
+
+    return mutex;
+};
 iD.geo = {};
 
 iD.geo.roundCoords = function(c) {
@@ -15797,6 +16135,11 @@ iD.geo.sphericalDistance = function(a, b) {
     return 6.3710E6 * Math.sqrt((x * x) + (y * y)) * Math.PI/180;
 };
 
+iD.geo.edgeEqual = function(a, b) {
+    return (a[0] === b[0] && a[1] === b[1]) ||
+        (a[0] === b[1] && a[1] === b[0]);
+};
+
 // Choose the edge with the minimal distance from `point` to its orthogonal
 // projection onto that edge, if such a projection exists, or the distance to
 // the closest vertex on that edge. Returns an object with the `index` of the
@@ -16200,10 +16543,7 @@ iD.actions.AddMidpoint = function(midpoint, node) {
 
         parents.forEach(function(way) {
             for (var i = 0; i < way.nodes.length - 1; i++) {
-                if ((way.nodes[i]     === midpoint.edge[0] &&
-                     way.nodes[i + 1] === midpoint.edge[1]) ||
-                    (way.nodes[i]     === midpoint.edge[1] &&
-                     way.nodes[i + 1] === midpoint.edge[0])) {
+                if (iD.geo.edgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) {
                     graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1));
 
                     // Add only one midpoint on doubled-back segments,
@@ -17569,7 +17909,7 @@ iD.behavior.drag = function() {
             touchId = d3.event.touches ? d3.event.changedTouches[0].identifier : null,
             offset,
             origin_ = point(),
-            moved = 0,
+            started = false,
             selectEnable = d3_event_userSelectSuppress(touchId != null ? "drag-" + touchId : "drag");
 
         var w = d3.select(window)
@@ -17598,13 +17938,13 @@ iD.behavior.drag = function() {
                 dx = p[0] - origin_[0],
                 dy = p[1] - origin_[1];
 
-            if (!moved) {
+            if (!started) {
+                started = true;
                 event_({
                     type: "start"
                 });
             }
 
-            moved |= dx | dy;
             origin_ = p;
             d3_eventCancel();
 
@@ -17616,7 +17956,7 @@ iD.behavior.drag = function() {
         }
 
         function dragend() {
-            if (moved) {
+            if (started) {
                 event_({
                     type: "end"
                 });
@@ -17971,12 +18311,13 @@ iD.behavior.DrawWay = function(context, wayId, index, mode, baseGraph) {
 
     // Connect the way to an existing way.
     drawWay.addWay = function(loc, edge) {
+        var previousEdge = startIndex ?
+            [way.nodes[startIndex], way.nodes[startIndex - 1]] :
+            [way.nodes[0], way.nodes[1]];
 
         // Avoid creating duplicate segments
-        if (!isArea) {
-            if (edge[0] === way.nodes[way.nodes.length - 1] ||
-                edge[1] === way.nodes[way.nodes.length - 1]) return;
-        }
+        if (!isArea && iD.geo.edgeEqual(edge, previousEdge))
+            return;
 
         var newNode = iD.Node({ loc: loc });
 
@@ -18806,7 +19147,7 @@ iD.modes.DragNode = function(context) {
         var d = datum();
         if (d.type === 'node' && d.id !== entity.id) {
             loc = d.loc;
-        } else if (d.type === 'way') {
+        } else if (d.type === 'way' && !d3.select(d3.event.sourceEvent.target).classed('fill')) {
             loc = iD.geo.chooseEdge(context.childNodes(d), context.mouse(), context.projection).loc;
         }
 
@@ -19193,18 +19534,12 @@ iD.modes.RotateWay = function(context, wayId) {
 iD.modes.Save = function(context) {
     var ui = iD.ui.Commit(context)
         .on('cancel', cancel)
-        .on('fix', fix)
         .on('save', save);
 
     function cancel() {
         context.enter(iD.modes.Browse(context));
     }
 
-    function fix(d) {
-        context.map().zoomTo(d.entity);
-        context.enter(iD.modes.Select(context, [d.entity.id]));
-    }
-
     function save(e) {
         var loading = iD.ui.Loading(context)
             .message(t('save.uploading'))
@@ -19451,6 +19786,11 @@ iD.modes.Select = function(context, selectedIDs) {
             context.surface()
                 .on('dblclick.select', dblclick);
         }, 200);
+
+        if (selectedIDs.length > 1) {
+            var entities = iD.ui.SelectionList(context, selectedIDs);
+            context.ui().sidebar.show(entities);
+        }
     };
 
     mode.exit = function() {
@@ -19478,6 +19818,7 @@ iD.modes.Select = function(context, selectedIDs) {
             .classed('selected', false);
 
         context.map().on('drawn.select', null);
+        context.ui().sidebar.hide();
     };
 
     return mode;
@@ -20414,7 +20755,6 @@ iD.Difference = function(base, head) {
     };
 
     difference.addParents = function(entities) {
-
         for (var i in entities) {
             addParents(head.parentWays(entities[i]), entities);
             addParents(head.parentRelations(entities[i]), entities);
@@ -20422,6 +20762,55 @@ iD.Difference = function(base, head) {
         return entities;
     };
 
+    difference.summary = function() {
+        var relevant = {};
+
+        function addEntity(entity, graph, changeType) {
+            relevant[entity.id] = {
+                entity: entity,
+                graph: graph,
+                changeType: changeType
+            };
+        }
+
+        function addParents(entity) {
+            var parents = head.parentWays(entity);
+            for (var j = parents.length - 1; j >= 0; j--) {
+                var parent = parents[j];
+                if (!(parent.id in relevant)) addEntity(parent, head, 'modified');
+            }
+        }
+
+        _.each(changes, function(change) {
+            if (change.head && change.head.geometry(head) !== 'vertex') {
+                addEntity(change.head, head, change.base ? 'modified' : 'created');
+
+            } else if (change.base && change.base.geometry(base) !== 'vertex') {
+                addEntity(change.base, base, 'deleted');
+
+            } else if (change.base && change.head) { // modified vertex
+                var moved    = !_.isEqual(change.base.loc,  change.head.loc),
+                    retagged = !_.isEqual(change.base.tags, change.head.tags);
+
+                if (moved) {
+                    addParents(change.head);
+                }
+
+                if (retagged || (moved && change.head.hasInterestingTags())) {
+                    addEntity(change.head, head, 'modified');
+                }
+
+            } else if (change.head && change.head.hasInterestingTags()) { // created vertex
+                addEntity(change.head, head, 'created');
+
+            } else if (change.base && change.base.hasInterestingTags()) { // deleted vertex
+                addEntity(change.base, base, 'deleted');
+            }
+        });
+
+        return d3.values(relevant);
+    };
+
     difference.complete = function(extent) {
         var result = {}, id, change;
 
@@ -20881,7 +21270,7 @@ iD.History = function(context) {
     var stack, index, tree,
         imageryUsed = ['Bing'],
         dispatch = d3.dispatch('change', 'undone', 'redone'),
-        lock = false;
+        lock = iD.util.SessionMutex('lock');
 
     function perform(actions) {
         actions = Array.prototype.slice.call(actions);
@@ -21037,10 +21426,6 @@ iD.History = function(context) {
             return this.difference().length() > 0;
         },
 
-        numChanges: function() {
-            return this.difference().length();
-        },
-
         imageryUsed: function(sources) {
             if (sources) {
                 imageryUsed = sources;
@@ -21152,39 +21537,37 @@ iD.History = function(context) {
         },
 
         save: function() {
-            if (!lock) return history;
-            context.storage(getKey('lock'), null);
-            context.storage(getKey('saved_history'), this.toJSON() || null);
+            if (lock.locked()) context.storage(getKey('saved_history'), history.toJSON() || null);
             return history;
         },
 
         clearSaved: function() {
-            if (!lock) return;
-            context.storage(getKey('saved_history'), null);
+            if (lock.locked()) context.storage(getKey('saved_history'), null);
+            return history;
         },
 
         lock: function() {
-            if (context.storage(getKey('lock'))) return false;
-            context.storage(getKey('lock'), true);
-            lock = true;
-            return lock;
+            return lock.lock();
+        },
+
+        unlock: function() {
+            lock.unlock();
         },
 
         // is iD not open in another window and it detects that
         // there's a history stored in localStorage that's recoverable?
         restorableChanges: function() {
-            return lock && !!context.storage(getKey('saved_history'));
+            return lock.locked() && !!context.storage(getKey('saved_history'));
         },
 
         // load history from a version stored in localStorage
         restore: function() {
-            if (!lock) return;
+            if (!lock.locked()) return;
 
             var json = context.storage(getKey('saved_history'));
-            if (json) this.fromJSON(json);
+            if (json) history.fromJSON(json);
 
             context.storage(getKey('saved_history', null));
-
         },
 
         _getKey: getKey
@@ -21252,12 +21635,8 @@ _.extend(iD.Node.prototype, {
 
     asGeoJSON: function() {
         return {
-            type: 'Feature',
-            properties: this.tags,
-            geometry: {
-                type: 'Point',
-                coordinates: this.loc
-            }
+            type: 'Point',
+            coordinates: this.loc
         };
     }
 });
@@ -21404,12 +21783,8 @@ _.extend(iD.Relation.prototype, {
         return resolver.transient(this, 'GeoJSON', function () {
             if (this.isMultipolygon()) {
                 return {
-                    type: 'Feature',
-                    properties: this.tags,
-                    geometry: {
-                        type: 'MultiPolygon',
-                        coordinates: this.multipolygon(resolver)
-                    }
+                    type: 'MultiPolygon',
+                    coordinates: this.multipolygon(resolver)
                 };
             } else {
                 return {
@@ -21765,29 +22140,21 @@ _.extend(iD.Way.prototype, {
                 }
 
                 var json = {
-                    type: 'Feature',
-                    properties: this.tags,
-                    geometry: {
-                        type: 'Polygon',
-                        coordinates: [_.pluck(nodes, 'loc')]
-                    }
+                    type: 'Polygon',
+                    coordinates: [_.pluck(nodes, 'loc')]
                 };
 
                 // Heuristic for detecting counterclockwise winding order. Assumes
                 // that OpenStreetMap polygons are not hemisphere-spanning.
                 if (d3.geo.area(json) > 2 * Math.PI) {
-                    json.geometry.coordinates[0] = json.geometry.coordinates[0].reverse();
+                    json.coordinates[0] = json.coordinates[0].reverse();
                 }
 
                 return json;
             } else {
                 return {
-                    type: 'Feature',
-                    properties: this.tags,
-                    geometry: {
-                        type: 'LineString',
-                        coordinates: _.pluck(nodes, 'loc')
-                    }
+                    type: 'LineString',
+                    coordinates: _.pluck(nodes, 'loc')
                 };
             }
         });
@@ -21835,6 +22202,8 @@ iD.Background = function(context) {
         }
     });
 
+    backgroundSources.unshift(iD.BackgroundSource.None());
+
     function findSource(id) {
         return _.find(backgroundSources, function(d) {
             return d.id && d.id === id;
@@ -21954,6 +22323,23 @@ iD.Background = function(context) {
         return background.hasGpxLayer() && gpxLayer.enable();
     };
 
+    function toDom(x) {
+        return (new DOMParser()).parseFromString(x, 'text/xml');
+    }
+
+    background.gpxLayerFiles = function(fileList) {
+        var f = fileList[0],
+            reader = new FileReader();
+
+        reader.onload = function(e) {
+            gpxLayer.geojson(toGeoJSON.gpx(toDom(e.target.result)));
+            dispatch.change();
+            context.map().pan([0, 0]);
+        };
+
+        reader.readAsText(f);
+    };
+
     background.zoomToGpxLayer = function() {
         if (background.hasGpxLayer()) {
             context.map()
@@ -21972,6 +22358,10 @@ iD.Background = function(context) {
             overlayLayers.some(function(l) { return l.source() === d; });
     };
 
+    background.overlayLayerSources = function() {
+        return overlayLayers.map(function (l) { return l.source(); });
+    };
+
     background.toggleOverlayLayer = function(d) {
         var layer;
 
@@ -22150,6 +22540,10 @@ iD.BackgroundSource.Bing = function(data, dispatch) {
 
     return bing;
 };
+
+iD.BackgroundSource.None = function() {
+    return iD.BackgroundSource({ name: t('background.none'), id: 'None', template: '' });
+};
 iD.GpxLayer = function(context, dispatch) {
     var projection,
         gj = {},
@@ -22205,10 +22599,6 @@ iD.GpxLayer = function(context, dispatch) {
         }
     }
 
-    function toDom(x) {
-        return (new DOMParser()).parseFromString(x, 'text/xml');
-    }
-
     render.projection = function(_) {
         if (!arguments.length) return projection;
         projection = _;
@@ -22247,16 +22637,7 @@ iD.GpxLayer = function(context, dispatch) {
             d3.event.stopPropagation();
             d3.event.preventDefault();
             if (!iD.detect().filedrop) return;
-            var f = d3.event.dataTransfer.files[0],
-                reader = new FileReader();
-
-            reader.onload = function(e) {
-                render.geojson(toGeoJSON.gpx(toDom(e.target.result)));
-                dispatch.change();
-                context.map().pan([0, 0]);
-            };
-
-            reader.readAsText(f);
+            context.background().gpxLayerFiles(d3.event.dataTransfer.files);
         })
         .on('dragenter.localgpx', over)
         .on('dragexit.localgpx', over)
@@ -22282,9 +22663,9 @@ iD.Map = function(context) {
         points = iD.svg.Points(roundedProjection, context),
         vertices = iD.svg.Vertices(roundedProjection, context),
         lines = iD.svg.Lines(projection),
-        areas = iD.svg.Areas(roundedProjection),
+        areas = iD.svg.Areas(projection),
         midpoints = iD.svg.Midpoints(roundedProjection, context),
-        labels = iD.svg.Labels(roundedProjection, context),
+        labels = iD.svg.Labels(projection, context),
         supersurface, surface,
         mouse,
         mousemove;
@@ -22535,10 +22916,10 @@ iD.Map = function(context) {
         return map;
     };
 
-    function setZoom(z, force) {
-        if (z === map.zoom() && !force)
+    function setZoom(_, force) {
+        if (_ === map.zoom() && !force)
             return false;
-        var scale = 256 * Math.pow(2, z),
+        var scale = 256 * Math.pow(2, _),
             center = pxCenter(),
             l = pointLocation(center);
         scale = Math.max(1024, Math.min(256 * Math.pow(2, 24), scale));
@@ -22553,15 +22934,16 @@ iD.Map = function(context) {
         return true;
     }
 
-    function setCenter(loc) {
-        var t = projection.translate(),
-            c = pxCenter(),
-            ll = projection(loc);
-        if (ll[0] === c[0] && ll[1] === c[1])
+    function setCenter(_) {
+        var c = map.center();
+        if (_[0] === c[0] && _[1] === c[1])
             return false;
+        var t = projection.translate(),
+            pxC = pxCenter(),
+            ll = projection(_);
         projection.translate([
-            t[0] - ll[0] + c[0],
-            t[1] - ll[1] + c[1]]);
+            t[0] - ll[0] + pxC[0],
+            t[1] - ll[1] + pxC[1]]);
         zoom.translate(projection.translate());
         return true;
     }
@@ -22757,6 +23139,7 @@ iD.TileLayer = function() {
         if (source.validZoom(z)) {
             tile().forEach(function(d) {
                 addSource(d);
+                if (d[3] === '') return;
                 requests.push(d);
                 if (cache[d[3]] === false && lookUp(d)) {
                     requests.push(addSource(lookUp(d)));
@@ -22865,29 +23248,27 @@ iD.svg = {
         };
     },
 
+    Round: function () {
+        return d3.geo.transform({
+            point: function(x, y) { return this.stream.point(Math.floor(x), Math.floor(y)); }
+        });
+    },
+
     Path: function(projection, graph, polygon) {
         var cache = {},
-            path = d3.geo.path().projection(projection);
-
-        function result(entity) {
-            if (entity.id in cache) return cache[entity.id];
+            round = iD.svg.Round().stream,
+            clip = d3.geo.clipExtent().extent(projection.clipExtent()).stream,
+            project = projection.stream,
+            path = d3.geo.path()
+                .projection({stream: function(output) { return polygon ? project(round(output)) : project(clip(round(output))); }});
 
-            var buffer = '';
-
-            path.context({
-                beginPath: function() {},
-                moveTo: function(x, y) { buffer += 'M' + Math.floor(x) + ',' + Math.floor(y); },
-                lineTo: function(x, y) { buffer += 'L' + Math.floor(x) + ',' + Math.floor(y); },
-                arc: function() {},
-                closePath: function() { buffer += 'Z'; }
-            });
-
-            path(entity.asGeoJSON(graph, polygon));
-
-            return cache[entity.id] = buffer;
-        }
-
-        return result;
+        return function(entity) {
+            if (entity.id in cache) {
+                return cache[entity.id];
+            } else {
+                return cache[entity.id] = path(entity.asGeoJSON(graph, polygon));
+            }
+        };
     },
 
     OneWaySegments: function(projection, graph, dt) {
@@ -22962,7 +23343,8 @@ iD.svg = {
     }
 };
 iD.svg.Areas = function(projection) {
-    // Patterns only work in Firefox when set directly on element
+    // Patterns only work in Firefox when set directly on element.
+    // (This is not a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=750632)
     var patterns = {
         wetland: 'wetland',
         beach: 'beach',
@@ -23024,23 +23406,28 @@ iD.svg.Areas = function(projection) {
             fill: areas
         };
 
+        var paths = surface.selectAll('.layer-shadow, .layer-stroke, .layer-fill')
+            .selectAll('path.area')
+            .filter(filter)
+            .data(function(layer) { return data[layer]; }, iD.Entity.key);
+
+        // Remove exiting areas first, so they aren't included in the `fills`
+        // array used for sorting below (https://github.com/systemed/iD/issues/1903).
+        paths.exit()
+            .remove();
+
+        var fills = surface.selectAll('.layer-fill path.area')[0];
+
         var bisect = d3.bisector(function(node) {
             return -node.__data__.area(graph);
         }).left;
 
-        var fills = surface.selectAll('.layer-fill path.area')[0];
-
         function sortedByArea(entity) {
             if (this.__data__ === 'fill') {
                 return fills[bisect(fills, -entity.area(graph))];
             }
         }
 
-        var paths = surface.selectAll('.layer-shadow, .layer-stroke, .layer-fill')
-            .selectAll('path.area')
-            .filter(filter)
-            .data(function(layer) { return data[layer]; }, iD.Entity.key);
-
         paths.enter()
             .insert('path', sortedByArea)
             .each(function(entity) {
@@ -23056,12 +23443,10 @@ iD.svg.Areas = function(projection) {
 
         paths
             .attr('d', path);
-
-        paths.exit()
-            .remove();
     };
 };
 iD.svg.Labels = function(projection, context) {
+    var path = d3.geo.path().projection(projection);
 
     // Replace with dict and iterate over entities tags instead?
     var label_stack = [
@@ -23431,8 +23816,7 @@ iD.svg.Labels = function(projection, context) {
         }
 
         function getAreaLabel(entity, width, height) {
-            var path = d3.geo.path().projection(projection),
-                centroid = path.centroid(entity.asGeoJSON(graph, true)),
+            var centroid = path.centroid(entity.asGeoJSON(graph, true)),
                 extent = entity.extent(graph),
                 entitywidth = projection(extent[1])[0] - projection(extent[0])[0],
                 rect;
@@ -23934,11 +24318,15 @@ iD.svg.Surface = function(context) {
     };
 };
 iD.svg.TagClasses = function() {
-    var keys = d3.set([
-        'highway', 'railway', 'waterway', 'power', 'motorway', 'amenity',
-        'natural', 'landuse', 'building', 'oneway', 'bridge', 'boundary',
-        'tunnel', 'leisure', 'construction', 'place', 'aeroway'
-    ]), tagClassRe = /^tag-/,
+    var primary = [
+            'highway', 'railway', 'waterway', 'aeroway', 'motorway',
+            'power', 'amenity', 'natural', 'landuse', 'building', 'leisure',
+            'place', 'boundary'
+        ],
+        secondary = [
+            'oneway', 'bridge', 'tunnel', 'construction'
+        ],
+        tagClassRe = /^tag-/,
         tags = function(entity) { return entity.tags; };
 
     var tagClasses = function(selection) {
@@ -23951,10 +24339,21 @@ iD.svg.TagClasses = function() {
                 return name.length && !tagClassRe.test(name);
             }).join(' ');
 
-            var t = tags(entity);
-            for (var k in t) {
-                if (!keys.has(k) || t[k] === 'no') continue;
-                classes += ' tag-' + k + ' tag-' + k + '-' + t[k];
+            var t = tags(entity), i, k, v;
+
+            for (i = 0; i < primary.length; i++) {
+                k = primary[i];
+                v = t[k];
+                if (!v || v === 'no') continue;
+                classes += ' tag-' + k + ' tag-' + k + '-' + v;
+                break;
+            }
+
+            for (i = 0; i < secondary.length; i++) {
+                k = secondary[i];
+                v = t[k];
+                if (!v || v === 'no') continue;
+                classes += ' tag-' + k + ' tag-' + k + '-' + v;
             }
 
             classes = classes.trim();
@@ -24175,9 +24574,7 @@ iD.ui = function(context) {
             .attr('class', 'spinner')
             .call(iD.ui.Spinner(context));
 
-        content.append('div')
-            .attr('class', 'attribution')
-            .attr('tabindex', -1)
+        content
             .call(iD.ui.Attribution(context));
 
         content.append('div')
@@ -24250,6 +24647,10 @@ iD.ui = function(context) {
             return context.save();
         };
 
+        window.onunload = function() {
+            context.history().unlock();
+        };
+
         d3.select(window).on('resize.editor', function() {
             map.dimensions(m.dimensions());
         });
@@ -24363,19 +24764,27 @@ iD.ui.Account = function(context) {
 iD.ui.Attribution = function(context) {
     var selection;
 
-    function update() {
-        if (!context.background().baseLayerSource()) {
-            selection.html('');
-            return;
-        }
+    function attribution(data, klass) {
+        var div = selection.selectAll('.' + klass)
+            .data([0]);
 
-        var attribution = selection.selectAll('.provided-by')
-            .data([context.background().baseLayerSource()], function(d) { return d.name; });
+        div.enter()
+            .append('div')
+            .attr('class', klass);
 
-        attribution.enter()
+        var background = div.selectAll('.attribution')
+            .data(data, function(d) { return d.name; });
+
+        background.enter()
             .append('span')
-            .attr('class', 'provided-by')
+            .attr('class', 'attribution')
             .each(function(d) {
+                if (d.terms_html) {
+                    d3.select(this)
+                        .html(d.terms_html);
+                    return;
+                }
+
                 var source = d.terms_text || d.id || d.name;
 
                 if (d.logo) {
@@ -24394,10 +24803,10 @@ iD.ui.Attribution = function(context) {
                 }
             });
 
-        attribution.exit()
+        background.exit()
             .remove();
 
-        var copyright = attribution.selectAll('.copyright-notice')
+        var copyright = background.selectAll('.copyright-notice')
             .data(function(d) {
                 var notice = d.copyrightNotices(context.map().zoom(), context.map().extent());
                 return notice ? [notice] : [];
@@ -24413,6 +24822,13 @@ iD.ui.Attribution = function(context) {
             .remove();
     }
 
+    function update() {
+        attribution([context.background().baseLayerSource()], 'base-layer-attribution');
+        attribution(context.background().overlayLayerSources().filter(function (s) {
+            return s.validZoom(context.map().zoom());
+        }), 'overlay-layer-attribution');
+    }
+
     return function(select) {
         selection = select;
 
@@ -24427,13 +24843,13 @@ iD.ui.Attribution = function(context) {
 };
 iD.ui.Background = function(context) {
     var key = 'b',
-        opacities = [1, 0.5, 0],
+        opacities = [1, 0.75, 0.5, 0.25],
         directions = [
             ['left', [1, 0]],
             ['top', [0, -1]],
             ['right', [-1, 0]],
             ['bottom', [0, 1]]],
-        opacityDefault = (context.storage('background-opacity') != undefined) ?
+        opacityDefault = (context.storage('background-opacity') !== undefined) ?
             (+context.storage('background-opacity')) : 0.5;
 
     function background(selection) {
@@ -24455,7 +24871,7 @@ iD.ui.Background = function(context) {
                 return context.background().showsLayer(d);
             }
 
-            content.selectAll('label.layer, label.custom_layer')
+            content.selectAll('.layer, .custom_layer')
                 .classed('active', active)
                 .selectAll('input')
                 .property('checked', active);
@@ -24470,7 +24886,9 @@ iD.ui.Background = function(context) {
         function clickCustom() {
             d3.event.preventDefault();
             var template = window.prompt(t('background.custom_prompt'));
-            if (!template) {
+            if (!template || template.indexOf('google.com') !== -1 ||
+               template.indexOf('googleapis.com') !== -1 ||
+               template.indexOf('google.ru') !== -1) {
                 selectLayer();
                 return;
             }
@@ -24497,33 +24915,33 @@ iD.ui.Background = function(context) {
                 .sources(context.map().extent())
                 .filter(filter);
 
-            var layerLinks = layerList.selectAll('label.layer')
+            var layerLinks = layerList.selectAll('li.layer')
                 .data(sources, function(d) { return d.name; });
 
-            var layerInner = layerLinks.enter()
-                .insert('label', '.custom_layer')
+            var enter = layerLinks.enter()
+                .insert('li', '.custom_layer')
                 .attr('class', 'layer');
 
             // only set tooltips for layers with tooltips
-            layerInner
-                .filter(function(d) { return d.description; })
+            enter.filter(function(d) { return d.description; })
                 .call(bootstrap.tooltip()
                     .title(function(d) { return d.description; })
                     .placement('left'));
 
-            layerInner.append('input')
+            var label = enter.append('label');
+
+            label.append('input')
                 .attr('type', type)
                 .attr('name', 'layers')
-                .attr('value', function(d) { return d.name; })
                 .on('change', change);
 
-            layerInner.append('span')
+            label.append('span')
                 .text(function(d) { return d.name; });
 
             layerLinks.exit()
                 .remove();
 
-            layerList.style('display', layerList.selectAll('label.layer').data().length > 0 ? 'block' : 'none');
+            layerList.style('display', layerList.selectAll('li.layer').data().length > 0 ? 'block' : 'none');
         }
 
         function update() {
@@ -24575,9 +24993,7 @@ iD.ui.Background = function(context) {
         function toggle() {
             if (d3.event) d3.event.preventDefault();
             tooltip.hide(button);
-            var visible = !button.classed('active');
-            setVisible(visible);
-            if (visible) content.selectAll('.toggle-list label:first-child').node().focus();
+            setVisible(!button.classed('active'));
         }
 
         function setVisible(show) {
@@ -24641,59 +25057,75 @@ iD.ui.Background = function(context) {
             .attr('class', 'opacity')
             .style('opacity', String);
 
-        var backgroundList = content
-            .append('div')
-            .attr('class', 'toggle-list layer-list');
+        var backgroundList = content.append('ul')
+            .attr('class', 'layer-list');
 
-        var custom = backgroundList
-            .append('label')
+        var custom = backgroundList.append('li')
             .attr('class', 'custom_layer')
             .datum({name: 'Custom'});
 
-        custom.append('input')
+        var label = custom.append('label');
+
+        label.append('input')
             .attr('type', 'radio')
             .attr('name', 'layers')
             .on('change', clickCustom);
 
-        custom.append('span')
+        label.append('span')
             .text(t('background.custom'));
 
-        var overlayList = content
-            .append('div')
-            .attr('class', 'toggle-list layer-list');
+        var overlayList = content.append('ul')
+            .attr('class', 'layer-list');
 
-        var gpxLayerItem = content
-            .append('div')
+        var gpxLayerItem = content.append('ul')
             .style('display', iD.detect().filedrop ? 'block' : 'none')
-            .attr('class', 'toggle-list layer-list')
-            .append('label')
+            .attr('class', 'layer-list')
+            .append('li')
             .classed('layer-toggle-gpx', true);
 
-        gpxLayerItem.call(bootstrap.tooltip()
-            .title(t('gpx.drag_drop'))
-            .placement('left'));
-
-        gpxLayerItem.append('input')
-            .attr('type', 'checkbox')
-            .property('disabled', true)
-            .on('change', clickGpx);
-
-        gpxLayerItem.append('span')
-            .text(t('gpx.local_layer'));
-
-        gpxLayerItem
-            .append('button')
-            .attr('class', 'minor layer-extent')
+        gpxLayerItem.append('button')
+            .attr('class', 'layer-extent')
+            .call(bootstrap.tooltip()
+                .title(t('gpx.zoom'))
+                .placement('left'))
             .on('click', function() {
                 d3.event.preventDefault();
                 d3.event.stopPropagation();
                 context.background().zoomToGpxLayer();
             })
             .append('span')
-                .attr('class', 'icon geocode' );
+            .attr('class', 'icon geolocate');
 
-        var adjustments = content
-            .append('div')
+        gpxLayerItem.append('button')
+            .attr('class', 'layer-browse')
+            .call(bootstrap.tooltip()
+                .title(t('gpx.browse'))
+                .placement('left'))
+            .on('click', function() {
+                d3.select(document.createElement('input'))
+                    .attr('type', 'file')
+                    .on('change', function() {
+                        context.background().gpxLayerFiles(d3.event.target.files);
+                    })
+                    .node().click();
+            })
+            .append('span')
+            .attr('class', 'icon geocode');
+
+        label = gpxLayerItem.append('label')
+            .call(bootstrap.tooltip()
+                .title(t('gpx.drag_drop'))
+                .placement('left'));
+
+        label.append('input')
+            .attr('type', 'checkbox')
+            .property('disabled', true)
+            .on('change', clickGpx);
+
+        label.append('span')
+            .text(t('gpx.local_layer'));
+
+        var adjustments = content.append('div')
             .attr('class', 'adjustments');
 
         adjustments.append('a')
@@ -24708,8 +25140,7 @@ iD.ui.Background = function(context) {
                 d3.event.preventDefault();
             });
 
-        var nudgeContainer = adjustments
-            .append('div')
+        var nudgeContainer = adjustments.append('div')
             .attr('class', 'nudge-container cf')
             .style('display', 'none');
 
@@ -24779,33 +25210,22 @@ iD.ui.cmd = function(code) {
     return keys.join('+');
 };
 iD.ui.Commit = function(context) {
-    var event = d3.dispatch('cancel', 'save', 'fix'),
-        presets = context.presets();
-
-    function zipSame(d) {
-        var c = {}, n = -1;
-        for (var i = 0; i < d.length; i++) {
-            var desc = {
-                name: d[i].tags.name || presets.match(d[i], context.graph()).name(),
-                geometry: d[i].geometry(context.graph()),
-                count: 1,
-                tagText: iD.util.tagText(d[i])
-            };
+    var event = d3.dispatch('cancel', 'save');
 
-            var fingerprint = desc.name + desc.tagText;
-            if (c[fingerprint]) {
-                c[fingerprint].count++;
-            } else {
-                c[fingerprint] = desc;
+    function commit(selection) {
+        var changes = context.history().changes(),
+            summary = context.history().difference().summary();
+
+        function zoomToEntity(change) {
+            var entity = change.entity;
+            if (change.changeType !== 'deleted' &&
+                context.graph().entity(entity.id).geometry(context.graph()) !== 'vertex') {
+                context.map().zoomTo(entity);
+                context.surface().selectAll(
+                    iD.util.entityOrMemberSelector([entity.id], context.graph()))
+                    .classed('hover', true);
             }
         }
-        return _.values(c);
-    }
-
-    function commit(selection) {
-        var changes = context.history().changes();
-
-        function changesLength(d) { return changes[d].length; }
 
         var header = selection.append('div')
             .attr('class', 'header fillL');
@@ -24870,7 +25290,7 @@ iD.ui.Commit = function(context) {
 
         // Confirm Button
         var saveButton = saveSection.append('button')
-            .attr('class', 'action col3 button')
+            .attr('class', 'action col4 button')
             .on('click.save', function() {
                 event.save({
                     comment: commentField.node().value
@@ -24881,11 +25301,13 @@ iD.ui.Commit = function(context) {
             .attr('class', 'label')
             .text(t('commit.save'));
 
+        // Warnings
         var warnings = body.selectAll('div.warning-section')
-            .data(iD.validate(changes, context.graph()))
+            .data([iD.validate(changes, context.graph())])
             .enter()
             .append('div')
-            .attr('class', 'modal-section warning-section fillL2');
+            .attr('class', 'modal-section warning-section fillL2')
+            .style('display', function(d) { return _.isEmpty(d) ? 'none' : null; });
 
         warnings.append('h3')
             .text(t('commit.warnings'));
@@ -24895,52 +25317,90 @@ iD.ui.Commit = function(context) {
             .selectAll('li')
             .data(function(d) { return d; })
             .enter()
-            .append('li');
+            .append('li')
+            .on('mouseover', mouseover)
+            .on('mouseout', mouseout)
+            .on('click', warningClick);
 
-        // only show the fix icon when an entity is given
-        warningLi.filter(function(d) { return d.entity; })
-            .append('button')
-            .attr('class', 'minor')
-            .on('click', event.fix)
-            .append('span')
-            .attr('class', 'icon warning');
+        warningLi.append('span')
+            .attr('class', 'alert icon icon-pre-text');
 
         warningLi.append('strong').text(function(d) {
             return d.message;
         });
 
-        var section = body.selectAll('div.commit-section')
-            .data(['modified', 'deleted', 'created'].filter(changesLength))
+        var changeSection = body.selectAll('div.commit-section')
+            .data([0])
             .enter()
             .append('div')
             .attr('class', 'commit-section modal-section fillL2');
 
-        section.append('h3')
-            .text(function(d) { return t('commit.' + d); })
-            .append('small')
-            .attr('class', 'count')
-            .text(changesLength);
+        changeSection.append('h3')
+            .text(summary.length + ' Changes');
 
-        var li = section.append('ul')
+        var li = changeSection.append('ul')
             .attr('class', 'changeset-list')
             .selectAll('li')
-            .data(function(d) { return zipSame(changes[d]); })
+            .data(summary)
             .enter()
-            .append('li');
+            .append('li')
+            .on('mouseover', mouseover)
+            .on('mouseout', mouseout)
+            .on('click', zoomToEntity);
+
+        li.append('span')
+            .attr('class', function(d) {
+                return d.entity.geometry(d.graph) + ' ' + d.changeType + ' icon icon-pre-text';
+            });
+
+        li.append('span')
+            .attr('class', 'change-type')
+            .text(function(d) {
+                return d.changeType + ' ';
+            });
 
         li.append('strong')
+            .attr('class', 'entity-type')
             .text(function(d) {
-                return d.geometry + ' ';
+                return context.presets().match(d.entity, d.graph).name();
             });
 
         li.append('span')
-            .text(function(d) { return d.name; })
-            .attr('title', function(d) { return d.tagText; });
+            .attr('class', 'entity-name')
+            .text(function(d) {
+                var name = iD.util.displayName(d.entity) || '',
+                    string = '';
+                if (name !== '') string += ':';
+                return string += ' ' + name;
+            });
 
-        li.filter(function(d) { return d.count > 1; })
-            .append('span')
-            .attr('class', 'count')
-            .text(function(d) { return d.count; });
+        li.style('opacity', 0)
+            .transition()
+            .style('opacity', 1);
+
+        li.style('opacity', 0)
+            .transition()
+            .style('opacity', 1);
+
+        function mouseover(d) {
+            if (d.entity) {
+                context.surface().selectAll(
+                    iD.util.entityOrMemberSelector([d.entity.id], context.graph())
+                ).classed('hover', true);
+            }
+        }
+
+        function mouseout() {
+            context.surface().selectAll('.hover')
+                .classed('hover', false);
+        }
+
+        function warningClick(d) {
+            if (d.entity) {
+                context.map().zoomTo(d.entity);
+                context.enter(iD.modes.Select(context, [d.entity.id]));
+            }
+        }
     }
 
     return d3.rebind(commit, event, 'on');
@@ -25356,15 +25816,18 @@ iD.ui.FeatureList = function(context) {
             }
 
             (geocodeResults || []).forEach(function(d) {
-                result.push({
-                    id: iD.Entity.id.fromOSM(d.osm_type, d.osm_id),
-                    geometry: d.osm_type === 'relation' ? 'relation' : d.osm_type === 'way' ? 'line' : 'point',
-                    type: (d.type.charAt(0).toUpperCase() + d.type.slice(1)).replace('_', ' '),
-                    name: d.display_name,
-                    extent: new iD.geo.Extent(
-                        [parseFloat(d.boundingbox[3]), parseFloat(d.boundingbox[0])],
-                        [parseFloat(d.boundingbox[2]), parseFloat(d.boundingbox[1])])
-                })
+                // https://github.com/systemed/iD/issues/1890
+                if (d.osm_type && d.osm_id) {
+                    result.push({
+                        id: iD.Entity.id.fromOSM(d.osm_type, d.osm_id),
+                        geometry: d.osm_type === 'relation' ? 'relation' : d.osm_type === 'way' ? 'line' : 'point',
+                        type: (d.type.charAt(0).toUpperCase() + d.type.slice(1)).replace('_', ' '),
+                        name: d.display_name,
+                        extent: new iD.geo.Extent(
+                            [parseFloat(d.boundingbox[3]), parseFloat(d.boundingbox[0])],
+                            [parseFloat(d.boundingbox[2]), parseFloat(d.boundingbox[1])])
+                    });
+                }
             });
 
             return result;
@@ -25795,7 +26258,7 @@ iD.ui.intro = function(context) {
 
         // Load semi-real data used in intro
         context.connection().toggle(false).flush();
-        context.history().save().reset();
+        context.history().reset();
         
         introGraph = JSON.parse(iD.introGraph);
         for (var key in introGraph) {
@@ -26216,6 +26679,20 @@ iD.ui.preset = function(context) {
             return t;
         };
 
+        field.present = function() {
+            return _.any(field.keys, function(key) {
+                return tags[key];
+            });
+        };
+
+        field.remove = function() {
+            var t = {};
+            field.keys.forEach(function(key) {
+                t[key] = undefined;
+            });
+            return t;
+        };
+
         return field;
     }
 
@@ -26268,21 +26745,35 @@ iD.ui.preset = function(context) {
             .attr('for', function(field) { return 'preset-input-' + field.id; })
             .text(function(field) { return field.label(); });
 
-        $label.append('button')
-            .attr('class', 'modified-icon minor')
+        var wrap = $label.append('div')
+            .attr('class', 'form-label-button-wrap');
+
+        wrap.append('button')
+            .attr('class', 'remove-icon')
+            .append('span').attr('class', 'icon delete');
+
+        wrap.append('button')
+            .attr('class', 'modified-icon')
             .attr('tabindex', -1)
             .append('div')
             .attr('class', 'icon undo');
 
         // Update
 
+        $fields.select('.form-label-button-wrap .remove-icon')
+            .on('click', remove);
+
         $fields.select('.modified-icon')
             .on('click', revert);
 
         $fields
+            .order()
             .classed('modified', function(field) {
                 return field.modified();
             })
+            .classed('present', function(field) {
+                return field.present();
+            })
             .each(function(field) {
                 var reference = iD.ui.TagReference({key: field.key});
 
@@ -26293,7 +26784,7 @@ iD.ui.preset = function(context) {
                 d3.select(this)
                     .call(field.input)
                     .call(reference.body)
-                    .select('.form-label')
+                    .select('.form-label-button-wrap')
                     .call(reference.button);
 
                 field.input.tags(tags);
@@ -26336,6 +26827,12 @@ iD.ui.preset = function(context) {
             d3.event.preventDefault();
             event.change(field.revert());
         }
+
+        function remove(field) {
+            d3.event.stopPropagation();
+            d3.event.preventDefault();
+            event.change(field.remove());
+        }
     }
 
     presets.preset = function(_) {
@@ -26723,6 +27220,7 @@ iD.ui.RadialMenu = function(context, operations) {
             .attr('r', 15)
             .classed('disabled', function(d) { return d.disabled(); })
             .on('click', click)
+            .on('mousedown', mousedown)
             .on('mouseover', mouseover)
             .on('mouseout', mouseout);
 
@@ -26735,6 +27233,10 @@ iD.ui.RadialMenu = function(context, operations) {
             .append('div')
             .attr('class', 'tooltip-inner radial-menu-tooltip');
 
+        function mousedown() {
+            d3.event.stopPropagation(); // https://github.com/systemed/iD/issues/1869
+        }
+
         function mouseover(d, i) {
             var rect = context.surfaceRect(),
                 angle = a0 + i * a,
@@ -26795,6 +27297,7 @@ iD.ui.RawMemberEditor = function(context) {
     var id;
 
     function selectMember(d) {
+        d3.event.preventDefault();
         context.enter(iD.modes.Select(context, [d.id]));
     }
 
@@ -26851,7 +27354,8 @@ iD.ui.RawMemberEditor = function(context) {
                 });
 
             var $enter = $items.enter().append('li')
-                .attr('class', 'member-row form-field');
+                .attr('class', 'member-row form-field')
+                .classed('member-incomplete', function(d) { return !d.member; });
 
             $enter.each(function(d) {
                 if (d.member) {
@@ -26871,7 +27375,7 @@ iD.ui.RawMemberEditor = function(context) {
 
                 } else {
                     d3.select(this).append('label')
-                        .attr('class', 'form-label member-incomplete')
+                        .attr('class', 'form-label')
                         .text(t('inspector.incomplete'));
                 }
             });
@@ -26908,6 +27412,7 @@ iD.ui.RawMembershipEditor = function(context) {
     var id, showBlank;
 
     function selectRelation(d) {
+        d3.event.preventDefault();
         context.enter(iD.modes.Select(context, [d.relation.id]));
     }
 
@@ -27413,13 +27918,13 @@ iD.ui.Save = function(context) {
         var numChanges = 0;
 
         context.history().on('change.save', function() {
-            var _ = history.numChanges();
+            var _ = history.difference().summary().length;
             if (_ === numChanges)
                 return;
             numChanges = _;
 
             tooltip.title(iD.ui.tooltipHtml(t(numChanges > 0 ?
-                    'save.help' : 'save.no_changes'), key))
+                    'save.help' : 'save.no_changes'), key));
 
             button
                 .classed('disabled', numChanges === 0)
@@ -27435,6 +27940,75 @@ iD.ui.Save = function(context) {
         });
     };
 };
+iD.ui.SelectionList = function(context, selectedIDs) {
+
+    function selectionList(selection) {
+        selection.classed('selection-list-pane', true);
+
+        var header = selection.append('div')
+            .attr('class', 'header fillL cf');
+
+        header.append('h3')
+            .text(t('inspector.multiselect'));
+
+        var listWrap = selection.append('div')
+            .attr('class', 'inspector-body');
+
+        var list = listWrap.append('div')
+            .attr('class', 'feature-list cf');
+
+        context.history().on('change.selection-list', drawList);
+        drawList();
+
+        function drawList() {
+            var entities = selectedIDs
+                .map(function(id) { return context.hasEntity(id); })
+                .filter(function(entity) { return entity; });
+
+            var items = list.selectAll('.feature-list-item')
+                .data(entities, iD.Entity.key);
+
+            var enter = items.enter().append('button')
+                .attr('class', 'feature-list-item')
+                .on('click', function(entity) {
+                    context.enter(iD.modes.Select(context, [entity.id]));
+                });
+
+            // Enter
+
+            var label = enter.append('div')
+                .attr('class', 'label');
+
+            label.append('span')
+                .attr('class', 'icon icon-pre-text');
+
+            label.append('span')
+                .attr('class', 'entity-type');
+
+            label.append('span')
+                .attr('class', 'entity-name');
+
+            // Update
+
+            items.selectAll('.icon')
+                .attr('class', function(entity) { return context.geometry(entity.id) + ' icon icon-pre-text'; });
+
+            items.selectAll('.entity-type')
+                .text(function(entity) { return context.presets().match(entity, context.graph()).name(); });
+
+            items.selectAll('.entity-name')
+                .text(function(entity) { return iD.util.displayName(entity); });
+
+            // Exit
+
+            items.exit()
+                .remove();
+        }
+    }
+
+    return selectionList;
+
+};
 iD.ui.Sidebar = function(context) {
     var inspector = iD.ui.Inspector(context),
         current;
@@ -27675,7 +28249,7 @@ iD.ui.Success = function(context) {
             .text(t('success.just_edited'));
 
         var body = selection.append('div')
-            .attr('class', 'body save-success');
+            .attr('class', 'body save-success fillL');
 
         body.append('p')
             .html(t('success.help_html'));
@@ -27819,7 +28393,7 @@ iD.ui.TagReference = function(tag) {
 
         var enter = button.enter().append('button')
             .attr('tabindex', -1)
-            .attr('class', 'tag-reference-button minor');
+            .attr('class', 'tag-reference-button');
 
         enter.append('span')
             .attr('class', 'icon inspect');
@@ -28107,7 +28681,6 @@ iD.ui.preset.address = function(field, context) {
         entity;
 
     function getStreets() {
-
         var extent = entity.extent(context.graph()),
             l = extent.center(),
             box = iD.geo.Extent(l).padByMeters(200);
@@ -28133,6 +28706,62 @@ iD.ui.preset.address = function(field, context) {
         }
     }
 
+    function getCities() {
+        var extent = entity.extent(context.graph()),
+            l = extent.center(),
+            box = iD.geo.Extent(l).padByMeters(200);
+
+        return context.intersects(box)
+            .filter(isAddressable)
+            .map(function(d) {
+                return {
+                    title: d.tags['addr:city'] || d.tags.name,
+                    value: d.tags['addr:city'] || d.tags.name,
+                    dist: iD.geo.sphericalDistance(d.extent(context.graph()).center(), l)
+                };
+            }).sort(function(a, b) {
+                return a.dist - b.dist;
+            });
+
+        function isAddressable(d) {
+            if (d.tags.name &&
+                (d.tags.admin_level === '8' || d.tags.border_type === 'city'))
+                return true;
+
+            if (d.tags.place && d.tags.name && (
+                    d.tags.place === 'city' ||
+                    d.tags.place === 'town' ||
+                    d.tags.place === 'village'))
+                return true;
+
+            if (d.tags['addr:city']) return true;
+
+            return false;
+        }
+    }
+
+    function getPostCodes() {
+        var extent = entity.extent(context.graph()),
+            l = extent.center(),
+            box = iD.geo.Extent(l).padByMeters(200);
+
+        return context.intersects(box)
+            .filter(isAddressable)
+            .map(function(d) {
+                return {
+                    title: d.tags['addr:postcode'],
+                    value: d.tags['addr:postcode'],
+                    dist: iD.geo.sphericalDistance(d.extent(context.graph()).center(), l)
+                };
+            }).sort(function(a, b) {
+                return a.dist - b.dist;
+            });
+
+        function isAddressable(d) {
+            return d.tags['addr:postcode'];
+        }
+    }
+
     function address(selection) {
         var wrap = selection.selectAll('.preset-input-wrap')
             .data([0]);
@@ -28185,6 +28814,18 @@ iD.ui.preset.address = function(field, context) {
                 .fetcher(function(value, callback) {
                     callback(getStreets());
                 }));
+
+        city
+            .call(d3.combobox()
+                .fetcher(function(value, callback) {
+                    callback(getCities());
+                }));
+
+        postcode
+            .call(d3.combobox()
+                .fetcher(function(value, callback) {
+                    callback(getPostCodes());
+                }));
     }
 
     function change() {
@@ -28258,7 +28899,7 @@ iD.ui.preset.check = function(field) {
         value = tags[field.key];
         box.property('indeterminate', !value);
         box.property('checked', value === 'yes');
-        text.text(value || t('inspector.unknown'));
+        text.text(value ? t('inspector.check.' + value, {default: value}) : t('inspector.unknown'));
         label.classed('set', !!value);
     };
 
@@ -28268,7 +28909,8 @@ iD.ui.preset.check = function(field) {
 
     return d3.rebind(check, event, 'on');
 };
-iD.ui.preset.combo = function(field) {
+iD.ui.preset.combo =
+iD.ui.preset.typeCombo = function(field) {
     var event = d3.dispatch('change'),
         input;
 
@@ -28313,13 +28955,18 @@ iD.ui.preset.combo = function(field) {
     }
 
     function change() {
+        var value = input.value().replace(' ', '_');
+        if (field.type === 'typeCombo' && !value) value = 'yes';
+
         var t = {};
-        t[field.key] = input.value().replace(' ', '_') || undefined;
+        t[field.key] = value || undefined;
         event.change(t);
     }
 
     combo.tags = function(tags) {
-        input.value(tags[field.key] || '');
+        var value = tags[field.key] || '';
+        if (field.type === 'typeCombo' && value === 'yes') value = '';
+        input.value(value);
     };
 
     combo.focus = function() {
@@ -28480,35 +29127,38 @@ iD.ui.preset.localized = function(field, context) {
     function key(lang) { return field.key + ':' + lang; }
 
     function changeLang(d) {
-        var value = d3.select(this).value(),
+        var lang = d3.select(this).value(),
             t = {},
             language = _.find(iD.data.wikipedia, function(d) {
-                return d[0].toLowerCase() === value.toLowerCase() ||
-                    d[1].toLowerCase() === value.toLowerCase();
+                return d[0].toLowerCase() === lang.toLowerCase() ||
+                    d[1].toLowerCase() === lang.toLowerCase();
             });
 
-        if (language) value = language[2];
+        if (language) lang = language[2];
 
-        if (d.lang) {
-            t[key(d.lang)] = '';
+        if (d.lang && d.lang !== lang) {
+            t[key(d.lang)] = undefined;
         }
 
-        if (d.value) {
-            t[key(value)] = d.value;
-        } else if (wikiTitles && wikiTitles[d.lang]) {
-            t[key(value)] = wikiTitles[d.lang];
+        var value = d3.select(this.parentNode)
+            .selectAll('.localized-value')
+            .value();
+
+        if (lang && value) {
+            t[key(lang)] = value;
+        } else if (lang && wikiTitles && wikiTitles[d.lang]) {
+            t[key(lang)] = wikiTitles[d.lang];
         }
 
+        d.lang = lang;
         event.change(t);
-
-        d.lang = value;
     }
 
     function changeValue(d) {
+        if (!d.lang) return;
         var t = {};
-        t[key(d.lang)] = d3.select(this).value() || '';
+        t[key(d.lang)] = d3.select(this).value() || undefined;
         event.change(t);
-
     }
 
     function fetcher(value, cb) {
@@ -28535,11 +29185,28 @@ iD.ui.preset.localized = function(field, context) {
                 var wrap = d3.select(this);
                 var langcombo = d3.combobox().fetcher(fetcher);
 
-                wrap.append('label')
+                var label = wrap.append('label')
                     .attr('class','form-label')
                     .text(t('translate.localized_translation_label'))
                     .attr('for','localized-lang');
 
+                label.append('button')
+                    .attr('class', 'minor remove')
+                    .on('click', function(d){
+                        d3.event.preventDefault();
+                        var t = {};
+                        t[key(d.lang)] = undefined;
+                        event.change(t);
+                        d3.select(this.parentNode.parentNode)
+                            .style('top','0')
+                            .style('max-height','240px')
+                            .transition()
+                            .style('opacity', '0')
+                            .style('max-height','0px')
+                            .remove();
+                    })
+                    .append('span').attr('class', 'icon delete');
+
                 wrap.append('input')
                     .attr('class', 'localized-lang')
                     .attr('type', 'text')
@@ -28554,23 +29221,6 @@ iD.ui.preset.localized = function(field, context) {
                     .attr('type', 'text')
                     .attr('placeholder', t('translate.localized_translation_name'))
                     .attr('class', 'localized-value');
-
-                wrap.append('button')
-                    .attr('class', 'minor button-input-action remove')
-                    .on('click', function(d) {
-                        d3.event.preventDefault();
-                        var t = {};
-                        t[key(d.lang)] = undefined;
-                        event.change(t);
-                        d3.select(this.parentNode)
-                            .style('top','0')
-                            .style('max-height','240px')
-                            .transition()
-                            .style('opacity', '0')
-                            .style('max-height','0px')
-                            .remove();
-                    })
-                    .append('span').attr('class', 'icon delete');
             });
 
         innerWrap
@@ -28596,16 +29246,16 @@ iD.ui.preset.localized = function(field, context) {
             .style('top','-10px')
             .remove();
 
-        selection.selectAll('.entry').select('.localized-lang').value(function(d) {
-            var lang = _.find(iD.data.wikipedia, function(lang) {
-                return lang[2] === d.lang;
+        var entry = selection.selectAll('.entry');
+
+        entry.select('.localized-lang')
+            .value(function(d) {
+                var lang = _.find(iD.data.wikipedia, function(lang) { return lang[2] === d.lang; });
+                return lang ? lang[1] : d.lang;
             });
-            return lang ? lang[1] : d.lang;
-        });
 
-        selection.selectAll('.entry').select('.localized-value').value(function(d) {
-            return d.value;
-        });
+        entry.select('.localized-value')
+            .value(function(d) { return d.value; });
     }
 
     i.tags = function(tags) {
@@ -28754,7 +29404,7 @@ iD.ui.preset.maxspeed = function(field, context) {
 iD.ui.preset.radio = function(field) {
 
     var event = d3.dispatch('change'),
-        labels, radios;
+        labels, radios, placeholder;
 
     function radio(selection) {
         selection.classed('preset-radio', true);
@@ -28765,6 +29415,11 @@ iD.ui.preset.radio = function(field) {
         var buttonWrap = wrap.enter().append('div')
             .attr('class', 'preset-input-wrap toggle-list');
 
+        buttonWrap.append('span')
+            .attr('class', 'placeholder');
+
+        placeholder = selection.selectAll('.placeholder');
+
         labels = wrap.selectAll('label')
             .data(field.options || field.keys);
 
@@ -28781,29 +29436,6 @@ iD.ui.preset.radio = function(field) {
 
         radios = labels.selectAll('input')
             .on('change', change);
-
-        buttonWrap.append('span')
-            .attr('class', 'placeholder')
-            .text(field.placeholder());
-
-        var remove = wrap.selectAll('label.remove')
-            .data([0]);
-
-        var removeButton = remove.enter().append('label')
-            .attr('class', 'remove');
-
-        removeButton.append('span')
-            .attr('class', 'icon remove');
-
-        removeButton.append('span')
-            .text(t('inspector.remove'));
-
-        remove
-            .on('click', function() {
-                d3.event.preventDefault();
-                radios.property('checked', false);
-                change();
-            });
     }
 
     function change() {
@@ -28831,6 +29463,12 @@ iD.ui.preset.radio = function(field) {
 
         labels.classed('active', checked);
         radios.property('checked', checked);
+        var selection = radios.filter(function() { return this.checked; });
+        if (selection.empty()) {
+            placeholder.text(t('inspector.none'));
+        } else {
+            placeholder.text(selection.attr('value'));
+        }
     };
 
     radio.focus = function() {
@@ -28878,7 +29516,6 @@ iD.ui.preset.wikipedia = function(field, context) {
 
     var event = d3.dispatch('change'),
         wikipedia = iD.wikipedia(),
-        language = iD.data.wikipedia[0],
         link, entity, lang, title;
 
     function i(selection) {
@@ -28902,7 +29539,7 @@ iD.ui.preset.wikipedia = function(field, context) {
                 if (!value) value = context.entity(entity.id).tags.name || '';
                 var searchfn = value.length > 7 ? wikipedia.search : wikipedia.suggestions;
 
-                searchfn(language && language[2], value, function(query, data) {
+                searchfn(language()[2], value, function(query, data) {
                     cb(data.map(function(d) {
                         return { value: d };
                     }));
@@ -28914,7 +29551,8 @@ iD.ui.preset.wikipedia = function(field, context) {
 
         lang.enter().append('input')
             .attr('type', 'text')
-            .attr('class', 'wiki-lang');
+            .attr('class', 'wiki-lang')
+            .value('English');
 
         lang
             .on('blur', changeLang)
@@ -28944,63 +29582,53 @@ iD.ui.preset.wikipedia = function(field, context) {
             .attr('class', 'icon out-link');
     }
 
-    function changeLang() {
+    function language() {
         var value = lang.value().toLowerCase();
-        language = _.find(iD.data.wikipedia, function(d) {
+        return _.find(iD.data.wikipedia, function(d) {
             return d[0].toLowerCase() === value ||
                 d[1].toLowerCase() === value ||
                 d[2].toLowerCase() === value;
         }) || iD.data.wikipedia[0];
+    }
 
-        if (value !== language[0]) {
-            lang.value(language[1]);
-        }
-
+    function changeLang() {
+        lang.value(language()[1]);
         change();
     }
 
     function change() {
-        var t = {};
-
-        var value = title.value();
-
-        var m = value.match('http://([a-z]+)\\.wikipedia.org/wiki/(.*)'),
-            newlanguage = m && m[1] && m[2] && _.find(iD.data.wikipedia, function(d) {
-                return m[1] === d[2];
-            });
+        var value = title.value(),
+            m = value.match(/http:\/\/([a-z]+)\.wikipedia\.org\/wiki\/(.+)/),
+            l = m && _.find(iD.data.wikipedia, function(d) { return m[1] === d[2]; });
 
-        if (newlanguage) {
+        if (l) {
             // Normalize title http://www.mediawiki.org/wiki/API:Query#Title_normalization
             value = m[2].replace(/_/g, ' ');
             value = value.slice(0, 1).toUpperCase() + value.slice(1);
-            language = newlanguage;
-            lang.value(language[0]);
+            lang.value(l[1]);
+            title.value(value);
         }
 
-        t[field.key] = value ? language[2] + ':' + value : undefined;
+        var t = {};
+        t[field.key] = value ? language()[2] + ':' + value : undefined;
         event.change(t);
-        link.attr('href', 'http://' + language[2] + '.wikipedia.org/wiki/' + (value || ''));
     }
 
     i.tags = function(tags) {
-        var m = tags[field.key] ? tags[field.key].match(/([^:]+):(.+)/) : null;
-
-        var language = m && m[1] && m[2] && _.find(iD.data.wikipedia, function(d) {
-            return m[1] === d[2];
-        });
+        var value = tags[field.key] || '',
+            m = value.match(/([^:]+):(.+)/),
+            l = m && _.find(iD.data.wikipedia, function(d) { return m[1] === d[2]; });
 
         // value in correct format
-        if (language) {
-            lang.value(language[1]);
+        if (l) {
+            lang.value(l[1]);
             title.value(m[2]);
             link.attr('href', 'http://' + m[1] + '.wikipedia.org/wiki/' + m[2]);
 
         // unrecognized value format
         } else {
-            lang.value('English');
-            title.value(tags[field.key] || '');
-            language = iD.data.wikipedia[0];
-            link.attr('href', 'http://en.wikipedia.org/wiki/Special:Search?search=' + tags[field.key]);
+            title.value(value);
+            link.attr('href', 'http://en.wikipedia.org/wiki/Special:Search?search=' + value);
         }
     };
 
@@ -29843,7 +30471,7 @@ iD.presets.Preset = function(id, preset, fields) {
         return tags;
     };
 
-    var applyTags = preset.applyTags || preset.tags;
+    var applyTags = preset.addTags || preset.tags;
     preset.applyTags = function(tags, geometry) {
         tags = _.clone(tags);
 
@@ -29868,7 +30496,7 @@ iD.presets.Preset = function(id, preset, fields) {
     return preset;
 };
 iD.validate = function(changes, graph) {
-    var warnings = [], change;
+    var warnings = [];
 
     // https://github.com/openstreetmap/josm/blob/mirror/src/org/
     // openstreetmap/josm/data/validation/tests/UnclosedWays.java#L80
@@ -29891,20 +30519,16 @@ iD.validate = function(changes, graph) {
     }
 
     for (var i = 0; i < changes.created.length; i++) {
-        change = changes.created[i];
+        var change = changes.created[i],
+            geometry = change.geometry(graph);
 
-        if (change.geometry(graph) === 'point' && _.isEmpty(change.tags)) {
+        if ((geometry === 'point' || geometry === 'line' || geometry === 'area') && !change.isUsed(graph)) {
             warnings.push({
-                message: t('validations.untagged_point'),
+                message: t('validations.untagged_' + geometry),
                 entity: change
             });
         }
 
-        if (change.geometry(graph) === 'line' && _.isEmpty(change.tags) &&
-                graph.parentRelations(change).length === 0) {
-            warnings.push({ message: t('validations.untagged_line'), entity: change });
-        }
-
         var deprecatedTags = change.deprecatedTags();
         if (!_.isEmpty(deprecatedTags)) {
             warnings.push({
@@ -29913,11 +30537,7 @@ iD.validate = function(changes, graph) {
                 }), entity: change });
         }
 
-        if (change.geometry(graph) === 'area' && _.isEmpty(change.tags)) {
-            warnings.push({ message: t('validations.untagged_area'), entity: change });
-        }
-
-        if (change.geometry(graph) === 'line' && tagSuggestsArea(change)) {
+        if (geometry === 'line' && tagSuggestsArea(change)) {
             warnings.push({
                 message: t('validations.tag_suggests_area', {tag: tagSuggestsArea(change)}),
                 entity: change
@@ -29925,7 +30545,7 @@ iD.validate = function(changes, graph) {
         }
     }
 
-    return warnings.length ? [warnings] : [];
+    return warnings;
 };
 })();
 window.locale = { _current: 'en' };
@@ -37777,6 +38397,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
         {
             "name": "Locator Overlay",
             "type": "tms",
+            "description": "Shows major features to help orient you.",
             "template": "http://{switch:a,b,c}.tiles.mapbox.com/v3/openstreetmap.map-btyhiati/{zoom}/{x}/{y}.png",
             "scaleExtent": [
                 0,
@@ -37806,6 +38427,41 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "template": "http://oatile{switch:1,2,3,4}.mqcdn.com/tiles/1.0.0/sat/{zoom}/{x}/{y}.png",
             "default": true
         },
+        {
+            "name": "NLS - Bartholomew Half Inch, 1897-1907",
+            "type": "tms",
+            "template": "http://geo.nls.uk/mapdata2/bartholomew/great_britain/{zoom}/{x}/{-y}.png",
+            "scaleExtent": [
+                0,
+                15
+            ],
+            "polygon": [
+                [
+                    [
+                        -9,
+                        49.8
+                    ],
+                    [
+                        -9,
+                        61.1
+                    ],
+                    [
+                        1.9,
+                        61.1
+                    ],
+                    [
+                        1.9,
+                        49.8
+                    ],
+                    [
+                        -9,
+                        49.8
+                    ]
+                ]
+            ],
+            "terms_url": "http://geo.nls.uk/maps/",
+            "terms_text": "National Library of Scotland Historic Maps"
+        },
         {
             "name": "NLS - OS 1-inch 7th Series 1955-61",
             "type": "tms",
@@ -44031,6 +44687,20 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "terms_text": "© OpenStreetMap contributors, CC-BY-SA",
             "default": true
         },
+        {
+            "name": "OpenStreetMap GPS traces",
+            "type": "tms",
+            "description": "Public GPS traces uploaded to OpenStreetMap.",
+            "template": "http://{switch:a,b,c}.gps-tile.openstreetmap.org/lines/{zoom}/{x}/{y}.png",
+            "scaleExtent": [
+                0,
+                20
+            ],
+            "terms_url": "http://www.openstreetmap.org/copyright",
+            "terms_text": "© OpenStreetMap contributors",
+            "terms_html": "© <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap contributors</a>. North: <span style='display: inline-block; width: 10px; height: 10px; background-color: #7fed11;'></span> South: <span style='display: inline-block; width: 10px; height: 10px; background-color: #7f11ed;'></span> East: <span style='display: inline-block; width: 10px; height: 10px; background-color: #ff3f3f;'></span> West: <span style='display: inline-block; width: 10px; height: 10px; background-color: #00bfbf;'></span>",
+            "overlay": true
+        },
         {
             "name": "Pangasinán/Bulacan (Phillipines HiRes)",
             "type": "tms",
@@ -55034,6 +55704,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                 "tags": {
                     "addr:housenumber": "*"
                 },
+                "addTags": {},
                 "matchScore": 0.2,
                 "name": "Address"
             },
@@ -57635,6 +58306,19 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                 },
                 "name": "Leisure"
             },
+            "leisure/common": {
+                "geometry": [
+                    "point",
+                    "area"
+                ],
+                "terms": [
+                    "open space"
+                ],
+                "tags": {
+                    "leisure": "common"
+                },
+                "name": "Common"
+            },
             "leisure/dog_park": {
                 "geometry": [
                     "point",
@@ -57973,6 +58657,21 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                 },
                 "name": "Lighthouse"
             },
+            "man_made/observation": {
+                "geometry": [
+                    "point",
+                    "area"
+                ],
+                "terms": [
+                    "lookout tower",
+                    "fire tower"
+                ],
+                "tags": {
+                    "man_made": "tower",
+                    "tower:type": "observation"
+                },
+                "name": "Observation Tower"
+            },
             "man_made/pier": {
                 "geometry": [
                     "line",
@@ -59355,6 +60054,26 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                 },
                 "name": "Laundry"
             },
+            "shop/locksmith": {
+                "icon": "shop",
+                "fields": [
+                    "address",
+                    "building_area",
+                    "opening_hours"
+                ],
+                "geometry": [
+                    "point",
+                    "vertex",
+                    "area"
+                ],
+                "terms": [
+                    "keys"
+                ],
+                "tags": {
+                    "shop": "locksmith"
+                },
+                "name": "Locksmith"
+            },
             "shop/mall": {
                 "icon": "shop",
                 "fields": [
@@ -59564,6 +60283,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "five-and-dime",
                     "flea market",
                     "galleria",
+                    "grocery store",
                     "mall",
                     "mart",
                     "outlet",
@@ -60614,12 +61334,12 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "aeroway": {
                 "key": "aeroway",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "amenity": {
                 "key": "amenity",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "artist": {
@@ -60644,7 +61364,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "barrier": {
                 "key": "barrier",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "bicycle_parking": {
@@ -60659,7 +61379,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "building": {
                 "key": "building",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Building"
             },
             "building_area": {
@@ -60773,7 +61493,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "entrance": {
                 "key": "entrance",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "fax": {
@@ -60820,12 +61540,12 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "highway": {
                 "key": "highway",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "historic": {
                 "key": "historic",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "iata": {
@@ -60866,7 +61586,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "landuse": {
                 "key": "landuse",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "lanes": {
@@ -60882,7 +61602,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "leisure": {
                 "key": "leisure",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "levels": {
@@ -60903,7 +61623,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "man_made": {
                 "key": "man_made",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "maxspeed": {
@@ -60920,7 +61640,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "natural": {
                 "key": "natural",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Natural"
             },
             "network": {
@@ -60937,7 +61657,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "office": {
                 "key": "office",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "oneway": {
@@ -60990,17 +61710,17 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "place": {
                 "key": "place",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "power": {
                 "key": "power",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "railway": {
                 "key": "railway",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "ref": {
@@ -61077,7 +61797,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "shop": {
                 "key": "shop",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "source": {
@@ -61128,7 +61848,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "tourism": {
                 "key": "tourism",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "towertype": {
@@ -61158,7 +61878,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "waterway": {
                 "key": "waterway",
-                "type": "combo",
+                "type": "typeCombo",
                 "label": "Type"
             },
             "website": {
@@ -72804,6 +73524,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
     "locales": [
         "af",
         "ar",
+        "ar-AA",
         "ast",
         "bn",
         "bs",
@@ -72833,6 +73554,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
         "lt",
         "no",
         "nn",
+        "fa",
         "pl",
         "pt",
         "pt-BR",
@@ -73098,15 +73820,22 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "back_tooltip": "Change feature",
             "remove": "Remove",
             "search": "Search",
+            "multiselect": "Selected items",
             "unknown": "Unknown",
             "incomplete": "<not downloaded>",
             "feature_list": "Search features",
-            "edit": "Edit feature"
+            "edit": "Edit feature",
+            "check": {
+                "yes": "Yes",
+                "no": "No"
+            },
+            "none": "None"
         },
         "background": {
             "title": "Background",
             "description": "Background settings",
             "percent_brightness": "{opacity}% brightness",
+            "none": "None",
             "custom": "Custom",
             "custom_prompt": "Enter a tile template. Valid tokens are {z}, {x}, {y} for Z/X/Y scheme and {u} for quadtile scheme.",
             "fix_misalignment": "Fix misalignment",
@@ -73169,7 +73898,9 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
         "cannot_zoom": "Cannot zoom out further in current mode.",
         "gpx": {
             "local_layer": "Local GPX file",
-            "drag_drop": "Drag and drop a .gpx file on the page"
+            "drag_drop": "Drag and drop a .gpx file on the page, or click the button to the right to browse",
+            "zoom": "Zoom to GPX track",
+            "browse": "Browse for a .gpx file"
         },
         "help": {
             "title": "Help",
@@ -73177,9 +73908,9 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "editing_saving": "# Editing & Saving\n\nThis editor is designed to work primarily online, and you're accessing\nit through a website right now.\n\n### Selecting Features\n\nTo select a map feature, like a road or point of interest, click\non it on the map. This will highlight the selected feature, open a panel with\ndetails about it, and show a menu of things you can do with the feature.\n\nTo select multiple features, hold down the 'Shift' key. Then either click\non the features you want to select, or drag on the map to draw a rectangle.\nThis will draw a box and select all the points within it.\n\n### Saving Edits\n\nWhen you make changes like editing roads, buildings, and places, these are\nstored locally until you save them to the server. Don't worry if you make\na mistake - you can undo changes by clicking the undo button, and redo\nchanges by clicking the redo button.\n\nClick 'Save' to finish a group of edits - for instance, if you've completed\nan area of town and would like to start on a new area. You'll have a chance\nto review what you've done, and the editor supplies helpful suggestions\nand warnings if something doesn't seem right about the changes.\n\nIf everything looks good, you can enter a short comment explaining the change\nyou made, and click 'Save' again to post the changes\nto [OpenStreetMap.org](http://www.openstreetmap.org/), where they are visible\nto all other users and available for others to build and improve upon.\n\nIf you can't finish your edits in one sitting, you can leave the editor\nwindow and come back (on the same browser and computer), and the\neditor application will offer to restore your work.\n",
             "roads": "# Roads\n\nYou can create, fix, and delete roads with this editor. Roads can be all\nkinds: paths, highways, trails, cycleways, and more - any often-crossed\nsegment should be mappable.\n\n### Selecting\n\nClick on a road to select it. An outline should become visible, along\nwith a small tools menu on the map and a sidebar showing more information\nabout the road.\n\n### Modifying\n\nOften you'll see roads that aren't aligned to the imagery behind them\nor to a GPS track. You can adjust these roads so they are in the correct\nplace.\n\nFirst click on the road you want to change. This will highlight it and show\ncontrol points along it that you can drag to better locations. If\nyou want to add new control points for more detail, double-click a part\nof the road without a node, and one will be added.\n\nIf the road connects to another road, but doesn't properly connect on\nthe map, you can drag one of its control points onto the other road in\norder to join them. Having roads connect is important for the map\nand essential for providing driving directions.\n\nYou can also click the 'Move' tool or press the `M` shortcut key to move the entire road at\none time, and then click again to save that movement.\n\n### Deleting\n\nIf a road is entirely incorrect - you can see that it doesn't exist in satellite\nimagery and ideally have confirmed locally that it's not present - you can delete\nit, which removes it from the map. Be cautious when deleting features -\nlike any other edit, the results are seen by everyone and satellite imagery\nis often out of date, so the road could simply be newly built.\n\nYou can delete a road by clicking on it to select it, then clicking the\ntrash can icon or pressing the 'Delete' key.\n\n### Creating\n\nFound somewhere there should be a road but there isn't? Click the 'Line'\nicon in the top-left of the editor or press the shortcut key `2` to start drawing\na line.\n\nClick on the start of the road on the map to start drawing. If the road\nbranches off from an existing road, start by clicking on the place where they connect.\n\nThen click on points along the road so that it follows the right path, according\nto satellite imagery or GPS. If the road you are drawing crosses another road, connect\nit by clicking on the intersection point. When you're done drawing, double-click\nor press 'Return' or 'Enter' on your keyboard.\n",
             "gps": "# GPS\n\nGPS data is the most trusted source of data for OpenStreetMap. This editor\nsupports local traces - `.gpx` files on your local computer. You can collect\nthis kind of GPS trace with a number of smartphone applications as well as\npersonal GPS hardware.\n\nFor information on how to perform a GPS survey, read\n[Surveying with a GPS](http://learnosm.org/en/beginner/using-gps/).\n\nTo use a GPX track for mapping, drag and drop the GPX file onto the map\neditor. If it's recognized, it will be added to the map as a bright green\nline. Click on the 'Background Settings' menu on the right side to enable,\ndisable, or zoom to this new GPX-powered layer.\n\nThe GPX track isn't directly uploaded to OpenStreetMap - the best way to\nuse it is to draw on the map, using it as a guide for the new features that\nyou add, and also to [upload it to OpenStreetMap](http://www.openstreetmap.org/trace/create)\nfor other users to use.\n",
-            "imagery": "# Imagery\n\nAerial imagery is an important resource for mapping. A combination of\nairplane flyovers, satellite views, and freely-compiled sources are available\nin the editor under the 'Background Settings' menu on the left.\n\nBy default a [Bing Maps](http://www.bing.com/maps/) satellite layer is\npresented in the editor, but as you pan and zoom the map to new geographical\nareas, new sources will become available. Some countries, like the United\nStates, France, and Denmark have very high-quality imagery available for some areas.\n\nImagery is sometimes offset from the map data because of a mistake on the\nimagery provider's side. If you see a lot of roads shifted from the background,\ndon't immediately move them all to match the background. Instead you can adjust\nthe imagery so that it matches the existing data by clicking 'Fix alignment' at\nthe bottom of the Background Settings UI.\n",
+            "imagery": "# Imagery\n\nAerial imagery is an important resource for mapping. A combination of\nairplane flyovers, satellite views, and freely-compiled sources are available\nin the editor under the 'Background Settings' menu on the right.\n\nBy default a [Bing Maps](http://www.bing.com/maps/) satellite layer is\npresented in the editor, but as you pan and zoom the map to new geographical\nareas, new sources will become available. Some countries, like the United\nStates, France, and Denmark have very high-quality imagery available for some areas.\n\nImagery is sometimes offset from the map data because of a mistake on the\nimagery provider's side. If you see a lot of roads shifted from the background,\ndon't immediately move them all to match the background. Instead you can adjust\nthe imagery so that it matches the existing data by clicking 'Fix alignment' at\nthe bottom of the Background Settings UI.\n",
             "addresses": "# Addresses\n\nAddresses are some of the most useful information for the map.\n\nAlthough addresses are often represented as parts of streets, in OpenStreetMap\nthey're recorded as attributes of buildings and places along streets.\n\nYou can add address information to places mapped as building outlines\nas well as those mapped as single points. The optimal source of address\ndata is from an on-the-ground survey or personal knowledge - as with any\nother feature, copying from commercial sources like Google Maps is strictly\nforbidden.\n",
-            "inspector": "# Using the Inspector\n\nThe inspector is the user interface element on the right-hand side of the\npage that appears when a feature is selected and allows you to edit its details.\n\n### Selecting a Feature Type\n\nAfter you add a point, line, or area, you can choose what type of feature it\nis, like whether it's a highway or residential road, supermarket or cafe.\nThe inspector will display buttons for common feature types, and you can\nfind others by typing what you're looking for in the search box.\n\nClick the 'i' in the bottom-right-hand corner of a feature type button to\nlearn more about it. Click a button to choose that type.\n\n### Using Forms and Editing Tags\n\nAfter you choose a feature type, or when you select a feature that already\nhas a type assigned, the inspector will display fields with details about\nthe feature like its name and address.\n\nBelow the fields you see, you can click icons to add other details,\nlike [Wikipedia](http://www.wikipedia.org/) information, wheelchair\naccess, and more.\n\nAt the bottom of the inspector, click 'Additional tags' to add arbitrary\nother tags to the element. [Taginfo](http://taginfo.openstreetmap.org/) is a\ngreat resource for learn more about popular tag combinations.\n\nChanges you make in the inspector are automatically applied to the map.\nYou can undo them at any time by clicking the 'Undo' button.\n\n### Closing the Inspector\n\nYou can close the inspector by clicking the close button in the top-right,\npressing the 'Escape' key, or clicking on the map.\n",
+            "inspector": "# Using the Inspector\n\nThe inspector is the section on the left side of the page that allows you to\nedit the details of the selected feature.\n\n### Selecting a Feature Type\n\nAfter you add a point, line, or area, you can choose what type of feature it\nis, like whether it's a highway or residential road, supermarket or cafe.\nThe inspector will display buttons for common feature types, and you can\nfind others by typing what you're looking for in the search box.\n\nClick the 'i' in the bottom-right-hand corner of a feature type button to\nlearn more about it. Click a button to choose that type.\n\n### Using Forms and Editing Tags\n\nAfter you choose a feature type, or when you select a feature that already\nhas a type assigned, the inspector will display fields with details about\nthe feature like its name and address.\n\nBelow the fields you see, you can click icons to add other details,\nlike [Wikipedia](http://www.wikipedia.org/) information, wheelchair\naccess, and more.\n\nAt the bottom of the inspector, click 'Additional tags' to add arbitrary\nother tags to the element. [Taginfo](http://taginfo.openstreetmap.org/) is a\ngreat resource for learn more about popular tag combinations.\n\nChanges you make in the inspector are automatically applied to the map.\nYou can undo them at any time by clicking the 'Undo' button.\n",
             "buildings": "# Buildings\n\nOpenStreetMap is the world's largest database of buildings. You can create\nand improve this database.\n\n### Selecting\n\nYou can select a building by clicking on its border. This will highlight the\nbuilding and open a small tools menu and a sidebar showing more information\nabout the building.\n\n### Modifying\n\nSometimes buildings are incorrectly placed or have incorrect tags.\n\nTo move an entire building, select it, then click the 'Move' tool. Move your\nmouse to shift the building, and click when it's correctly placed.\n\nTo fix the specific shape of a building, click and drag the nodes that form\nits border into better places.\n\n### Creating\n\nOne of the main questions around adding buildings to the map is that\nOpenStreetMap records buildings both as shapes and points. The rule of thumb\nis to _map a building as a shape whenever possible_, and map companies, homes,\namenities, and other things that operate out of buildings as points placed\nwithin the building shape.\n\nStart drawing a building as a shape by clicking the 'Area' button in the top\nleft of the interface, and end it either by pressing 'Return' on your keyboard\nor clicking on the first node drawn to close the shape.\n\n### Deleting\n\nIf a building is entirely incorrect - you can see that it doesn't exist in satellite\nimagery and ideally have confirmed locally that it's not present - you can delete\nit, which removes it from the map. Be cautious when deleting features -\nlike any other edit, the results are seen by everyone and satellite imagery\nis often out of date, so the building could simply be newly built.\n\nYou can delete a building by clicking on it to select it, then clicking the\ntrash can icon or pressing the 'Delete' key.\n",
             "relations": "# Relations\n\nA relation is a special type of feature in OpenStreetMap that groups together\nother features. For example, two common types of relations are *route relations*,\nwhich group together sections of road that belong to a specific freeway or\nhighway, and *multipolygons*, which group together several lines that define\na complex area (one with several pieces or holes in it like a donut).\n\nThe group of features in a relation are called *members*. In the sidebar, you can\nsee which relations a feature is a member of, and click on a relation there\nto select the it. When the relation is selected, you can see all of its\nmembers listed in the sidebar and highlighted on the map.\n\nFor the most part, iD will take care of maintaining relations automatically\nwhile you edit. The main thing you should be aware of is that if you delete a\nsection of road to redraw it more accurately, you should make sure that the\nnew section is a member of the same relations as the original.\n\n## Editing Relations\n\nIf you want to edit relations, here are the basics.\n\nTo add a feature to a relation, select the feature, click the \"+\" button in the\n\"All relations\" section of the sidebar, and select or type the name of the relation.\n\nTo create a new relation, select the first feature that should be a member,\nclick the \"+\" button in the \"All relations\" section, and select \"New relation...\".\n\nTo remove a feature from a relation, select the feature and click the trash\nbutton next to the relation you want to remove it from.\n\nYou can create multipolygons with holes using the \"Merge\" tool. Draw two areas (inner\nand outer), hold the Shift key and click on each of them to select them both, and then\nclick the \"Merge\" (+) button.\n"
         },
@@ -74237,6 +74968,10 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "name": "Leisure",
                     "terms": ""
                 },
+                "leisure/common": {
+                    "name": "Common",
+                    "terms": "open space"
+                },
                 "leisure/dog_park": {
                     "name": "Dog Park",
                     "terms": ""
@@ -74333,6 +75068,10 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "name": "Lighthouse",
                     "terms": ""
                 },
+                "man_made/observation": {
+                    "name": "Observation Tower",
+                    "terms": "lookout tower,fire tower"
+                },
                 "man_made/pier": {
                     "name": "Pier",
                     "terms": ""
@@ -74709,6 +75448,10 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "name": "Laundry",
                     "terms": ""
                 },
+                "shop/locksmith": {
+                    "name": "Locksmith",
+                    "terms": "keys"
+                },
                 "shop/mall": {
                     "name": "Mall",
                     "terms": ""
@@ -74755,7 +75498,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                 },
                 "shop/supermarket": {
                     "name": "Supermarket",
-                    "terms": "bazaar,boutique,chain,co-op,cut-rate store,discount store,five-and-dime,flea market,galleria,mall,mart,outlet,outlet store,shop,shopping center,shopping centre,shopping plaza,stand,store,supermarket,thrift shop"
+                    "terms": "bazaar,boutique,chain,co-op,cut-rate store,discount store,five-and-dime,flea market,galleria,grocery store,mall,mart,outlet,outlet store,shop,shopping center,shopping centre,shopping plaza,stand,store,supermarket,thrift shop"
                 },
                 "shop/toys": {
                     "name": "Toy Store",
index e6a0aba9fc21f25078928eada9126c0e53da85a9..f190bba022286c2d2726dbb156fee63fecc7e6b5 100644 (file)
      inkscape:window-height="1032"
      id="namedview392"
      showgrid="true"
-     inkscape:zoom="4.2527422"
-     inkscape:cx="305.14936"
-     inkscape:cy="354.08338"
+     inkscape:zoom="11.313708"
+     inkscape:cx="167.44373"
+     inkscape:cy="388.70339"
      inkscape:window-x="2"
      inkscape:window-y="0"
      inkscape:window-maximized="0"
      inkscape:current-layer="layer12"
-     showguides="true"
+     showguides="false"
      inkscape:guide-bbox="true"
-     inkscape:snap-global="false">
+     inkscape:snap-global="true"
+     inkscape:snap-bbox="true"
+     inkscape:snap-bbox-midpoints="true"
+     inkscape:snap-nodes="false">
     <inkscape:grid
        type="xygrid"
        id="grid6326"
        style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        inkscape:connector-curvature="0" />
     <path
-       d="m 191,144 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z"
+       d="m 189,142 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z"
        id="path4822"
        style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        inkscape:connector-curvature="0" />
        style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        inkscape:connector-curvature="0" />
     <path
-       d="m 191,152 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z"
+       d="m 189,154 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z"
        id="path4800"
        style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        inkscape:connector-curvature="0" />
     <path
-       d="m 199,152 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z"
+       d="m 201,154 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z"
        id="path4798"
        style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        inkscape:connector-curvature="0" />
        style="opacity:0.25;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        inkscape:connector-curvature="0" />
     <path
-       d="m 191,164 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m 0,8 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m 8,0 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z"
-       id="path3443"
        style="opacity:0.25;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 189,162 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z"
+       id="path3412"
+       inkscape:connector-curvature="0" />
+    <path
+       style="opacity:0.25;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 189,174 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z"
+       id="path3410"
+       inkscape:connector-curvature="0" />
+    <path
+       style="opacity:0.25;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       d="m 201,174 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z"
+       id="path3443"
        inkscape:connector-curvature="0" />
     <path
        d="m 215,160 -1,1 0,1.0625 c -3.94444,0.49381 -7,3.85922 -7,7.9375 0,4.41827 3.58173,8 8,8 4.41827,0 8,-3.58173 8,-8 0,-2.46731 -1.11852,-4.65856 -2.875,-6.125 l -1.40625,1.40625 C 220.11409,166.37996 221,168.08592 221,170 c 0,3.3137 -2.6863,6 -6,6 -3.3137,0 -6,-2.6863 -6,-6 0,-2.97561 2.15859,-5.43327 5,-5.90625 l 0,0.90625 1,1 3,-3 -3,-3 z"
        style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        inkscape:connector-curvature="0" />
     <rect
-       width="2"
+       width="6"
        height="2"
-       x="169"
-       y="153"
-       transform="translate(25,-3.0624999e-6)"
+       x="192"
+       y="155"
        id="rect4769"
        style="color:#000000;fill:#7092ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999905;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
     <rect
        width="2"
-       height="2"
-       x="190"
-       y="149"
+       height="5.9999971"
+       x="188"
+       y="147"
        id="rect4769-6"
        style="color:#000000;fill:#7092ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999905;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
     <rect
        id="rect4791"
        style="color:#000000;fill:#7092ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999905;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
     <path
-       d="m 190,169 2,0 c 0,0.66667 0,1.33333 0,2 l -2,0 z"
+       d="m 188,167 2,0 c 0,2.00001 0,4 0,6 l -2,0 z"
        id="path4863"
        style="opacity:0.25;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        inkscape:connector-curvature="0" />
     <path
-       d="m 194,173 2,0 c 0,0.66667 0,1.33333 0,2 l -2,0 z"
+       d="m 192,175 6,0 c 0,0.66667 0,1.33333 0,2 l -6,0 z"
        id="path4863-8"
        style="opacity:0.25;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        inkscape:connector-curvature="0" />
            inkscape:connector-curvature="0" />
       </g>
     </g>
+    <path
+       inkscape:connector-curvature="0"
+       style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="path17942-7"
+       d="m 614,7.9999969 -1,1.0000001 0,2 1,1 2,0 1,-1 0,-2 -1,-1.0000001 -2,0 z m 1,1.0000001 c 0.5523,0 1,0.4477 1,1 0,0.5523 -0.4477,1 -1,1 -0.5523,0 -1,-0.4477 -1,-1 0,-0.5523 0.4477,-1 1,-1 z" />
+    <path
+       inkscape:connector-curvature="0"
+       style="opacity:0.5;color:#000000;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="path17944-2"
+       d="m 614,47.999997 -1,1 0,2 1,1 2,0 1,-1 0,-2 -1,-1 -2,0 z m 1,1 c 0.5523,0 1,0.4477 1,1 0,0.5523 -0.4477,1 -1,1 -0.5523,0 -1,-0.4477 -1,-1 0,-0.5523 0.4477,-1 1,-1 z" />
+    <path
+       d="m 357,83.999997 -1,1 0,1.59375 -6.40625,6.40625 -1.59375,0 -1,1 0,2 1,1 2,0 1,-1 0,-1.59375 6.40625,-6.40625 1.59375,0 1,-1 0,-2 -1,-1 z m -22,1 c -2.76142,0 -5,2.23858 -5,5 0,2.76143 5,7 5,7 0,0 5,-4.23857 5,-7 0,-2.76142 -2.23858,-5 -5,-5 z m 23,0 c 0.55228,0 1,0.44772 1,1 0,0.55229 -0.44772,1 -1,1 -0.25152,0 -0.48052,-0.0967 -0.65625,-0.25 -0.0344,-0.03002 -0.0638,-0.05934 -0.0937,-0.09375 -0.15335,-0.175731 -0.25,-0.404729 -0.25,-0.65625 0,-0.55228 0.44772,-1 1,-1 z m 10,0 -1,1 0,2 1,1 0,4 -1,1 0,2 1,1 2,0 1,-1 4,0 1,1 2,0 1,-1 0,-2 -1,-1 0,-4 1,-1 0,-2 -1,-1 -2,0 -1,1 -4,0 -1,-1 z m 1,1 c 0.55228,0 1,0.447715 1,1 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 z m 8,0 c 0.55228,0 1,0.447715 1,1 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 z m -41.84375,2 c 1.10457,0 2,0.89543 2,2 0,1.10457 -0.89543,2 -2,2 -1.10457,0 -2,-0.89543 -2,-2 0,-1.10457 0.89543,-2 2,-2 z m 35.84375,0 4,0 1,1 0,4 -1,1 -4,0 -1,-1 0,-4 z m -22,6 c 0.25152,0 0.48052,0.0967 0.65625,0.25 l 0.0937,0.09375 c 0.15335,0.175731 0.25,0.404734 0.25,0.65625 0,0.55229 -0.44772,1 -1,1 -0.55228,0 -1,-0.44771 -1,-1 0,-0.55228 0.44772,-1 1,-1 z m 20,0 c 0.55228,0 1,0.447715 1,1 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 z m 8,0 c 0.55228,0 1,0.447715 1,1 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 z"
+       id="path2997-7"
+       style="color:#000000;fill:#e06d5f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccccccccsscsscssccscccccccccccccccccccccccccccssssssssssssssscccccccccsccsssssssssssssss" />
+    <path
+       sodipodi:nodetypes="cccccccccccccccccsscsscssccscccccccccccccccccccccccccccssssssssssssssscccccccccsccsssssssssssssss"
+       inkscape:connector-curvature="0"
+       style="color:#000000;fill:#8cd05f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="path3444"
+       d="m 357,104 -1,1 0,1.59375 L 349.59375,113 348,113 l -1,1 0,2 1,1 2,0 1,-1 0,-1.59375 L 357.40625,108 359,108 l 1,-1 0,-2 -1,-1 z m -22,1 c -2.76142,0 -5,2.23858 -5,5 0,2.76143 5,7 5,7 0,0 5,-4.23857 5,-7 0,-2.76142 -2.23858,-5 -5,-5 z m 23,0 c 0.55228,0 1,0.44772 1,1 0,0.55229 -0.44772,1 -1,1 -0.25152,0 -0.48052,-0.0967 -0.65625,-0.25 -0.0344,-0.03 -0.0638,-0.0593 -0.0937,-0.0937 -0.15335,-0.17573 -0.25,-0.40473 -0.25,-0.65625 0,-0.55228 0.44772,-1 1,-1 z m 10,0 -1,1 0,2 1,1 0,4 -1,1 0,2 1,1 2,0 1,-1 4,0 1,1 2,0 1,-1 0,-2 -1,-1 0,-4 1,-1 0,-2 -1,-1 -2,0 -1,1 -4,0 -1,-1 z m 1,1 c 0.55228,0 1,0.44771 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55229 0.44772,-1 1,-1 z m 8,0 c 0.55228,0 1,0.44771 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55229 0.44772,-1 1,-1 z m -41.84375,2 c 1.10457,0 2,0.89543 2,2 0,1.10457 -0.89543,2 -2,2 -1.10457,0 -2,-0.89543 -2,-2 0,-1.10457 0.89543,-2 2,-2 z M 371,108 l 4,0 1,1 0,4 -1,1 -4,0 -1,-1 0,-4 z m -22,6 c 0.25152,0 0.48052,0.0967 0.65625,0.25 l 0.0937,0.0937 c 0.15335,0.17573 0.25,0.40473 0.25,0.65625 0,0.55229 -0.44772,1 -1,1 -0.55228,0 -1,-0.44771 -1,-1 0,-0.55228 0.44772,-1 1,-1 z m 20,0 c 0.55228,0 1,0.44771 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55229 0.44772,-1 1,-1 z m 8,0 c 0.55228,0 1,0.44771 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55229 0.44772,-1 1,-1 z" />
+    <rect
+       style="color:#000000;fill:#7092ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999905;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="rect3397"
+       y="147"
+       x="200"
+       height="5.9999971"
+       width="2" />
+    <path
+       inkscape:connector-curvature="0"
+       style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="path3400"
+       d="m 201,142 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z" />
+    <rect
+       style="color:#000000;fill:#7092ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999905;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="rect3402"
+       y="143"
+       x="192"
+       height="2"
+       width="6" />
+    <path
+       inkscape:connector-curvature="0"
+       style="opacity:0.25;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="path3404"
+       d="m 192,163 6,0 c 0,0.66667 0,1.33333 0,2 l -6,0 z" />
+    <path
+       inkscape:connector-curvature="0"
+       style="opacity:0.25;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="path3406"
+       d="m 200,167 2,0 c 0,2 0,3.99998 0,6 l -2,0 z" />
+    <path
+       id="path3414"
+       d="m 201,162 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z"
+       style="opacity:0.25;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       inkscape:connector-curvature="0" />
   </g>
 </svg>
index 416a8a21cce1de36dc21aaed806be1201a03fe53..45b76aaad9942080ed5037e95d48f00a0d67ac84 100644 (file)
     },
     "cannot_zoom": "Kan nie verder uitzoom in die huidige mode nie.",
     "gpx": {
-        "local_layer": "Plaaslike GPX leer",
-        "drag_drop": "Sleep en laat val 'n .gpx leer op die bladsy"
+        "local_layer": "Plaaslike GPX leer"
     },
     "help": {
         "title": "Help",
-        "help": "# Help\n\nHierdie is 'n probram vir  [OpenStreetMap](http://www.openstreetmap.org/), die gratis en veranderbarie kaart van die wêreld. Jy kan dit gebruik om nuwe data by te voeg of op te dateer waar jy bly en die \"open-source\" en \"open-data\" kaart beter te maak vir almal wat dit gebruik.\n\nVerandering wat jy aanbring op die kaart sal sigbaar wees vir almal at OpenStreetMap gebruik. Jy het nodig om 'n [nuwe gebruikersnaam](https://www.openstreetmap.org/user/new) vir jou self te skep voor jy data kan toevoeg by die kaart. \n\nDie [iD editor](http://ideditor.com/) is 'n gemeenskapsprojek met die [kode beskikbaar op GitHub](https://github.com/systemed/iD).\n",
-        "imagery": "# Lugfotos\n\nLugfotos is 'n belangrike bron vir kaartwerk. 'n Kombinasie van vliegtuie, satelliete en ander gratis bronne is beskikbaar in die program en soos wat jy rondbeweeg en in uit zoom na ander geografiese areas, gaan ander bronne beskikbaar word. \n\nLugfotos is partykeer uit fase uit met die kaart data en is gewoonlik as gevolg van 'n probleem an die lugfotoverskaffer se kant. As jy dus 'n gedeelte van die kaart sien wat lyk of dit als geskuif is moet dit nie dadelik reg skuif nie. Jy kan die lugfotos regskuif deur op 'Verbeter ligging' te klick aan die onderkant van Agtergrond Stellings.\n",
-        "inspector": "# Gebruik van die eienskapslys\n\nDie eienskapslys verskyn op die regterkant wanneer jy 'n item kies met die muis en laat jou toe om eienskappe te verander of by te voeg.\n\n### Kies 'n eienskap tipe\nWanneer jy punt, lyn of area bygevoeg het dan kan jy die eienskap tipe kies soos byvoorbeeld 'n snelweg, residentieele pad, supermark of 'n kafee. Die eienskapslys sal knoppies wys vir al die algmene eienskap tipes en jy kan meer vind deur in die soek boks te tik vir wat jy soek. \n\nOm meer van 'n eienskap te leer klick op die 'i' in die onder regterkantse hoek van die eienskapsknoppie. Klick om 'n eienskapsknoppie om dit aan die kaart item toe te ken.\n\n### Gebruik van vorms en verandering van eienskappe\n\nNa jy 'n eienskaptipe gekies het of wanneer jy 'n item gekies het wat reeds eienskappe het, dan sal die eienskaps lys die detail wys van die item soos die naam en adres. \n\nOnder die lys van eienskappe is 'n lys van ikone met meer detail soos die [Wikipedia](http://www.wikipedia.org/) bladsy, rolstoel toegang en meer.\n\nJy kan ook op Aditioneele Eienskappe klick aan die onderkant van die eienskapslys om meer eienskappe by te voeg wat relevant is. [Taginfo](http://taginfo.openstreetmap.org/) is 'n goeie bron in Engels om meer van die gewilde eienskapkombinasies te leer.\n\nVerandering wat jy in die eienskapslys maak word automaties deel van die kaart. Jy kan dit ongedaan maak deur op die 'Ongedaan' knoppie te klick. \n\n### Toemaak van die eienskapslys\n\nJy kan die eienskapslys toemaak deur op die teomaakknoppie regs bo te klick or deur die 'Esc' sleutel te druk, of om op die kaart te klick.\n\n\n"
+        "help": "# Help\n\nHierdie is 'n probram vir  [OpenStreetMap](http://www.openstreetmap.org/), die gratis en veranderbarie kaart van die wêreld. Jy kan dit gebruik om nuwe data by te voeg of op te dateer waar jy bly en die \"open-source\" en \"open-data\" kaart beter te maak vir almal wat dit gebruik.\n\nVerandering wat jy aanbring op die kaart sal sigbaar wees vir almal at OpenStreetMap gebruik. Jy het nodig om 'n [nuwe gebruikersnaam](https://www.openstreetmap.org/user/new) vir jou self te skep voor jy data kan toevoeg by die kaart. \n\nDie [iD editor](http://ideditor.com/) is 'n gemeenskapsprojek met die [kode beskikbaar op GitHub](https://github.com/systemed/iD).\n"
     },
     "intro": {
         "navigation": {
                 "name": "Karwas"
             },
             "amenity/cinema": {
-                "name": "Fliek"
+                "name": "Fliek",
+                "terms": "Fliek, Inry, Movie, Silverdoek"
             },
             "amenity/college": {
-                "name": "Kollege"
+                "name": "Kollege",
+                "terms": "kollege, landboukollege, raad, genootskap"
             },
             "amenity/courthouse": {
                 "name": "Hof"
                 "name": "Laagte"
             },
             "landuse/cemetery": {
-                "name": "Begrafplaas"
+                "name": "Begrafplaas",
+                "terms": "begrafplaas, kerkhof, dodeakker, godsakker"
             },
             "landuse/commercial": {
-                "name": "Kommersieel"
+                "name": "Kommersieel",
+                "terms": "kommersieel, handeldrywend, "
             },
             "landuse/construction": {
-                "name": "Konstruksie"
+                "name": "Konstruksie",
+                "terms": "Konstruksie"
             },
             "landuse/farm": {
-                "name": "Plaas"
+                "name": "Plaas",
+                "terms": "Plaas"
             },
             "landuse/farmyard": {
-                "name": "Plaaswerf"
+                "name": "Plaaswerf",
+                "terms": "plaaswerf"
             },
             "landuse/forest": {
-                "name": "Woud"
+                "name": "Woud",
+                "terms": "Woud, Oerwoud, Bos"
             },
             "landuse/grass": {
-                "name": "Gras"
+                "name": "Gras",
+                "terms": "Gras, weiveld"
             },
             "landuse/industrial": {
-                "name": "Industrieel"
+                "name": "Industrieel",
+                "terms": "industrieel, nyweraar"
             },
             "landuse/meadow": {
-                "name": "Weiveld"
+                "name": "Weiveld",
+                "terms": "weiland, grasland, weiveld"
             },
             "landuse/orchard": {
-                "name": "Boord"
+                "name": "Boord",
+                "terms": "boord, vrugteboord"
             },
             "landuse/quarry": {
-                "name": "Kwarrie"
+                "name": "Kwarrie",
+                "terms": "steengroef, klipbreekgat, groef"
             },
             "landuse/residential": {
-                "name": "Residensieel"
+                "name": "Residensieel",
+                "terms": "residensieel, huisadres, woonhuis"
             },
             "landuse/retail": {
-                "name": "Kleinhandel"
+                "name": "Kleinhandel",
+                "terms": "kleinhandel, kleinhandelsaak"
             },
             "landuse/vineyard": {
-                "name": "Druiweprieel"
+                "name": "Druiweprieel",
+                "terms": "wingerd"
             },
             "leisure": {
                 "name": "Gemak"
             },
+            "leisure/dog_park": {
+                "name": "Hondepark",
+                "terms": "hondepark"
+            },
             "leisure/garden": {
-                "name": "Tuin"
+                "name": "Tuin",
+                "terms": "Tuin, gedenktuin"
             },
             "leisure/golf_course": {
-                "name": "Golfbaan"
+                "name": "Golfbaan",
+                "terms": "Golfbaan"
             },
             "leisure/marina": {
-                "name": "Vasmeerplek"
+                "name": "Vasmeerplek",
+                "terms": "marina, jaghawe, waterdorp"
             },
             "leisure/park": {
-                "name": "Park"
+                "name": "Park",
+                "terms": "Park"
             },
             "leisure/pitch": {
-                "name": "Sport Veld"
+                "name": "Sport Veld",
+                "terms": "Sportveld"
             },
             "leisure/pitch/american_football": {
-                "name": "Amerikaanse Voetbal Veld"
+                "name": "Amerikaanse Voetbal Veld",
+                "terms": "Amerikaanse voetbalveld"
             },
             "leisure/pitch/baseball": {
-                "name": "Bofpalveld"
+                "name": "Bofpalveld",
+                "terms": "bofbaldiamant"
             },
             "leisure/pitch/basketball": {
-                "name": "Basketbalbaan"
+                "name": "Basketbalbaan",
+                "terms": "Korfbalbaan"
             },
             "leisure/pitch/soccer": {
-                "name": "Sokkerveld"
+                "name": "Sokkerveld",
+                "terms": "Sokkerveld"
             },
             "leisure/pitch/tennis": {
-                "name": "Tennisbaan"
+                "name": "Tennisbaan",
+                "terms": "Tennisbaan"
             },
             "leisure/pitch/volleyball": {
-                "name": "Vlugbalbaan"
+                "name": "Vlugbalbaan",
+                "terms": "Vlugbalbaan"
             },
             "leisure/playground": {
-                "name": "Speelpark"
+                "name": "Speelpark",
+                "terms": "Speelgrond, speelplek, terein"
             },
             "leisure/slipway": {
-                "name": "Inglipbaan"
+                "name": "Inglipbaan",
+                "terms": "inglipbaan,oprit,afrit"
             },
             "leisure/stadium": {
-                "name": "Stadium"
+                "name": "Stadium",
+                "terms": "stadion"
             },
             "leisure/swimming_pool": {
-                "name": "Swembad"
+                "name": "Swembad",
+                "terms": "swembad"
             },
             "line": {
-                "name": "Lyn"
+                "name": "Lyn",
+                "terms": "Lyn"
             },
             "man_made": {
                 "name": "Mens gemaak"
             },
             "man_made/breakwater": {
-                "name": "Breekwater"
+                "name": "Breekwater",
+                "terms": "breekwater,seebreker,golfbreker"
             },
             "man_made/lighthouse": {
-                "name": "Ligtoring"
+                "name": "Ligtoring",
+                "terms": "Lugtoring"
             },
             "man_made/pier": {
-                "name": "Landingsplek"
+                "name": "Landingsplek",
+                "terms": "pier,landingshoof,wandelhoof"
             },
             "man_made/pipeline": {
-                "name": "Pyplyn"
+                "name": "Pyplyn",
+                "terms": "pyplyn"
             },
             "man_made/survey_point": {
                 "name": "Landmeterspunt"
             },
             "man_made/tower": {
-                "name": "Toring"
+                "name": "Toring",
+                "terms": "Toring,paal"
             },
             "man_made/wastewater_plant": {
-                "name": "Rioolplaas"
+                "name": "Rioolplaas",
+                "terms": "rioolplaas"
             },
             "man_made/water_tower": {
-                "name": "Watertoring"
+                "name": "Watertoring",
+                "terms": "Watertoring"
             },
             "man_made/water_well": {
-                "name": "Put"
+                "name": "Put",
+                "terms": "put"
             },
             "man_made/water_works": {
-                "name": "Waterwerke"
+                "name": "Waterwerke",
+                "terms": "waterwerke"
             },
             "natural": {
                 "name": "Natuur"
                 "name": "Baai"
             },
             "natural/beach": {
-                "name": "Strand"
+                "name": "Strand",
+                "terms": "strand"
             },
             "natural/cliff": {
-                "name": "Krans"
+                "name": "Krans",
+                "terms": "krans"
             },
             "natural/coastline": {
-                "name": "Kuslyn"
+                "name": "Kuslyn",
+                "terms": "kuslyn"
             },
             "natural/glacier": {
-                "name": "Gletser"
+                "name": "Gletser",
+                "terms": "gletser"
             },
             "natural/grassland": {
                 "name": "Grasvlakte"
                 "name": "Fontein"
             },
             "natural/tree": {
-                "name": "Boom"
+                "name": "Boom",
+                "terms": "Boom"
             },
             "natural/water": {
-                "name": "Water"
+                "name": "Water",
+                "terms": "water"
             },
             "natural/water/lake": {
-                "name": "Meer"
+                "name": "Meer",
+                "terms": "Meer"
             },
             "natural/water/pond": {
                 "name": "Dammetjie"
             },
             "natural/water/reservoir": {
-                "name": "Reservoir"
+                "name": "Reservoir",
+                "terms": "Reservoir"
             },
             "natural/wetland": {
                 "name": "Vleiland"
             },
             "natural/wood": {
-                "name": "Woud"
+                "name": "Woud",
+                "terms": "Woud"
             },
             "office": {
-                "name": "Kantoor"
+                "name": "Kantoor",
+                "terms": "Kantoor"
             },
             "place": {
-                "name": "Plek"
+                "name": "Plek",
+                "terms": "Plek"
             },
             "place/city": {
-                "name": "Stad"
+                "name": "Stad",
+                "terms": "Stad"
             },
             "place/hamlet": {
                 "name": "Dorpie"
             },
             "place/island": {
-                "name": "Eiland"
+                "name": "Eiland",
+                "terms": "Eiland"
             },
             "place/isolated_dwelling": {
                 "name": "Afgeleë blyplek"
                 "name": "Ligging"
             },
             "place/town": {
-                "name": "Dorp"
+                "name": "Dorp",
+                "terms": "Dorp"
             },
             "place/village": {
-                "name": "Dorpie"
+                "name": "Dorpie",
+                "terms": "Dorpie"
             },
             "point": {
                 "name": "Punt"
             },
             "power": {
-                "name": "Krag"
+                "name": "Krag",
+                "terms": "Krag"
             },
             "power/line": {
-                "name": "Kraglyn"
+                "name": "Kraglyn",
+                "terms": "Kraglyn,kragdraad"
             },
             "power/pole": {
-                "name": "Kragpaal"
+                "name": "Kragpaal",
+                "terms": "Kragpaal"
             },
             "power/sub_station": {
-                "name": "Substasie"
+                "name": "Substasie",
+                "terms": "Substasie"
             },
             "power/tower": {
-                "name": "Hoogspanningstoring"
+                "name": "Hoogspanningstoring",
+                "terms": "Hoogspanningstoring"
             },
             "power/transformer": {
-                "name": "Transformator"
+                "name": "Transformator",
+                "terms": "transformator"
             },
             "railway": {
-                "name": "Spoorlyn"
+                "name": "Spoorlyn",
+                "terms": "Spoorweg"
             },
             "railway/abandoned": {
                 "name": "Verlate spoorlyn"
diff --git a/vendor/assets/iD/iD/locales/ar-AA.json b/vendor/assets/iD/iD/locales/ar-AA.json
new file mode 100644 (file)
index 0000000..9e26dfe
--- /dev/null
@@ -0,0 +1 @@
+{}
\ No newline at end of file
index df71a97e966ce466e43ae81f3c9b9257a2a5b48f..0abc2ca36b7c46a7c1873dd6b8d69e93055e35be 100644 (file)
         "title": "حفظ"
     },
     "presets": {
+        "categories": {
+            "category-path": {
+                "name": "طريق"
+            }
+        },
         "fields": {
+            "access": {
+                "label": "الوصول"
+            },
             "address": {
                 "label": "العنوان",
                 "placeholders": {
+                    "housename": "اسم المنزل",
                     "number": "١٢٣",
                     "street": "الشارع",
                     "city": "المدينة"
             "capacity": {
                 "label": "السعة"
             },
+            "collection_times": {
+                "label": "وقت الاستلام"
+            },
             "construction": {
                 "label": "النوع"
             },
             "crossing": {
                 "label": "النوع"
             },
+            "cuisine": {
+                "label": "طعام"
+            },
+            "denomination": {
+                "label": "الطائفة"
+            },
+            "denotation": {
+                "label": "علامة"
+            },
+            "elevation": {
+                "label": "الارتفاع"
+            },
+            "emergency": {
+                "label": "طوارئ"
+            },
             "entrance": {
                 "label": "النوع"
             },
             "fax": {
                 "label": "الناسوخ (الفاكس)"
             },
+            "fee": {
+                "label": "رسوم"
+            },
+            "highway": {
+                "label": "النوع"
+            },
+            "historic": {
+                "label": "النوع"
+            },
             "internet_access": {
                 "label": "إنترنت",
                 "options": {
                     "wlan": "واي فاي",
-                    "wired": "سلكي"
+                    "wired": "سلكي",
+                    "terminal": "بوابة"
                 }
             },
             "landuse": {
             "opening_hours": {
                 "label": "ساعات"
             },
+            "operator": {
+                "label": "مشغل"
+            },
             "phone": {
                 "label": "هاتف"
             },
                     "muslim": "الإسلام",
                     "buddhist": "البوذية",
                     "jewish": "اليهودية",
-                    "hindu": "الهيندوسية"
+                    "hindu": "الهيندوسية",
+                    "shinto": "الشينتو",
+                    "taoist": "التاو"
                 }
             },
+            "sac_scale": {
+                "label": "صعوبة الطريق"
+            },
             "service": {
                 "label": "النوع"
             },
+            "shelter": {
+                "label": "ملجأ"
+            },
             "shop": {
                 "label": "النوع"
             },
             }
         },
         "presets": {
+            "aeroway": {
+                "name": "جوي"
+            },
             "aeroway/aerodrome": {
                 "name": "مطار"
             },
+            "aeroway/helipad": {
+                "name": "مهبط الهليكوبتر"
+            },
+            "amenity": {
+                "name": "مرفق"
+            },
             "amenity/bank": {
                 "name": "بنك"
             },
+            "amenity/bar": {
+                "name": "بار"
+            },
+            "amenity/bench": {
+                "name": "مقعد"
+            },
             "amenity/bicycle_parking": {
                 "name": "موقف درجات"
             },
+            "amenity/bicycle_rental": {
+                "name": "تأجير دراجات"
+            },
             "amenity/cafe": {
                 "name": "مقهى"
             },
             "amenity/fire_station": {
                 "name": "محطة إطفاء"
             },
+            "amenity/fuel": {
+                "name": "محطة غاز"
+            },
+            "amenity/grave_yard": {
+                "name": "مقبرة"
+            },
             "amenity/hospital": {
                 "name": "مستشفى"
             },
             "amenity/pharmacy": {
                 "name": "صيدلية"
             },
+            "amenity/place_of_worship": {
+                "name": "مكان عبادة"
+            },
             "amenity/place_of_worship/christian": {
                 "name": "كنيسة"
             },
+            "amenity/place_of_worship/jewish": {
+                "name": "كنيس يهودي"
+            },
             "amenity/place_of_worship/muslim": {
                 "name": "مسجد"
             },
+            "amenity/police": {
+                "name": "شرطة"
+            },
+            "amenity/post_box": {
+                "name": "صندوق بريد"
+            },
+            "amenity/post_office": {
+                "name": "بريد"
+            },
+            "amenity/pub": {
+                "name": "حانة"
+            },
             "amenity/restaurant": {
                 "name": "مطعم"
             },
             "amenity/school": {
                 "name": "مدرسة"
             },
+            "amenity/telephone": {
+                "name": "هاتف"
+            },
             "amenity/toilets": {
                 "name": "دورات مياه"
             },
+            "amenity/townhall": {
+                "name": "قاعة البلدة"
+            },
             "amenity/university": {
                 "name": "جامعة"
             },
             "building": {
                 "name": "مبنى"
             },
+            "entrance": {
+                "name": "مدخل"
+            },
             "highway": {
                 "name": "طريق سريع"
             },
+            "highway/bridleway": {
+                "name": "طريق الخيول"
+            },
             "highway/bus_stop": {
                 "name": "محطة باص"
             },
             "highway/crossing": {
                 "name": "تقاطع"
             },
+            "highway/cycleway": {
+                "name": "طريق دراجة هوائية"
+            },
+            "highway/footway": {
+                "name": "طريق مشي بالأقدام"
+            },
+            "highway/motorway": {
+                "name": "طريق سريع"
+            },
+            "highway/path": {
+                "name": "طريق"
+            },
             "highway/primary": {
                 "name": "طريق رئيسي"
             },
             "highway/service": {
                 "name": "طريق خدمة"
             },
+            "highway/steps": {
+                "name": "درج"
+            },
+            "highway/tertiary": {
+                "name": "طريق ثالثي"
+            },
+            "highway/track": {
+                "name": "شاحنات"
+            },
             "highway/traffic_signals": {
                 "name": "إشارات مرور"
             },
+            "highway/trunk": {
+                "name": "طريق شاحنات"
+            },
+            "highway/turning_circle": {
+                "name": "دائرة رجوع"
+            },
             "highway/unclassified": {
                 "name": "طريق غير مصنف"
             },
+            "historic": {
+                "name": "موقع تاريخي"
+            },
+            "historic/monument": {
+                "name": "نصب تذكاري"
+            },
+            "landuse": {
+                "name": "استخدام الارض"
+            },
+            "landuse/allotments": {
+                "name": "مزارع مخصصة"
+            },
+            "landuse/basin": {
+                "name": "حوض"
+            },
+            "landuse/cemetery": {
+                "name": "مقبرة"
+            },
+            "landuse/commercial": {
+                "name": "تجاري"
+            },
+            "landuse/construction": {
+                "name": "إنشاءات"
+            },
             "landuse/farm": {
                 "name": "مزرعة"
             },
+            "landuse/farmyard": {
+                "name": "فناء المزرعة"
+            },
+            "landuse/forest": {
+                "name": "غابة"
+            },
+            "landuse/grass": {
+                "name": "عشب"
+            },
+            "landuse/industrial": {
+                "name": "صناعي"
+            },
+            "landuse/meadow": {
+                "name": "مرج"
+            },
+            "landuse/orchard": {
+                "name": "بستان"
+            },
+            "landuse/quarry": {
+                "name": "محجر"
+            },
+            "landuse/residential": {
+                "name": "سكني"
+            },
+            "landuse/vineyard": {
+                "name": "مزرعة العنب"
+            },
+            "leisure": {
+                "name": "الترفيه"
+            },
             "leisure/garden": {
                 "name": "حديقة"
             },
+            "leisure/golf_course": {
+                "name": "معلب جولف"
+            },
+            "leisure/park": {
+                "name": "حديقة"
+            },
+            "leisure/pitch": {
+                "name": "ملعب رياضي"
+            },
+            "leisure/pitch/american_football": {
+                "name": "ملعب كرة قدم أمريكية"
+            },
+            "leisure/pitch/baseball": {
+                "name": "ملعب بيسبول"
+            },
+            "leisure/pitch/basketball": {
+                "name": "ملعب كرة السلة"
+            },
+            "leisure/pitch/soccer": {
+                "name": "ملعب كرة القدم"
+            },
+            "leisure/pitch/tennis": {
+                "name": "ملعب تنس"
+            },
+            "leisure/playground": {
+                "name": "ساحة ألعاب للأطفال"
+            },
+            "man_made": {
+                "name": "مباني صناعية"
+            },
+            "man_made/lighthouse": {
+                "name": "منارة"
+            },
+            "man_made/pier": {
+                "name": "رصيف بحري"
+            },
+            "man_made/water_tower": {
+                "name": "خزان مائي"
+            },
+            "natural": {
+                "name": "طبيعي"
+            },
+            "natural/bay": {
+                "name": "خليج"
+            },
+            "natural/beach": {
+                "name": "شاطئ"
+            },
+            "natural/cliff": {
+                "name": "جرف صخري"
+            },
+            "natural/coastline": {
+                "name": "ساحل"
+            },
+            "natural/glacier": {
+                "name": "كتلة جليدية"
+            },
+            "natural/grassland": {
+                "name": "أرض عشبية"
+            },
+            "natural/heath": {
+                "name": "مرج"
+            },
+            "natural/peak": {
+                "name": "قمة"
+            },
+            "natural/scrub": {
+                "name": "أراضي الأشجار القمئية"
+            },
+            "natural/spring": {
+                "name": "نبع"
+            },
+            "natural/tree": {
+                "name": "شجرة"
+            },
+            "natural/water": {
+                "name": "مياه"
+            },
+            "natural/water/lake": {
+                "name": "بحيرة"
+            },
+            "natural/water/pond": {
+                "name": "بركة"
+            },
+            "natural/water/reservoir": {
+                "name": "خزان"
+            },
+            "natural/wetland": {
+                "name": "أرض رطبة"
+            },
+            "natural/wood": {
+                "name": "غابة أخشاب"
+            },
+            "office": {
+                "name": "مكتب"
+            },
+            "place": {
+                "name": "قصر"
+            },
+            "place/hamlet": {
+                "name": "قرية صغيرة"
+            },
+            "place/island": {
+                "name": "جزيرة"
+            },
+            "place/locality": {
+                "name": "موقع"
+            },
+            "place/village": {
+                "name": "قرية"
+            },
+            "power/sub_station": {
+                "name": "محطة فرعية"
+            },
+            "railway": {
+                "name": "سكة حديد"
+            },
+            "railway/level_crossing": {
+                "name": "معبر سكة حديدية"
+            },
+            "railway/rail": {
+                "name": "قطار"
+            },
+            "railway/subway": {
+                "name": "مترو الأنفاق"
+            },
+            "railway/subway_entrance": {
+                "name": "مدخل مترو الأنفاق"
+            },
+            "shop": {
+                "name": "محل"
+            },
+            "shop/butcher": {
+                "name": "ملحمة"
+            },
+            "shop/supermarket": {
+                "name": "سوبر ماركت"
+            },
+            "tourism": {
+                "name": "سياحي"
+            },
             "tourism/alpine_hut": {
                 "name": "داراستراحة"
             },
             "tourism/attraction": {
                 "name": "معلم سياحي"
             },
+            "tourism/camp_site": {
+                "name": "موقع مخيم"
+            },
+            "tourism/caravan_site": {
+                "name": "موقف عربات كبيرة"
+            },
             "tourism/chalet": {
                 "name": "شاليه"
             },
             "tourism/guest_house": {
                 "name": "استراحة"
             },
+            "tourism/hostel": {
+                "name": "نزل"
+            },
+            "tourism/hotel": {
+                "name": "فندق"
+            },
+            "tourism/information": {
+                "name": "معلومات"
+            },
+            "tourism/motel": {
+                "name": "فندق رخيص"
+            },
+            "tourism/museum": {
+                "name": "متحف"
+            },
+            "tourism/picnic_site": {
+                "name": "موقع نزهة"
+            },
+            "tourism/theme_park": {
+                "name": "حديقة ترفيه"
+            },
             "tourism/zoo": {
                 "name": "حديقة حيوانات"
+            },
+            "waterway": {
+                "name": "مجرى مائي"
+            },
+            "waterway/canal": {
+                "name": "قناة"
+            },
+            "waterway/dam": {
+                "name": "سد"
+            },
+            "waterway/ditch": {
+                "name": "خندق"
+            },
+            "waterway/drain": {
+                "name": "مصرف مياه"
+            },
+            "waterway/river": {
+                "name": "نهر"
+            },
+            "waterway/riverbank": {
+                "name": "ضفة نهر"
+            },
+            "waterway/stream": {
+                "name": "مجرى"
+            },
+            "waterway/weir": {
+                "name": "هدار سد صغير"
             }
         }
     }
index f70c6ea923ee5fe15bfd08c944c3acda0620b31e..d1661906be0aceef723ea9cb6d95ffa714172a5f 100644 (file)
         "out": "Alloñar"
     },
     "gpx": {
-        "local_layer": "Ficheru GPX llocal",
-        "drag_drop": "Arrastrar y soltar un ficheru .gpx na páxina"
+        "local_layer": "Ficheru GPX llocal"
     },
     "help": {
         "title": "Ayuda",
-        "help": "# Ayuda\n\nEsti ye un editor pa [OpenStreetMap](http://www.openstreetmap.org/), el\nmapa del mundu llibre y editable. Pue usalu p'amestar y anovar los\ndatos nel to área, faciendo un mapa del mundu de códigu y datos\nabiertos meyor pa tol mundu.\n\nLes ediciones que faiga nesti mapa sedrán visibles pa cualquiera qu'use\nOpenStreetMap. Pa poder editar, necesitará una\n[cuenta de baldre n'OpenStreetMap](https://www.openstreetmap.org/user/new).\n\nEl [editor iD](http://ideditor.com/) ye un proyeutu collaborativu col [códigu\nfonte disponible en GitHub](https://github.com/systemed/iD).\n",
-        "imagery": "# Imaxes\n\nLes imaxes aérees son un recursu importante pa facer mapes. Ta disponible\nnel editor una combinación de vuelos d'aviones, vistes de satélite, y fontes compilaes\nde mou llibre baxo'l menú 'Preferencies del fondu' a la izquierda.\n\nDe mou predetermináu, nel editor apaez una capa de satélite de\n [Bing Maps](http://www.bing.com/maps/), pero cuando mueva y faiga zoom nel mapa a\nnueves árees xeográfiques, apaecerán fontes nueves. Dalgunos países, como los Estaos\nXuníos, Francia y Dinamarca tienen imaxes de calidá mui alta pa delles árees.\n\nLes imaxes, dacuando, tan desplazaes del mapa por aciu d'un fallu del fornidor\nde les imaxes. Si ve munches carreteres que nun casen col fondu, nun\nmueva nel intre toes elles p'axustales al fondu. Al aviesu, axuste la\nimaxe pa que case colos datos esistentes calcando 'Iguar alliniamientu' abaxo\nde la interfaz de les Preferencies del fondu.\n"
+        "help": "# Ayuda\n\nEsti ye un editor pa [OpenStreetMap](http://www.openstreetmap.org/), el\nmapa del mundu llibre y editable. Pue usalu p'amestar y anovar los\ndatos nel to área, faciendo un mapa del mundu de códigu y datos\nabiertos meyor pa tol mundu.\n\nLes ediciones que faiga nesti mapa sedrán visibles pa cualquiera qu'use\nOpenStreetMap. Pa poder editar, necesitará una\n[cuenta de baldre n'OpenStreetMap](https://www.openstreetmap.org/user/new).\n\nEl [editor iD](http://ideditor.com/) ye un proyeutu collaborativu col [códigu\nfonte disponible en GitHub](https://github.com/systemed/iD).\n"
     },
     "intro": {
         "navigation": {
index 49b2aa7dec4d421cf02df223cd3a3484f21f80d2..55ecf86fd8deba249ee746374d44da6568615d89 100644 (file)
     },
     "cannot_zoom": "Не можете да намалявате повече в текущия режим.",
     "gpx": {
-        "local_layer": "Локален GPX файл",
-        "drag_drop": "Влачете и пуснете .gpx файл върху страницата"
+        "local_layer": "Локален GPX файл"
     },
     "help": {
         "title": "Помощ",
         "help": "# Помощ⏎\n⏎\nТова е редактор за [OpenStreetMap](http://www.openstreetmap.org/), ⏎\nсвободната и редактируема карта на света. Може да го използате да⏎\nдобавяте и обновявате информацията за вашия регион, създавайки⏎\nкарта на света с отворен код и данни, по-добра за всеки.⏎\n⏎\nРедакциите, които правите на тази карта ще са видими за всеки, който⏎\nползва OpenStreetMap. За да направите редакция ви трябва⏎\n[безплатен OpenStreetMap акаунт](https://www.openstreetmap.org/user/new).⏎\n⏎\n[iD редакторът](http://ideditor.com/) е съвместен проект, с [изходен код⏎\nналичен в GitHub](https://github.com/systemed/iD).⏎\n",
         "roads": "# Пътища\n\nМожете да създавате, поправяте и изтривате пътища с този редактор.\nПътищата могат да бъдат най-различни видове: пътеки, автомагистрали,\nтуристически пътеки, велосипедни алеи и много други - всеки често \nпрекосяван обект трябва да може да се картографира.\n\n### Избиране\n\nЩракнете върху път за да го изберете. Край него трябва да се появи контур, \nзаедно с малко меню с инструменти върху картата и странична лента, \nпоказваща повече информация за пътя.\n\n### Модифициране\n\nЧесто ще виждате пътища, които не са подравнени към изображението \nпод тях или към GPS трак. Можете да оправите тези пътища така, че\nда бъдат на правилното си място.\n\nПърво щракнете върху пътя, който искате да промените. Това ще го\nосвети и ще покаже контролни точки по продължението му, които\nможете да завлачите на по-добри места. Ако искате да добавите\nнови контролни точки за повече детайл, щракнете два пъти върху\nчастта от пътя без възел и такъв ще бъде създаден.\n\nАко пътят се свързва с друг път, но не се свързва коректно на картата,\nможете да завлачите една от контролните точки върху другия път с цел\nда ги съедините. Свързването на пътищата е важно за картата и \nнеобходимо при даването на упътвания за шофьори.\n\nМожете също да щракнете бутонът 'Преместване' или бързия \nклавиш `M`, за да преместите целия път наведнъж, а след това\nщракнете отново, за да запазите преместването.\n\n### Изтриване\n\nАко пътят е изцяло грешен - можете да видите, че не съществува\nна сателитното изображение или в най-добрия случай сте се убедили\nна място, че не съществува - можете да го изтриете, което го премахва\nот картата. Бъдете внимателни, когато изтривате елементи - като \nвсяка друга редакция, резултатите се виждат от всички, а сателитните \nизображения често са неактуални, така че пътят може просто да е\nновопостроен.\n\nМожете да изтриете път като щракнете върху нея за да го изберете, \nа след това щракнете върху иконата кошче или да натиснете бутона\n'Delete'.\n\n### Създаване\n\nОткрили сте, че някъде трябва да има път, но такъв няма? Щракнете\nна иконата 'Линия' в горния ляв край на редактора или натиснете\nбързия клавиш `2` за да започнете чертането на линия.\n\nЩракнете върху началото на пътя на картата за да започнете чертането.\nАко пътят се разклонява от съществуващ такъв, започнете като щракнете\nвърху мястото, където те се свързват.\n\nСлед това щракайте точки по продължението на пътя така, че той да\nследва правилния маршрут, според сателитното изображение или GPS.\nАко пътят, който чертаете, пресича друг път, свържете го като щракнете\nвърху точката на пресичане. Когато сте готови с чертането, щракнете \nдва пъти или натиснете 'Return' или 'Enter' от клавиатурата.\n",
-        "imagery": "# Изображения\n\nВъздушните снимки са важен източник на информация за картографията. Комбинация от аерофотограметрични снимки, сателитни изображения и свободно разпространявани източници на данни са на разположение в редактора в менюто 'Подложка настройки' от ляво.\n\nСателитният слой [Bing Maps](http://www.bing.com/maps/) е  зареден по подразбиране в редактора, но при движение и увеличаване на картата към нови географски области се появяват нови източници на информация. Някои страни, като САЩ, Франция и Дания, имат много висококачествени изображения за някои области.\n\nИзображенията понякога са отместени от елементите на картата, поради грешка на доставчика на изображения. Ако забележите много отместени от фоновото изображение пътища, не бързайте да ги премествате, за да съвпаднат с фоновото изображение. Вместо това можете да нагласите изображението така, че да съвпада със съществуващите данни като натиснете 'Подравняване' в долния край на таблото 'Подложка настройки'.\n",
         "addresses": "# Адреси\n\nАдресите са една от най-полезните информации на картата.\n\nВъпреки че, адресите често са представяни като части от улици, в\nOpenStreetMap те се записват като атрибути на сгради и места \nпокрай улици.\n\nМожете да добавяте адресна информация към места изобразени като\nконтури на сграда, също и към тези изобразени като кочка. Оптималния\nизточник на адресна информация е от измерване на терен или \nлични познания - както и с всички останали обекти, копирането от \nкомерсиални източници като Google Maps е стриктно забранено.\n",
-        "inspector": "# Използване на инспектора\n\nИнспекторът е частта от потребителския интерфейс в дясно на \nстраницата, която се появява, когато е избран елемент и ви позволява \nда редактирате неговите атрибути.\n\n### Избиране на вид елемент\n\nСлед като сте добавили точка, линия или площ, можете да изберете \nкакъв вид обект е тя, дали е автомагистрала или улица, супермаркет\n или кафене. Инспекторът ще показва бутони за често използваните \nобекти, а можете да откриете други, като напишете какво ви трябва \nв полето за търсене.\n\nНатиснете 'i' в долния десен ъгъл на бутона елемент вид, за да разберете \nповече за него. Натиснете бутон, за да изберете този вид.\n\n### Използване на формулярите и редактиране на таговете\n\nСлед като изберете вид елемент или когато изберете елемент, който \nвече има определен вид, инспекторът ще изведе полета с атрибутите \nна елемента, като неговото име и адрес.\n\nПод полетата, които виждате можете да щракнете върху иконите,\n за да добавяте други атрибути като информация от \n[Wikipedia](http://www.wikipedia.org/), достъп за инвалидни колички \nи други.\n\nВ долния край на инспектора, натиснете 'Други тагове', за да \nдобавите произволни тагове към елемента. \n[Taginfo](http://taginfo.openstreetmap.org/) е чудесен източник на \nинформация за научаване на повече за популярните \nкомбинации от тагове.\n\nПромените, които правите в инспектора се прилагат автоматично \nкъм картата. Можете да ги отхвърлите по всяко време, като натиснете \nбутона 'Отхвърляне'.\n\n### Затваряне на инспектора\n\nМожете да затворите инспектора, като натиснете бутона за затваряне \nв горния десен ъгъл, като натиснете бутона 'Escape' или като \nщракнете върху картата.\n",
         "buildings": "# Сгради\n\nOpenStreetMap е най-голямата в света база данни за сгради. Можете да \nсъздавате и подобрявате тази база данни.\n\n### Избиране\n\nМожете да изберете сграда като щракнете върху нейния контур. Това ще \nосвети сградата и ще отвори малко меню с инструменти, както и \nстранична лента с повече информация за сградата.\n\n### Модифициране\n\nПонякога сградите са неправилно поставени или имат грешни тагове.\n\nЗа да преместите цяла сграда, изберете я и след това натиснете \nинструмента 'Преместване'. Движете мишката за да преместите \nсградата и щракнете, когато е на точното си място.\n\nЗа да оправите формата на сградата, щракнете и завлачете възлите, \nкоито оформят контура и ги поставете на по-добри позиции.\n\n### Създаване\n\nЕдин от основните въпроси около добавянето на сгради в картата \nе, че OpenStreetMap може да записва сградите и като контур, и като \nточка. Практическо правило е сграда да се картографира като контур \nвинаги, когато това е възможно, а отделните компании, жилища, услуги и \nдруги обекти, които оперират в сгради - като точки поставени в \nконтура на сградата.\n\nЗапочнете чертането на контура на сградата като натиснете бутонът \n'Площи' в горния ляв край на интерфейса и завършете като натиснете\n'Enter' от клавиатурата или като щракнете върху първия начертан възел,\nза да затворите контура.\n\n### Изтриване\n\nАко сградата е изцяло грешна - можете да видите, че не съществува\nна сателитното изображение или в най-добрия случай сте се убедили\nна място, че не съществува - можете да я изтриете, което я премахва\nот картата. Бъдете внимателни, когато изтривате елементи - като \nвсяка друга редакция, резултатите се виждат от всички, а сателитните \nизображения често са неактуални, така че сградата може просто да е\nновопостроена.\n\nМожете да изтриете сграда като щракнете върху нея за да я изберете, \nа след това щракнете върху иконата кошче или да натиснете бутона\n'Delete'.\n"
     },
     "intro": {
index f211b9b83efaf7ec9fa68f5eb89f982f5503f6c9..a19f3aa20d652dcd39112cde698b0b66ea103f89 100644 (file)
         "tag_suggests_area": "{tag} ট্যাগটি অনুসারে রেখাটি এলাকা হবে, কিন্তু নয়।",
         "deprecated_tags": "পুরোন ও অব্যবহৃত ট্যাগ: {tags}"
     },
-    "gpx": {
-        "drag_drop": "একটি .gpx ফাইল টেনে এনে পেজটিতে ফেলুন"
-    },
     "help": {
         "title": "সাহায্য",
         "help": "# সাহায্য⏎\n⏎\nএটি, দুনিয়ার বিনামুল্য/মুক্ত এবং পরিবর্তনযোগ্য ম্যাপ, [ওপেনস্ট্রীটম্যাপ](http://www.openstreetmap.org/)-এর⏎\nএকটি এডিটর। অাপনি অাপনার এলাকার তথ্য সংযোজন করা ও পরিবর্তন করার জন্য⏎\nএটি ব্যবহার করে, সকলের জন্য উন্নীত একটি ওপেন-সোর্স এবং ওপেন-ডাটা ম্যাপ⏎\nতৈরী করতে পারেন।\n⏎\nঅাপনি এই ম্যাপ-এ যা পরিবর্তন করবেন তা ওপেনস্ট্রীটম্যাপ-এর যারা ব্যবহার করে⏎\nতাদের সবার কাছে দৃশ্যমান হবে। পরিবর্তন করার জন্য অাপনার একটি [বিনামুল্য⏎\nওপেনস্ট্রীটম্যাপ অ্যাকাউন্ট](https://www.openstreetmap.org/user/new) লাগবে।⏎\n⏎\n[iD এডিটর](http://ideditor.com/) একটি কোল্যাবোরেটিভ প্রকল্প, [যার সোর্স কোড Github-এ লভ্য](https://github.com/systemed/iD)।\n⏎\n"
index 5ad6c8d481ad4968cd5bc0e1643f66d483eb725f..5108622fda248cceb5549adaf286ddb49d3d4ed5 100644 (file)
@@ -83,7 +83,8 @@
             "annotation": {
                 "line": "Ispravljeni uglovi linije.",
                 "area": "Ispravljeni uglovi područja."
-            }
+            },
+            "not_squarish": "Ovo se ne može napraviti kvadratom jer nema kvadratnu formu."
         },
         "straighten": {
             "title": "Ispraviti",
         "back_tooltip": "Promijeniti značajku",
         "remove": "Uklonite",
         "search": "Pretraga",
+        "multiselect": "Odabrane stavke",
         "unknown": "Nepoznato",
         "incomplete": "<nije preuzeto>",
         "feature_list": "Značajke pretrage",
-        "edit": "Urediti značajku"
+        "edit": "Urediti značajku",
+        "none": "Ništa"
     },
     "background": {
         "title": "Pozadina",
         "description": "Podešavanja pozadine",
         "percent_brightness": "prozirnost {opacity}% ",
+        "none": "Ništa",
         "custom": "Prilagođena pozadina",
         "custom_prompt": "Unesite šablon pločica. Validni simboli su {z}, {x}, {y} za Z/X/Y šemu i {u} za \"QuadTile\" šemu.",
         "fix_misalignment": "Popravite poravnanje",
     "cannot_zoom": "Ne može se umanjiti više u trenutnom načinu.",
     "gpx": {
         "local_layer": "Lokalna GPX datoteka",
-        "drag_drop": "Povući i spustiti .gpx datoteku na stranicu"
+        "drag_drop": "Povući i spustiti .gpx datoteku na stranicu, ili kliknuti na dugme na desnoj strani za pregled",
+        "zoom": "Zumirati na GPX trasu",
+        "browse": "Tražiti .gpx datoteku"
     },
     "help": {
         "title": "Pomoć",
         "editing_saving": "# Uređivanje i spremanje\n\nOvaj editor je dizajniran da primarno radi online, i pristupate mu\nkroz web stranicu upravo sada.\n\n### Odabir značajki\n\nDa odaberete značajku na karti, kao npr. cestu ili tačku od interesa, kliknite\nna istu na karti. Ovo će osvijetliti odabranu značajku, otvoriti panel sa\ndetaljima o istoj, i pokazati izbor stvari koje možete uraditi sa značajkom.\n\nDa odaberete više značajki odjednom, držite tipku 'Shift'. Onda ili kliknite\nna značajke koje želite odabrati, ili povucite na karti da nacrtate pravougaonik.\nOvo će nacrtati kutiju i odabrati sve tačke unutar iste.\n\n### Spremanje uređivanja\n\nKada uradite promjene kao što su uređivanje cesta, zgrada i mjesta, isti se\npohranjuju lokalno sve dok ih ne spremite na server. Ne brinite ako napravite\ngrešku - možete poništiti promjene klikom na dugme \"Poništiti\", i vratiti\npromjene klikom na dugme \"Vratiti\".\n\nKliknite na 'Spremiti' da završite grupu uređivanja - npr, ako ste završili\ndio grada i želite započeti uređivanje na novom području. Imaćete priliku\nda pregledate šta ste uradili, a editor daje prijedloge od pomoći\ni upozorenja ako se nešto ne čini uredu sa promjenama.\n\nAko sve izgleda uredno, možete unijeti kratak komentar kojim objašnjavate promjene\nkoje ste napravili, i kliknite na 'Spremiti' opet kako bi postavili promjene\nna [OpenStreetMap.org](http://www.openstreetmap.org/), gdje su one vidljive\nsvim drugim korisnicima i dostupne za druge da ih dalje uređuju i poboljšavaju.\n\nAko ne možete završiti vaša uređivanja u jednom sjedenju, možete napustiti prozor\neditora i vratiti se (na istom pregledniku i računaru), i\naplikacija editora će ponuditi da vratite vaš rad.\n",
         "roads": "# Putevi\n\nMožete crtati, popravljati, i brisati puteve sa ovim uređivačem. Putevi mogu biti svih\nvrsta: staze, ceste, tragovi, biciklističke staze, i više - bilo koji često prelaženi\nsegment bi trebao biti moguć za ucrtavanje.\n\n### Odabir\n\nKliknite na put da ga odaberete. vanjska linija bi trebala postati vidljiva, zajedno\nsa malim menijem alata na karti i bočnom trakom koja pokazuje više informacija\no putu.\n\n### Izmjena\n\nČesto ćete vidjeti puteve koji nisu poravnati da satelistskim slikama iza njih\nili sa GPS trasom. Možete podesiti ove puteve tako da su na pravom\nmjestu.\n\nPrvi klik na put koji želite mijenjati. Ovo će ga označiti i pokazati\nkontrolne tačke uz njega koje možete pomjerati na bolje lokacije. Ukoliko\nželite dodati nove kontrolne tačke za više detalja, dva puta kliknite na dio\nputa bez čvora, i jedan će biti dodan.\n\nUkoliko se put povezuje na drugi put, ali se neprikladno povezuje na\nkartu, možete povući jednu od njegovih kontnrolnih tačaka na drugi put u\nnamjeri da ih spojite. Održavanje puteva povezanim je važno za kartu\ni od vitalnoj je značaja za obezbjeđivanje uputa za vožnju.\n\nMožete takođe kliknuti na alat 'Pomjeriti' ili pritisnuti 'M' tipku koja je prečica da pomičete cijeli put\nistovremeno, i onda kliknete opet da spasite to pomicanje. \n\n### Brisanje\n\nUkoliko je put u potpunosti netačan - možete vidjeti da ne postoji na satelitskoj\nslici i idealno bi bilo da potvrdite da nije prisutan lokalno - možete ga izbrisati,\nšto ga uklanja sa karte. Budite pažljivi kada brišete značajke -\nkao i svako drugo uređivanje, rezultati su vidljivi svima i satelitske slike\nsu često stare, tako da bi put mogao ustvari biti novoizgrađeni.\n\nMožete izbrisati put klikom na njega da ga odaberete, i onda klikajući na\nikonu kante za smeće ili pritiskom na tipku 'Delete'.\n\n### Pravljenje\n\nNašli ste negdje da bi tu trebao biti put ali ga nema? Kliknite ikonu 'Linija'\nu donjem lijevom uglu uređivača ili pritisnite tipku`2` da bi započeli crtanje\nlinije.\n\nKliknite na početak puta na kartu da započnete crtanje. Ukoliko se put\ngranan sa postojećeg puta, započnite sa mjesta gdje se povezuju.\n\nOnda kliknite na tačke uzduž puta tako da slijedi pravu putanju, prema\nsatelitskim slikama ili prema GPS-u. Ukoliko se put koji crtate križa sa drugim putem, povežite\nga klikom na tačku križanja. Kada završite crtanje, dva puta kliknite\nili pritisnite 'Backspace' ili 'Enter' na Vašoj tastaturi.\n",
         "gps": "# GPS\n\nGPS podaci su napouzdaniji izvor podataka za OpenStreetMap. Ovaj uređivač\npodržava lokalne trase - `.gpx` datoteke na Vašem lokalnom računaru. Možete sakupiti\novu vrstu GPS trasa sa brojnim \"smartphone\" aplikacijama kao i sa\nličnim GPS hardverom.\n\nZa informacije kako izbršiti GPS istraživanje, pročitajte\n[Istraživanje sa GPS-om](http://learnosm.org/en/beginner/using-gps/).\n\nDa bi koristili GPX trase za mapiranje, povucite i spustite GPX datoteku na uređivač\nkarte. Ukoliko je prepoznat, biće dodan karti kao svjetlo zelena\nlinija. Kliknite na meni 'Podešavanja pozadine' na lijevoj strani da omogućite,\nonemogućite, ili uvećate ovaj novi sloj pokretan GPX-om.\n\nGPX trasa ne biva direktno postavljena na OpenStreetMap - najbolji način\nda se ona koristi je crtanje na karti, koristeći je kao vodilju za nove značajke koje\nVi dodajete, i takođe možete [da je postavite na OpenStreetMap](http://www.openstreetmap.org/trace/create)\nza druge korisnike da je koriste.\n",
-        "imagery": "# Satelitske slike\n\nSatelitske slike su važan resurs za mapiranje. Kombinacija\npreleta avionom, satelitski pogledi i slobodno sastavljeni izvori su dostupni\nu uređivaču pod menijem 'Podešavanja pozadine' na lijevoj strani.\n\nU početnik postavkama satelitski sloj [Bing Maps] (http://www.bing.com/maps/) je\nprezentiran u uređivaču, ali kako pomičete i uvećavate kartu na nova geografska\npodručja, novi će izvori postati dostupni. Neke zemlje, poput Sjedinjenih\nDržava, Francuske i Danske imaju slike vrlo visoke kvalitete na raspolaganju za neka područja.\n\nSatelitske slike ponekad odstupaju od podataka karte, zbog greške na\nstrani davatelja satelitskih slika. Ako vidite puno cesta pomjerenih u pozadini.\nnemojte ih odmah sve premještati kako bi se slagale sa pozadinom. Umjesto toga možete podesiti\nsatelitske slike tako da odgovaraju postojećim podacima klikom na 'Popravljanje poravnanja', na\ndnu interfejsa Postavki pozadine.\n",
+        "imagery": "# Satelitske slike\n\nSatelitske slike su važan resurs za mapiranje. Kombinacija\npreleta avionom, satelitski pogledi i slobodno sastavljeni izvorisu dostupni\nu uređivaču pod menijem 'Podešavanja pozadine' na desnoj strani.\n\nU početnik postavkama satelitski sloj [Bing Maps] (http://www.bing.com/maps/) je\nprezentiran u uređivaču, ali kako pomičete i uvećavate kartu na nova geografska\npodručja, novi će izvori postati dostupni. Neke zemlje, poput Sjedinjenih\nDržava, Francuske i Danske imaju slike vrlo visoke kvalitete na raspolaganju za neka područja.\n\nSatelitske slike ponekad odstupaju od podataka karte, zbog greške na\nstrani davatelja satelitskih slika. Ako vidite puno cesta pomjerenih u pozadini.\nnemojte ih odmah sve premještati kako bi se slagale sa pozadinom. Umjesto toga možete podesiti\nsatelitske slike tako da odgovaraju postojećim podacima klikom na 'Popravljanje poravnanja', na\ndnu interfejsa Podešavanja pozadine.\n",
         "addresses": "# Addrese\n\nAddrese su neke od najkorisnijih informacija na karti.\n\nIako su adrese često predstavljene kao dijelovi ulica, na karti OpenStreetMap\nsu one spremljene kao atributi građevina i mjesta uz ulice.\n\nMožete dodati informaciju o adresama mjesta koja su ucrtana kao i vanjske linije građevina takođe\nkao i onih koja su ucrtana kao obične tačke. Optimalni izvor podataka adresa\nse dobija iz istraživanja na licu mjesta ili ličnim znanjem- kao što je slučaj sam bilo kojom drugom značajkom,\nkopiranje iz komercijalnih izvora kao što je Google Maps je striktno\nzabranjeno.\n",
-        "inspector": "# Korištenje inspektora\n\nInspektor je element korisničkog interfejsa na desnoj strani\nstranice koji se pojavljuje kada je značajka odabrana i dozvoljava Vam da uređujete njene detalje.\n\n### Odabir vrste značajke\n\nNakon što dodate tačku, liniju ili područje, možete birati koja je to vrsta značajke,\nkao npr. da li je to cesta ili rezidencijalna cesta, supermarket ili kafe.\nInspector će prikazati dugmad za vrste općih značajki, i možete\nnaći druge unošenjem onoga što tražite u polje za pretragu.\n\nKliknite na 'i' u donjem desnom uglu dugmeta vrste značajke da\nsaznate više o istoj. Kliknite na dugme da odaberete tu vrstu.\n\n### Korištenje obrazaca i oznaka za uređivanje\n\nNakon što odaberete vrstu značajke, ili kada odaberete značajku koja već\nima pripisanu vrstu, inspektor će prikazati polja sa detaljima o\nznačajki kao što je njen naziv i adresa.\n\nIspod polja koje vidite, možete kliknuti na ikone da dodate druge detalje,\nkao što su informacije sa stranice [Wikipedia](http://www.wikipedia.org/), prustup\nza invalidska kolica, i drugo.\n\nNa dnu inspektora, kliknite 'Dodatne oznake' da dodate još neke\ndruge oznake elementu. [Taginfo](http://taginfo.openstreetmap.org/) je\nodličan izvor za više informacija o popularnim kombinacijama oznaka.\n\nPromjene koje napravite u inspektoru bivaju automatski primijenjene na karti.\nMožete ih poništiti bilo kad klikom na dugme za poništavanje.\n\n### Zatvaranje inspektora\n\nMožete zatvoriti inspektor klikom na dugme za zatvaranje u gornjem desnom uglu,\npritiskom na tipku 'Esc', ili klikom na kartu.\n",
+        "inspector": "# Korištenje inspektora\n\nInspektor je element korisničkog interfejsa na lijevoj strani\nstranice koji vam dozvoljava da uređujete odabranu značajku.\n\n### Odabir vrste značajke\n\nNakon što dodate tačku, liniju ili područje, možete birati koja je to vrsta značajke,\nkao npr. da li je to cesta ili rezidencijalna cesta, supermarket ili kafe.\nInspector će prikazati dugmad za vrste općih značajki, i možete\nnaći druge unošenjem onoga što tražite u polje za pretragu.\n\nKliknite na 'i' u donjem desnom uglu dugmeta vrste značajke da\nsaznate više o istoj. Kliknite na dugme da odaberete tu vrstu.\n\n### Korištenje obrazaca i oznaka za uređivanje\n\nNakon što odaberete vrstu značajke, ili kada odaberete značajku koja već\nima pripisanu vrstu, inspektor će prikazati polja sa detaljima o\nznačajki kao što je njen naziv i adresa.\n\nIspod polja koje vidite, možete kliknuti na ikone da dodate druge detalje,\nkao što su informacije sa stranice [Wikipedia](http://www.wikipedia.org/), pristup\nza invalidska kolica, i više.\n\nNa dnu inspektora, kliknite 'Dodatne oznake' da dodate još neke\ndruge oznake elementu. [Taginfo](http://taginfo.openstreetmap.org/) je\nodličan izvor za više informacija o popularnim kombinacijama oznaka.\n\nPromjene koje napravite u inspektoru bivaju automatski primijenjene na karti.\nMožete ih poništiti bilo kad klikom na dugme za poništavanje.\n",
         "buildings": "# Građevine\n\nOpenStreetMap karta je najveća svjetska baza građevina. Možete napraviti\ni proširiti ovu bazu podataka.\n\n### Odabir\n\nMožete odabrati građevinu odnosno zgradu klikom na njene granice. Ovo će označiti\ngrađevinu i otvoriti mali meni alata i bočnu traku koja pokazuje više informacija\no građevinama.\n\n### Izmjena\n\nPonekad su građevine nepravilno postavljene ili imaju nepravilne oznake.\n\nDa bi pomjerili cijelu građevinu, odaberite je, i onda kliknite na alat 'Pomicanje'. Pomaknite Vaš\nmiš da pomjerite građevinu, i kliknite kada je ona pravilno postavljena.\n\nDa bi popravili specifičan oblik građevine, kliknite i povucite čvorove koji formiraju\nnjenu granicu na bolje mjesto.\n\n### Pravljenje\n\nJedno od glavnih pitanja oko dodavanja zgrada karti je to da\nOpenStreetMap snima građevine i kao oblike i kao tačke. Pravilo palca\nje _ucrtavati građevinu kao oblik gdje god je moguće_, kao i ucrtavati kompanije, domove,\ni druge značajne građevine, a i druge stvari koje operiraju van građevina kao tačke smještene\nunutar oblika građevine.\n\nZapočnite crtati građevinu kao oblik klikom na dugme 'Područje' u gornjem\nlijevom dijelu interfejsa, i završite je pritiskom na 'Backspace' na Vašoj tastaturi\nili klikom na prvi čvor koji je ucrtan kako bi zatvorili oblik.\n\n### Brisanje\n\nUkoliko je građevina u potpunosti netačna - možete vidjeti da ne postoji u satelitskim\nslikama i idealno dobro bi bilo da potvrdite da lokalno nije prisutna -  možete je obrisati,\nšto je uklanja sa karte. Budite pažljivi kada brišete značajke -\nkao i svako drugo uređivanje, rezultate vide svi i satelitske slike\nsu često stare, tako da bi građevina mogla biti novoizgrađena.\n\nMožete izbrisati građevinu klikom na nju da bi ste je odabrali, i onda kliknuti na\nikonu kante za smeće ili pritiskom na tipku 'Delete'.\n",
         "relations": "# Relacije\n\nRelacija je posebna vrsta značajke OpenStreetMap projektu koja grupira\ndruge značajke. Na primjer, dvije uobičajene vrste relacija su *relacije ruta*,\nkoje zajedno grupiraju dijelove puta koji pripadaju posebnom putu ili\nautoputu, i  *multipoligoni*, koji zajedno grupiraju nekoliko linija koje definiraju\nsloženo područje (jedno sa više dijelova ili rupa u sebi kao krofna).\n\nGrupa značajki u relaciji se naziva *članovi*. Na Bočnoj traic, možete\nvidjeti kojoj relaciji pripada član, i kliknuti na relaciju\nda je odaberete. Kada je relacija odabrana možete vidjeti sve njene\nčlanove izlistane na bočnoj traci i osvijetljene na karti.\n\nU većini slučajeva, iD editor će voditi računa o održavanju relacija automatski\ndok uređujete. Glavna stvar koje trebate biti svjesni jeste da ako izbrišete\ndio puta u namjeri da ga nacrtate tačnije, morate biti sigurni da je\nnovi dio član istih relacija kao i original.\n\n## Uređivanje relacija\n\nAko želite uređivati relacije, ovo su osnove.\n\nDa dodate značajku relaciji, odaberite značajku, kliknite na dugme \"+\" u\ndijelu \"Sve relacije\" na bočnoj traci, i izaberite ili ukucajte naziv relacije.\n\nDa napravite novu relaciju, prvo odaberite značajku koja treba biti član,\nkliknite na dugme \"+\" u dijelu \"Sve relacije\", i izaberite \"Nova relacija...\".\n\nDa uklonite značajku iz relacije, odaberite značajku i kliknite na dugme smeće\nkoje se pojavljuje uy relaciju iz koje je želite ukloniti.\n\nMožete praviti multipoligone sa rupama koristeći alat \"Spojiti\". Nacrtajte dva područja (unutrašnje i\nvanjsko), držite tipku Shift i kliknite na svaku od njih da ih izaberete, a potom\nkliknite na dugme \"Spojiti\" (+).\n"
     },
                 "name": "Rekreacija",
                 "terms": "rekreacija,razonoda"
             },
+            "leisure/common": {
+                "name": "Uobičajeno",
+                "terms": "uobičajeno,uobičajeno ime,uobičajeni naziv"
+            },
             "leisure/dog_park": {
                 "name": "Igralište za pse",
                 "terms": "igralište za pse,park za pse"
                 "name": "Svjetionik",
                 "terms": "svjetionik,toranj za svjetlosnu navigaciju"
             },
+            "man_made/observation": {
+                "name": "Osmatračnica",
+                "terms": "osmatračnica,toranj za osmatranje,platforma za osmatranje,toranj za turiste,protupožarni toranj"
+            },
             "man_made/pier": {
                 "name": "Pristanište",
                 "terms": "pristanište,mol"
                 "name": "Praonica",
                 "terms": "praonica,servis za pranje rublja"
             },
+            "shop/locksmith": {
+                "name": "Bravar",
+                "terms": "bravar,kopiranje ključeva,bravarija"
+            },
             "shop/mall": {
                 "name": "Tržni centar",
                 "terms": "tržni centar,supermarket,hipermarket"
index 1f9c727fc7ce98131a904a46332a66e30b4e6d51..a339d7a2570288bf16d07346811d3e0ba3409568 100644 (file)
@@ -83,7 +83,8 @@
             "annotation": {
                 "line": "Heu quadrat les cantonades d'una línia.",
                 "area": "Heu quadrat les cantonades d'una àrea."
-            }
+            },
+            "not_squarish": "Això no es pot quadrar perquè no té forma quadrada"
         },
         "straighten": {
             "title": "Fer recta",
         "back_tooltip": "Canvia la característica",
         "remove": "Elimina",
         "search": "Cerca",
+        "multiselect": "Els ítems seleccionats",
         "unknown": "Desconegut",
         "incomplete": "<no baixat>",
         "feature_list": "Cerca característiques",
-        "edit": "Editar la característica"
+        "edit": "Editar la característica",
+        "none": "Cap"
     },
     "background": {
         "title": "Fons",
         "description": "Paràmetres de configuració del fons",
         "percent_brightness": "{opacity}% brillantor",
+        "none": "Cap",
         "custom": "Personalitza",
         "custom_prompt": "Introdueix una plantilla de casella. Els paràmetres vàlids són {z}, {x}, {y} per a l'esquema Z/X/Y i  {u} per a l'esquema quadtile.",
         "fix_misalignment": "Corregeix la desalineació",
     "cannot_zoom": "No es pot allunyar més la vista al mode actual.",
     "gpx": {
         "local_layer": "Fitxer GPX local",
-        "drag_drop": "Arrossega i deixa un fitxer .gpx a la pàgina"
+        "drag_drop": "Arrosegueu i deixeu un fitxer .gpx a la pàgina, o bé cliqueu el botó que es troba a la dreta per navegar pel vostre sistema.",
+        "zoom": "Ajusteu la vista a la traça GPX",
+        "browse": "Buscar el fitxer .gpx"
     },
     "help": {
         "title": "Ajuda",
         "editing_saving": "# Edició i desat\n\nAquest editor està dissenyat per treballar principalment en línia, i hi has accedit mitjançant una pàgina web.\n\n### Selecció de característiques\n\nPer selecionar una característica del mapa, com ara una carretera o un punt d'interès, clica-hi a sobre. Això ressaltarà la característica, obrirà un panell amb els detalls sobre aquesta, i un menú amb les coses que hi pots fer .\n\nPots seleccionar múltiples característiques, prement la tecla 'Shift' i clicant-les per separat, o bé clicant i arrossegant el cursor. Això seleccionarà totes les característiques que englobi el requadre que es dibuixarà i permetrà modificar totes les característiques seleccionades en un sol cop.\n\n### Desant les edicions\n\nQuan facis canvis com ara editar carreteres, edificis, o llocs, aquests canvis es guarden localment fins que els desis al servidor. No et preocupis si comets algun error- pots desfer els canvis clicant el botó de desfer, i pots refer els canvis clicant el botó de refer.\n\nClica 'Desa' per acabar un grup d'edicions - per exemple, si has acabat de delimitar l'àrea d'una ciutat i vols començar a fer-ne una altra. Tindràs la oportunitat de revisar la feina feta,\ni l'editor proporcionarà suggeriments que et podràn ajudar\ni també mostrarà alertes si alguna cosa no està del tot bé als teus canvis.\n\nSi tot sembla correcte, pots escriure un breu comentari explicant el canvis\nque has fet, i clicar desa un altre cop per publicar els canvis\na [OpenStreetMap.org](http://www.openstreetmap.org/), on seràn visibles\nper a tots els altres usuaris i disponibles per a altres editors per refer-los o bé millorar-los.\n\nSi no pots acabar les teves edicions en una sessió, pots sortir de la finestra d'edició i tornar més tard (al mateix navegador i ordinador), i l'aplicació d'edició\npreguntarà si vols restaurar els canvis anteriors.\n",
         "roads": "# Carreteres\n\nPots crear, ajustar i eliminar carreteres amb aquest editor. Les carreteres poden ser\nde molts tipus: pistes, autovies, camins, carrils bici, i molts més - tots els segments\nmés comuns han de ser cartografiables.\n\n### Selecció\n\nClica a la carretera per seleccionar-la. Al fer això els seus contorns es faran visibles, \ncom també un petit menú d'eines i una barra lateral que mostrarà més informació\nsobre la carretera.\n\n### Modificació\n\nDe vegades veuràs carreteres que no estan alineades amb la imatge del darrere \no amb una traça de GPS. Podeu ajustar aquestes carreteres per tal que estiguin al lloc\ncorrecte.\n\nPrimer clica a la carretera que vols canviar. Això la ressaltarà i mostrarà els punts de control\nque pots arrossegar a les ubicacions desitjades. Si el que\nvols és afegir nous punts per obtenir un grau de detall més alt, fes doble clic en una part de la carretera sense cap punt, i se'n afegirà un.\n\nSi la carretera es connecta amb una altra, però no ho reflecteix al mapa, \npots arrossegar un dels punts de control cap a l'altre carretera \nper tal d'unir-les. Fer que les carreteres es connectin és molt important \nper al mapa i essencial per proveir direccions per a la conducció.\n\nTambé pots clicar l'eina «Moure» o prémer la tecla «M» per moure la carretera sencera, tota de cop, i llavors clicar altra vegada per guardar aquest moviment.\n\n### Eliminació\n\nSi una carretera està totalment malament -pots apreciar que no existeix a la imatge per satèl·lit\ni a més a més, els veïns ens han confirmat que no existeix - la pots eliminar, cosa que la treurà del mapa. Vés amb molt de compte a l'hora d'eliminar característiques -\ncom ara altres edicions; els resultats podran ser vistos per tothom i moltes vegades la imatgeria per satèl·lit no està actualitzada, per tant la carretera es pot haver estat construida recentment.\n\nPots eliminar una carretera clicant-la, i llavors clicant la icona de la paperera o bé prement la tecla «Suprimir».\n\n### Creació\n\nHas trobat que en algun lloc hi hauria d'haver una carretera però no hi és? Clica la icona «Línia»\nal marge superior esquerre de la zona del mapa o bé prem la tecla «2» per començar a dibuixar\nuna línia.\n\nClica a l'inici de la carretera al mapa per començar a dibuixar. Si la carretera comença amb una bifurcació en una carretera existent, cliqueu al lloc a on connecten.\n\nA continuació clica a diferents punts al llarg de la carretera per tal que segueixi el traçat correcte, d'acord  amb la imatge del satèl·lit o la traça del GPS. Si la carretera que estàs dibuixant s'encreua amb una altra carretera, connecta-les clicant al punt d'intersecció. Quan acabis el dibuix, fes doble clic o prem «Retorn» del teclat.\n",
         "gps": "# GPS\n\nLes dades de GPS són la font més fiable de dades per a l'OpenStreetMap. Aquest editor és compatible amb les taces locals - fitxers`.gpx`al teu ordinador local. Pots recollir \naquest tipus de traça GPS amb algunes aplicacions per a smartphones com també \ndispositius personals de GPS.\n\nPer a més informació sobre com recollir dades amb GPS, llegeix\n[Recollir dades amb GPS](http://learnosm.org/en/beginner/using-gps/).\n\nper fer servir una traça GPX per editar el mapa, arrossega i deixa el fitxer GPX a l'editor. \nSi es detecta, s'afegirà el mapa com una línia verda llampant. \nClica a 'Paràmetres de configuració del fons'  al cantó esquerre per activar,\ndesactivar, o per ajustar la vista a aquesta capa GPX.\n\nLa traça GPX no és pujada directament a OpenStreetMap - la millor manera de \nfer-la servir és dibuixar tu el mapa, fent-la servir com a guia per a les noves característiques que afegiràs. també les pots [pujar a l'OpenStreetMap] \n(http://www.openstreetmap.org/trace/create)\nperquè d'altres persones les utilitzin.\n",
-        "imagery": "# Imatgeria\n\nLa imatgeria aèria és un recurs important per a l'edició de mapes. Una combinació de\nvols d'aeronaus, fotografies de satèl·lit, i d'altres fonts compilades gratuïtament \nestan disponibles a l'editor dins del menú de l'esquerre 'Paràmetres de configuració del fons'.\n\nPer defecte, l'editor mostra la capa de satèl·lit de [Bing Maps](http://www.bing.com/maps/), però a mesura que et mous i ajustes la vista del mapa a noves àrees geogràfiques, noves fonts estaran disponibles. En alguns països, com ara els Estats Units, França, i Dinamarca tenen\n una imatgeria d'alta qualitat disponible per a determinades àrees.\n\nLa imatgeria de vegades no es correspon amb les dades del mapa, això és degut a un error\nper part del proveïdor de la imatge. Si veieu moltes carreteres mogudes del seu lloc a la imatge,\nno les mogueu per tal que encaixin amb aquesta. Ja que pots ajustar la imatgeria per tal de que quadri amb les dades existents clicant a 'Corregeix la desalineació' a sota de la pestanya dels\n'Paràmetres de configuració del fons'.\n",
+        "imagery": "# Imatgeria\n\nLa imatgeria aèria és un recurs important per a l'edició de mapes. Una combinació de\nvols d'aeronaus, fotografies de satèl·lit, i d'altres fonts compilades gratuïtament \nestan disponibles a l'editor dins del menú de l'esquerra 'Paràmetres de configuració del fons'.\n\nPer defecte, l'editor mostra la capa de satèl·lit de [Bing Maps](http://www.bing.com/maps/), però a mesura que et mous i ajustes la vista del mapa a noves àrees geogràfiques, noves fonts estaran disponibles. En alguns països, com ara els Estats Units, França, i Dinamarca tenen\n una imatgeria d'alta qualitat disponible per a determinades àrees.\n\nLa imatgeria a vegades no es correspon amb les dades del mapa, això és degut a un error\nper part del proveïdor de la imatge. Si veus moltes carreteres mogudes del seu lloc a la imatge,\nno les moguis per tal que encaixin amb aquesta. Ja que pots ajustar la imatgeria per tal de que quadri amb les dades existents clicant a 'Corregeix la desalineació' al capdevall de la pestanya dels\n'Paràmetres de configuració del fons'.\n",
         "addresses": "# Adreçes\n\nLes adreçes són una de les informacions més útils per al mapa.\n\nTot i que les adreces sovint es representen com a part del carrer, a l'OpenStreetMap\nes desen com a atributs dels edificis i llocs al llarg dels carrers\n\nPodeu afegir la informació de l'adreça a llocs cartografiats com a edificis com també\na aquells llocs cartografiats com a simples punts. La forma òptima d'obtenir dades \nde les adreces és a partir d'un estudi al carrer o bé el coneixement propi - com a qualsevol altra característica, la còpia de fonts comercials com ara el Google Maps és estrictament prohibida.\n",
-        "inspector": "# Ús de l'inspector\n\nL'Inspector és l'element de la interfície d'usuari que es troba al cantó esquerre de la pàgina i que \napareix quan una característica és seleccionada i permet editar-ne els detalls.\n\n### Selecció del tipus de característica\n\nDesprés d'afegir un punt, línia, o àrea, pots escollir quin tipus de característica és.\nTant si és una autopista com un carrer residencial, un supermercat o un cafè.\nL'inspector mostrarà botons per als tipus de característica més comuns, i en pots trobar d'altres escrivint el que estàs cercant al quadre de cerca.\n\nFes clic a la «i» al cantó inferior dret del botó  del tipus de característica per saber-ne més. Fes clic al botó per seleccionar-la.\n\n### Utilització dels camps i les etiquetes d'edició\n\nDesprés d'escollir la característica, o quan seleccionis una característica que ja té\nun tipus assignat, l'inspector mostrarà uns camps amb detalls de la característica \ncom ara el seu nom o la seva adreça .\n\nA sota dels camps que veus, pots clicar algunes icones per afegir altres detalls,\ncom ara informació de la [Viquipèdia](http://ca.wikipedia.org/), l'accés per a cadires de rodes,\ni alguna cosa més.\n\nAl capdavall de l'inspector, clica «Etiquetes addicionals» per afegir altres etiquetes arbitràries a l'element. [Taginfo](http://taginfo.openstreetmap.org/) és una gran eina per aprendre'n més sobre les combinacions d'etiquetes més populars.\n\nEls canvis que facis a l'inspector s'aplicaran automàticament al mapa.\nEls pots desfer en qualsevol moment clicant al botó de «Desfés».\n\n##Tancament de l'inspector\n\nPots tancar l'inspector clicant el botó de tancament al cantó superior dret,\nprement la tecla «Esc», o bé clicant al mapa.\n",
+        "inspector": "# Utilitzant l'inspector\n\nL'Inspector és l'element de l'interfície d'usuari que es troba al cantó dret de la pàgina i que+\napareix quan una característica és seleccionada i permet editar-ne els detalls.\n\n### Selecció del tipus de característica\n\nDesprés d'afegir un punt, línia, o àrea, pots escollir quin tipus de característica és,\nTant si és una autopista com un carrer residencial, un supermercat o un cafè.\nL'inspector mostrarà botons per els tipus de característica més comuns, i en pots trobar d'altres escrivint el que estàs buscant al quadre de cerca.\n\nClica la 'i' al cantó inferior dret del botó  del tipus de característica per saber-ne més. Clica el botó per seleccionar-la.\n\n### Utilització dels camps i les etiquetes d'edició\n\nDesprés d'escollir la característica, o quan selecciones una característica que ja té\nun tipus assignat, l'inspector mostrarà uns camps amb detalls de la característica \ncom ara el seu nom o la seva adreça .\n\nA sota dels camps que veus, pots clicar algunes icones per afegir altres detalls,\ncom ara infrmació de la [Viquipèdia](http://www.wikipedia.org/), l'accés per a cadires de rodes,\ni alguna cosa més.\n\nAl capdavall de l'inspector, clica 'Etiquetes adicionals' per afegir altres etiquetes arbitràries a l'element. [Taginfo](http://taginfo.openstreetmap.org/) és una gran eina per aprendre'n més sobre les combinacions d'etiquetes més populars.\n\nEls canvis que facis a l'inspector s'aplicaran automàticament al mapa.\nEls pots desfer en qualsevol moment clicant al botó de 'Desfer' .\n\n",
         "buildings": "# Edificis\n\nL'OpenStreetMap és la base de dades d'edificis més gran del món. Podeu ampliar \ni millorar aquesta base de dades.\n\n### Selecció\n\nPots seleccionar un edifici clicant al seu marge. Això farà ressaltar\nl'edifici i obrirà un petit menú d'eines i una barra lateral mostrant més informació\nsobre l'edifici.\n\n### Modificació\n\nA vegades els edificis estan mal col·locats o tenen etiquetes incorrectes.\n\nPer moure l'edifici sencer, selecciona'l, tot seguit clica l'eina 'Mou'. Desplaça el\ncursor per desplaçar l'edifici, i torna a clicar quan estigui posicionat correctament.\n\nPer ajustar la forma específica d'un edifici, clica i arrossega els nodes que componen \nel seu marge als llocs desitjats.\n\n### Creació\n\nUn dels principals temes sobre l'addició d'edificis al mapa és que\nl'OpenStreetMap pot desar edificis com a punts però també com a figures. La norma general\nper a cartografiar un edifici diu que _aquest s'ha d'expressar, sempre que sigui possible, com a una figura_, i les companyies, empreses,\nequipaments, i d'altres coses que operen als edificis, s'han de cartografiar com a punts \ncol·locats dins de la figura de l'edifici.\n\n\nComença a dibuixar un edifici com a figura clicant el botó 'Àrea' a la zona superior esquerra de la interfície, i finalitzeu-lo o bé prement la tecla 'Retorn' del teclat\no clicant al primer node que heu col·locat per tancar la figura.\n\n### Eliminació\n\nSi un edifici està totalment malament - pots apreciar que no existeix a la imatge per satèl·lit\ni a més a més, els veïns ens han confirmat que no existeix - el pots eliminar, cosa que el traurà del mapa. S'ha d'anar amb molt de compte a l'hora d'eliminar característiques -\ncom totes les altres edicions, els resultats podran ser vistos per tothom i moltes vegades la imatgeria per satèl·lit no està actualitzada, per tant l'edifici pot haver estat construït recentment.\n\nPots eliminar un edifici clicant-lo, i llavors clicant la icona de la paperera o bé prement la tecla 'Suprimir'.\n",
         "relations": "# Relacions\n\nUna relació és un tipus especial de característica a l'OpenStreetMap que reuneix altres característiques. Per exemple, dos tipus comuns de relacions són les *relacions de ruta*,\nque reuneixen seccions de carreteres que pertanyen a una autovia o autopista en concret, i els *multipolígons*, que reuneixen diferents línies que defineixen una àrea complexa (amb vàris segments o amb forats, com un donut).\n\nEl grup de característiques en una relació s'anomena *els membres*. A la barra lateral, pots veure a quines relacions n'és membre una característica, i clicar una relació des d'un membre per seleccionar-la i entrar-hi. Quan selecciones i entres a la relació, pots veure tots els seus membres llistats a la barra lateral i subratllats al mapa .\n\nLa majoria de vegades, l'iD s'encarregarà de mantenir les relacions automàticament\nmentre tu edites. L'única cosa que has de procurar és de reconnectar la relació si esborres algun tram de l'original, és a dir si esborres un tram d'una relació per refer-lo amb més precisió, has de incloure el nou tram a la relació, igual que ho era el tram original.\n\n## Edició de les relacions\n\nSi el que vols és editar relacions, aquí hi han les pautes bàsiques.\n\nPer afegir una característica a una relació, selecciona la característica, clica el botó \"+\" a la secció \"Totes les relacions\" de la barra lateral, i selecciona o escriu el nom de la relació.\n\nPer crear una nova relació, selecciona la primera característica que n'hauria de ser membre, clica el botó \"+\" a la secció \"Totes les relacions\", i selecciona \"Nova relació...\".\n\nPer eliminar una característica d'una relació, selecciona la característica i clica el botó de la paperera que es troba al costat de la relació que vols eliminar.\n\nPots crear multipolígons amb forats utilitzant l'eina \"Fusionar\". Dibuixa dues àrees (la interior i la exterior), mantén premuda la tecla Shift i clica a les dues àrees per seleccionar-les alhora, llavors clica el botó \"Fusiona\" (+).\n"
     },
             "leisure": {
                 "name": "Esbarjo"
             },
+            "leisure/common": {
+                "name": "Àrea comuna"
+            },
             "leisure/dog_park": {
                 "name": "Parc Caní"
             },
             "man_made/lighthouse": {
                 "name": "Far"
             },
+            "man_made/observation": {
+                "name": "Torre de vigilància"
+            },
             "man_made/pier": {
                 "name": "Moll de pilons"
             },
             "shop/laundry": {
                 "name": "Bugaderia"
             },
+            "shop/locksmith": {
+                "name": "Copisteria de claus"
+            },
             "shop/mall": {
                 "name": "Centre comercial"
             },
index f8dabd36b1caf87f38290f828785ecfa71366c4b..fb90cdf7355ac32023699463375086f688a8d286 100644 (file)
@@ -83,7 +83,8 @@
             "annotation": {
                 "line": "Úhly cesty do pravého úhle.",
                 "area": "Rohy plochy do pravého úhle."
-            }
+            },
+            "not_squarish": "Z objektu není možné udělat čtverec, protože se čtverci vůbec nepodobá."
         },
         "straighten": {
             "title": "Narovnat",
         "back_tooltip": "Změnit objekt",
         "remove": "Odstranit",
         "search": "Hledat",
+        "multiselect": "Zvolené objekty",
         "unknown": "Není známo",
         "incomplete": "<nebylo staženo>",
         "feature_list": "Hledat objekty",
-        "edit": "Editovat objekt"
+        "edit": "Editovat objekt",
+        "none": "Žádné"
     },
     "background": {
         "title": "Pozadí",
         "description": "Nastavení pozadí",
         "percent_brightness": "{opacity}% viditelnost",
+        "none": "Žádné",
         "custom": "Vlastní",
         "custom_prompt": "Vložte šablonu adres dlaždic. Lze použít tokeny {z}, {x}, {y} pro schéma Z/X/Y a {u} pro hierarchické schéma quadtile.",
         "fix_misalignment": "Zarovnat pozadí",
     "cannot_zoom": "Aktuální nastavení nedovoluje větší zvětšení.",
     "gpx": {
         "local_layer": "Vlastní GPX soubor",
-        "drag_drop": "Přetáhněte do editoru soubor .gpx"
+        "drag_drop": "Přetáhněte do editoru soubor .gpx nebo klikněte na tlačítko vpravo a zvolte soubor pomocí dialogu.",
+        "zoom": "Zvětšit na stopu GPX",
+        "browse": "Zvolit .gpx soubor v dialogu"
     },
     "help": {
         "title": "Pomoc",
         "editing_saving": "# Editace a publikace\n\nTento editor pracuje primárně online - právě teď k němu přistupujete prostřednictvím webové stránky.\n\n### Výběr objektů\n\nChcete-li vybrat objekt, jako třeba silnici nebo obchod, klikněte na něj v mapě. Objekt se tím označí, otevře se boční panel s vlastnostmi objektu a zobrazí se nabídka akcemi, které lze s objektem provést.\n\nMůžete označit a pracovat s několika objekty najednou: podržte klávesu 'Shift', a pak buď postupně označte dotyčné objekty, anebo klikněte na mapu a táhněte myší či prstem - editor označí všechny objekty uvnitř příslušného obdélníku.\n\n### Publikace změn\n\nKdyž provedete nějaké úpravy objektů v mapě, úpravy jsou uloženy lokálně ve vašem prohlížeči. Nelekejte se, když uděláte chybu - úpravy lze vrátit zpět tlačítkem Zpět, a naopak je znovu provést tlačítkem Znovu.\n\nPo dokončení bloku úprav klikněte na 'Uložit' - například když jste upravili jednu část města, a chcete začít úpravy někde jinde. Zobrazí se přehled úprav, které jste provedli, editor tyto úpravy zkontroluje, a když se mu něco nebude zdát, zobrazí varování a návrhy.\n\nKdyž bude všechno v pořádku, můžete přidat krátký komentář s vysvětlením vašich úprav a kliknout znovu 'Uložit'. Úpravy se tímto publikují na [OpenStreetMap.org](http://www.openstreetmap.org/), kde za chvíli budou viditelné pro všechny uživatele a bude na nich možné provádět další úpravy.\n\nPokud nechcete nebo nemůžete pravy dokončit teď, stačí prostě odejít ze stránky pryč. Až příště navštívíte stránku (na stejném počítači, ve stejném prohlížeči), editor vám nabídne možnost znovu načíst neuložené úpravy.\n",
         "roads": "# Cesty\n\nEditor umožňuje vytvářet, opravovat a mazat silnice, pěšiny, cyklostezky, železnice atd. Zmapovat by mělo jít jakýkoli druh komunikace.\n\n### Výběr\n\nKdyž na cestu kliknete, zbarví se její obrys, otevře se u ní malá nabídka s nástroji a dále boční panel s informacemi o cestě.\n\n### Úpravy\n\nČasto narazíte na cesty, které jen nepřesně sledují pozadí či trasu GPS. Takové cesty můžete zarovnat na správné místo.\n\nNapřed klikněte na cestu, kterou chcete upravit. Cesta se rozsvítí a podél ní se objeví kontrolní uzly, které můžete posunout na správné místo. Pokud chcete přidat další kontrolní body a zpřesnit tak průběh cesty, stačí dvakrát kliknout na kus cesty mezi dvěma uzly - na zvolené místo přibude nový uzel.\n\nKdyž je reálná cesta napojena na jinou, ale v mapě spojeny nejsou, posuňte myší kontrolní uzel jedné cesty nad druhou - cesty se pak spojí. Propojení cest je velmi důležité pro správnou funkci navigací.\n\nTaké můžete posunout najednou celou cestu: buď klikněte na ikonu posunu v menu zobrazeném u cesty nebo stiskněte klávesu `M` a potom klikněte myší pro ukončení posunu. Jen pozor - pokud jsou vůči pozadí či GPS stopě všechny objekty v okolí, pravděpodobně to bude chybným pozadím a ne chybnou polohou objektů.\n\n### Mazání\n\nPokud je cesta úplně špatně, můžete ji zcela odstranit z mapy. Neměli byste se spoléhat pouze na satelitní snímky - mohou být zastaralé nebo zavádějící -, ideální je se přesvědčit na místě, že cesta opravdu neexistuje. Zvlášť při mazání objektů buďte opatrní - výsledek vaší úpravy se projeví v mapě pro všechny její uživatele.\n\nCestu smažete tak, že na ni kliknete a zvolíte ikonu odpadkového koše nebo stisknete klávesu Delete.\n\n### Vytváření\n\nNarazili jste na cestu, která by v mapě měla být, ale není? Klikněte na tlačítko 'Cesta' vlevo nahoře nebo stiskněte klávesu `2` - to vám umožní nakreslit novou cestu.\n\nKlikněte na místo, kde cesta začíná. Pokud cesta vychází z jiné, existující cesty, klikněte na místo, kde se cesty oddělují.\n\nPotom postupně klikejte na body, kudy cesta vede, podle satelitních snímků nebo trasy z GPS. Pokud vaše cesta protíná jinou, je třeba je propojit tak, že kliknete na bod křížení. Nakonec dvakrát klikněte na stejné místo nebo stiskněte klávesu 'Return' nebo 'Enter', cesta se tak ukončí.\n",
         "gps": "# GPS\n\nData z GPS jsou nejdůvěryhodnějším zdrojem informací pro OpenStreetMap. Tento editor podporuje zobrazení tras ve formátu `.gpx` nahraných z vašeho počítače. Takovou trasu můžete nasbírat s pomocí nejrůznějších aplikací pro mobily nebo s pomocí specializované navigace.\n\nPro více informací, jak provést takový sběr dat z GPS, viz např. návod anglicky:\n[Surveying with a GPS](http://learnosm.org/en/beginner/using-gps/).\n\nPokud už máte záznam ve formátu GPX, přetáhněte soubor myší či prstem nad editor. Rozpozná-li editor formát souboru, zobrazí se trasa v mapě jako světle zelená čára. Pokud chcete tuto novou vrstvu zapnout, vypnout nebo zvětšit na velikost pracovní plochy, klikněte na menu 'Nastavení pozadí' na pravé straně.\n\nTrasa GPX nebude přímo nahrána na OpenStreetMap - pouze slouží jako vodítko, podle kterého se můžete orientovat, a podle kterého můžete kreslit nové objekty do mapy. Pokud chcete přímo trasu GPX poskytnout i ostatním, můžete ji [nahrát do samostatné databáze OpenStreetMap](http://www.openstreetmap.org/trace/create).⏎\n",
-        "imagery": "# Podkladové snímky\n\nSatelitní a letecké snímky jsou důležitým zdrojem mapových dat. V menu 'Nastavení pozadí' na levé straně editoru je k dispozici kombinace leteckých snímků, satelitních snímků a dalších volně dostupných podkladů.\n\nImplicitní vrstvou jsou satelitní snímky [Bing](http://www.bing.com/maps/), ale jakmile se přesunete do konkrétní geografické oblasti a nastavíte dostatečné zvětšení, nabídnou se vám nové mapové podklady. V některých státech, jako jsou Spojené státy, Francie či Dánskou, jsou k dispozici snímky ve vysoké kvalitě. Pro velkou část České republiky jsou také dostupné velmi detailní satelitní snímky (data z katastru nemovitostí zatím editor nepodporuje).\n\nPodklady jsou někdy posunuté vůči mapě, kvůli chybám na straně poskytovatele snímů. Pokud uvidíte, že je mnoho cest v mapě posunuto vůči pozadí, nesnažte se je přesunout - posun obvykle znamená chybu v podkladu a ne chybu v mapě. V menu 'Nastavení pozadí' klikněte na 'Zarovnat pozadí' - to vám dovolí posunout podklad, aby lícoval s mapou.\n",
+        "imagery": "# Podkladové snímky\n\nSatelitní a letecké snímky jsou důležitým zdrojem mapových dat. V menu 'Nastavení pozadí' na levé straně editoru je k dispozici kombinace leteckých snímků, satelitních snímků a dalších volně dostupných podkladů.\n\nImplicitní vrstvou jsou satelitní snímky [Bing](http://www.bing.com/maps/), ale jakmile se přesunete do konkrétní geografické oblasti a nastavíte dostatečné zvětšení, nabídnou se vám další mapové podklady. V některých státech, jako jsou Spojené státy, Francie či Dánskou, jsou k dispozici snímky ve vysoké kvalitě. Pro velkou část České republiky jsou také dostupné velmi detailní satelitní snímky a navíc data z katastru nemovitostí.\n\nPodklady jsou někdy posunuté vůči mapě, kvůli chybám na straně poskytovatele snímů. Pokud uvidíte, že je mnoho cest v mapě posunuto vůči pozadí, nesnažte se je hned přesunout - posun obvykle znamená chybu v podkladu a ne chybu v mapě. V menu 'Nastavení pozadí' klikněte na 'Zarovnat pozadí' - to vám dovolí posunout podklad, aby lícoval s mapou.\n",
         "addresses": "# Adresy\n\nJednou z nejužitečnějších součástí mapy jsou adresy.\n\nAdresy jsou sice někdy chápány jako označení kousku ulice, ale v OpenStreetMap jsou uloženy v budovách či objektech podél ulice. V České republice jsou adresy většinou samostatným uzlem uvnitř budovy.\n\nMůžete tedy data o adrese vkládat jak k samostatnému bodu, tak k ploše označující budovu.\nNejlepším zdrojem informací o adresách je průzkum přímo v terénu či jeho dobrá znalost - stejně jako u celého projektu OpenStreetMap je přebírání dat z komerčních zdrojů typu Google Maps přísně zakázáno.\n",
-        "inspector": "# Používání Inspektoru\n\nInspektor je prvek uživatelského rozhraní na pravé straně. Inspektor se objeví, když je vybraný nějaký objekt, a umožní vám editovat jeho vlastnosti.\n\n### Výběr typu objektu\n\nJakmile vytvoříte uzel, cestu nebo plochu, můžete zvolit typ objektu. Např. jestli jde o silnici nebo pěšinu, obchod nebo hospodu. Inspektor zobrazí tlačítka pro nejčastější typy objektů; další můžete najít prostřednictvím pole pro vyhledávání.\n\nKdyž u tlačítka typu objektu kliknete na 'i' vpravo dole, zobrazí se vám o něm více informací. Když kliknete na samotné tlačítko, vyberete příslušný typ.\n\n### Formuláře a editace vlastností\n\nPoté, co vyberete typ objektu nebo když vyberete objekt s už přiřazeným typem, v inspektoru se zobrazí pole s bližšími informacemi o objektu - jako třeba název nebo adresa.\n\nPod těmito poli jsou další ikony. Když na ně kliknete, tak můžete přidávat další detaily, jako vazbu na [Wikipedii](http://www.wikipedia.org/), přístup pro vozíčkáře atd.\n\nPokud chcete přidat k objektu ještě nějaké jiné vlastnosti, klikněte na 'Další vlastnosti' úplně dole. Jedním z informačních zdrojů pak může být [Taginfo](http://taginfo.openstreetmap.org/), kde se dozvíte o nejčastějších kombinacích tagů.\n\nZměny provedené v inspektoru jsou ihned vidět na mapě zobrazené ve vašem prohlížeči. Můžete je vrátit zpět kliknutím na tlačítko 'Undo'.\n\n### Zavření inspektoru\n\nInspektor můžete zavřít kliknutím na tlačítko vpravo nahoře, nebo stisknutím Escape, nebo kliknutím jinam na mapu.\n",
+        "inspector": "# Používání Inspektoru\n\nInspektor je prvek uživatelského rozhraní na levé straně, který umožňuje editovat vlastnosti zvoleného objektu.\n\n### Výběr typu objektu\n\nJakmile vytvoříte uzel, cestu nebo plochu, můžete zvolit typ vytvořeného objektu. Např. jestli jde o silnici nebo pěšinu, obchod nebo hospodu. Inspektor zobrazí tlačítka pro nejčastější typy objektů; další můžete najít prostřednictvím pole pro vyhledávání.\n\nKdyž u tlačítka typu objektu kliknete na 'i' vpravo dole, zobrazí se vám o něm více informací. Když kliknete na samotné tlačítko, vyberete příslušný typ.\n\n### Formuláře a editace vlastností\n\nPoté, co vyberete typ objektu nebo když vyberete objekt s už přiřazeným typem, v inspektoru se zobrazí pole s bližšími informacemi o objektu - jako třeba název nebo adresa.\n\nPod těmito poli jsou další ikony. Když na ně kliknete, tak můžete přidávat další detaily, jako vazbu na [Wikipedii](http://www.wikipedia.org/), přístup pro vozíčkáře atd.\n\nPokud chcete přidat k objektu ještě nějaké jiné vlastnosti, klikněte na 'Další vlastnosti' úplně dole. Jedním z informačních zdrojů pak může být [Taginfo](http://taginfo.openstreetmap.org/), kde se dozvíte o nejčastějších kombinacích tagů.\n\nZměny provedené v inspektoru jsou ihned vidět na mapě zobrazené ve vašem prohlížeči. Můžete je vrátit zpět kliknutím na tlačítko 'Undo'.\n",
         "buildings": "# Budovy\n\nOpenStreetMap je největší databází budov na světě. Můžete tuto databázi rozšiřovat a vylepšovat.\n\n### Výběr\n\nBudovu označíte kliknutím na její hranici. Budova se v editoru rozsvítí, otevře se malá nabídka nástrojů a boční panel s informacemi o budově.\n\n### Úpravy\n\nBudovy někdy mohou mít špatnou polohu, tvar nebo nesprávné vlastnosti.\n\nPokud chcete posunout celou budovu, označte ji a kliněte na ikonu posunu - pak můžete pohnout budovou myší. Posun ukončíte kliknutím.\n\nKdyž má budova špatný tvar, klikněte na uzel na hranici budovy a posuňte ho na správné místo.\n\n### Vytváření\n\nMohou být budovy v mapě zaznamenané jako plochy, nebo jako samostatné uzly? Pravidlo je takové, že _pokud je to možné, budovy by se měly mapovat jako plochy_, a firmy, podniky, zařízení a další subjekty působící v budově by se měly mapovat jako uzly uvnitř budovy. V České republice se jako uzly uvnitř budovy obvykle mapují i adresy.\n\nChcete-li nakreslit novou budovu, klikněte na tlačítko 'Plocha' vlevo nahoře a klikáním nakreslete obrys budovy. Kreslení ukončíte buď kliknutím na první nakreslený uzel nebo stisknutím klávesy 'Enter' nebo 'Return'.\n\n### Smazání\n\nBudovy lze také mazat - ale dělejte to pouze v případě, že jste si opravdu jistí, že budova ve skutečnosti neexistuje. Satelitní snímky nejsou dostatečným důkazem, protože mohou být zastaralé nebo zavádějící. Buďte opatrní - když budovu smažete, budova zmizí z mapy pro všechny její uživatele.\n\nBudovu smažete tak, že ji označíte kliknutím a potom buď kliknete na ikonu odpadkového koše, nebo stisknete klávesu 'Delete'.\n",
         "relations": "# Relace\n\nRelace je speciálním typem objektu OpenStreetMap, který seskupuje dohromady jiné objekty.\nDvěma nejčastějšími příklady relací jsou *relace trasy*, které obsahují seznam částí cest, po kterých vede nějaká trasa, a *multipolygony*, které obsahují seznam jednoduchých ploch tvořících dohromady složitější plochu (např. plochu z několika částí nebo s dírami uvnitř).\n\nObjekty seznamu v relaci se nazývají *prvky*. V bočním panelu jsou vidět relace, kterých je zvolený objekt prvkem, a relaci pak můžete kliknutím zvolit. Po zvolení relace jsou všechny její prvky jednak uvedené v bočním panelu a také označené na mapě.\n\nVe většině případů iD dokáže relace udržovat při editacích automaticky. Měli byste si být vědomi jistých omezení: třeba když smažete kus cesty a potom ji nakreslíte znovu, je třeba zkontrolovat, že nový kus cesty je prvkem stejných relací jako původní kus.\n\n## Editace relací\n\nPři editaci relací se držte následujících principů.\n\nNový prvek do relace přidáte tak, že zvolíte daný objekt, kliknete na tlačítko \"+\" v bočním panelu v sekci \"Všechny relace\", a zvolíte nebo napíšete jméno relace.\n\nPodobně novou relaci založíte tak, že zvolíte objekt, který by se měl stát prvním prvkem relace, kliknete na tlačítko \"+\" v sekci \"Všechny relace\" a zvolíte \"Nová relace...\".\n\nPrvek z relace vyjmete tím způsobem, že zvolíte daný objekt a kliknete na tlačítko odpadkového koše vedle relace, ze které objekt chcete vyjmout.\n\nMultipolygony s dírami můžete vytvořit pomocí nástroje \"Spojit\". Nakreslete dvě plochy (vnitřní a vnější), stiskněte klávesu Shift a klikněte postupně na obě plochy, čímž je označíte. Multipolygon pak vytvoříte kliknutím na tlačítko \"Spojit\" (+).\n"
     },
                 "terms": "dům"
             },
             "building/hut": {
-                "name": "Chata",
-                "terms": "chatka,dřevěnice"
+                "name": "Chatička",
+                "terms": "chatička,chatka,chata,bouda,dřevěnice,kůlna,dřevník"
             },
             "building/industrial": {
                 "name": "Průmyslová budova",
                 "terms": "obytná budova,ubytování,bývání,byt"
             },
             "emergency/ambulance_station": {
-                "name": "Zdravotní pohotovost"
+                "name": "Stanice záchranné služby",
+                "terms": "ambulance,pohotovost,zdravotní pohotovost,pohotovostní stanice,záchranná služba,služba"
             },
             "emergency/fire_hydrant": {
                 "name": "Požární hydrant",
                 "name": "Volný čas",
                 "terms": "oddech,volno,volná chvíle,odpočinek,volný čas"
             },
+            "leisure/common": {
+                "name": "Volně přístupný prostor",
+                "terms": "volně přístupný prostor,volně přístupné,veřejně přístupné"
+            },
             "leisure/dog_park": {
                 "name": "Psí park",
                 "terms": "park pro psy,psí park"
                 "name": "Maják",
                 "terms": "maják,světlo"
             },
+            "man_made/observation": {
+                "name": "Rozhledna",
+                "terms": "rozhledna,pozorovatelna,věž"
+            },
             "man_made/pier": {
                 "name": "Molo",
                 "terms": "molo,sloupy,pilíř,vlnolam,hráz,kotva,kotvení,ukotvení,lodě,promenáda,lávka,promenáda a přístaviště,přístavní hráz"
                 "terms": "kancelář,kancelářský,úřad,úřadovna,administrativa,office,sídlo"
             },
             "place": {
-                "name": "Místo"
+                "name": "Místo",
+                "terms": "obec,místo,lokace,město,vesnice"
             },
             "place/city": {
-                "name": "Velkoměsto"
+                "name": "Velkoměsto",
+                "terms": "velkoměsto,město,city"
             },
             "place/hamlet": {
-                "name": "Vesnička"
+                "name": "Vesnička",
+                "terms": "vesnička,vesnice,obec,lhota"
             },
             "place/island": {
                 "name": "Ostrov",
                 "terms": "ostrov,ostrůvek,souostroví,archipel,atol,útes"
             },
             "place/isolated_dwelling": {
-                "name": "Samota"
+                "name": "Samota",
+                "terms": "samota,vesnička,obec"
             },
             "place/locality": {
-                "name": "Neobydlené místo"
+                "name": "Neobydlené místo",
+                "terms": "neobydlené místo,místo,lokalita"
             },
             "place/town": {
-                "name": "Město"
+                "name": "Město",
+                "terms": "město,městys,městečko,velkoměsto,obec"
             },
             "place/village": {
                 "name": "Vesnice",
                 "terms": "vesnice"
             },
             "point": {
-                "name": "Uzel"
+                "name": "Uzel",
+                "terms": "uzel,bod,vrchol,tečka,puntík"
             },
             "power": {
                 "name": "Energetika",
                 "terms": "sloup vysokého napětí,vysoké napětí"
             },
             "power/transformer": {
-                "name": "Transformátor"
+                "name": "Transformátor",
+                "terms": "transformátor,transformátorová stanice,elektrická stanice,adaptér"
             },
             "railway": {
                 "name": "Železnice",
                 "terms": "železnice, železniční dráha"
             },
             "railway/abandoned": {
-                "name": "Opuštěná železnice"
+                "name": "Opuštěná železnice",
+                "terms": "opuštěná železnice,opuštěná trať,nepoužívaná"
             },
             "railway/disused": {
                 "name": "Nepoužívaná železnice",
                 "terms": "přejezd,železniční přejezd,přejezd přes koleje,přejezd přes železnici,přejezd přes vlak,vlakový přejezd"
             },
             "railway/monorail": {
-                "name": "Jednokolejka"
+                "name": "Jednokolejka",
+                "terms": "jednokolejka,monorail,jednokolejná trať"
             },
             "railway/platform": {
                 "name": "Nástupiště",
                 "terms": "železniční nástupiště, nástupiště"
             },
             "railway/rail": {
-                "name": "Kolej"
+                "name": "Kolej",
+                "terms": "koleje,železnice,vlak,trať"
             },
             "railway/station": {
-                "name": "Nádraží"
+                "name": "Nádraží",
+                "terms": "stanice,železniční stanice,zastávka,železniční zastávka,nádraží,vlak"
             },
             "railway/subway": {
                 "name": "Metro",
                 "terms": "metro"
             },
             "railway/subway_entrance": {
-                "name": "Vstup do metra"
+                "name": "Vstup do metra",
+                "terms": "vstup do metra,vchod do metra,vlez do metra,vestibul,metro"
             },
             "railway/tram": {
                 "name": "Tramvaj",
                 "terms": "tramvaj,tranvaj,šalina,šmirgl,tramvajka,elektrika,električka,tram"
             },
             "relation": {
-                "name": "Relace"
+                "name": "Relace",
+                "terms": "relace,vztah,seznam,objekt"
             },
             "route/ferry": {
-                "name": "Trasa trajektu"
+                "name": "Trasa trajektu",
+                "terms": "trajekt,trasa,linka,loď,trasa trajektu"
             },
             "shop": {
-                "name": "Obchod"
+                "name": "Obchod",
+                "terms": "obchod,prodej,nákup,stánek,market,obchodní,nákupní"
             },
             "shop/alcohol": {
                 "name": "Prodejna alkoholu",
                 "terms": "Pekařství"
             },
             "shop/beauty": {
-                "name": "Kosmetický salón"
+                "name": "Kosmetický salón",
+                "terms": "kosmetický salón,kadeřnictví,vizážista,kosmetika,salón krásy,nehty,kosmetika,depilace"
             },
             "shop/beverages": {
-                "name": "Prodejna nápojů"
+                "name": "Prodejna nápojů",
+                "terms": "prodejna nápojů,obchod s nápoji,nápoje,pití,malinovka,kofola,občerstvení,nealkoholické nápoje"
             },
             "shop/bicycle": {
-                "name": "Cykloprodejna"
+                "name": "Cykloprodejna",
+                "terms": "obchod s koly,kola,horská kola,jízdní kola,cyklistika,cykloprodejna"
             },
             "shop/books": {
                 "name": "Knihkupectví",
                 "terms": "Knihovnictví"
             },
             "shop/boutique": {
-                "name": "Módní butik"
+                "name": "Módní butik",
+                "terms": "oblečení,šaty,oděv,oděvy,butik,móda,módní"
             },
             "shop/butcher": {
                 "name": "Řeznictví",
                 "terms": "Řezník"
             },
             "shop/car": {
-                "name": "Prodejna aut"
+                "name": "Prodejna aut",
+                "terms": "prodejna aut,autosalón,autobazar"
             },
             "shop/car_parts": {
-                "name": "Náhradní díly pro auta"
+                "name": "Náhradní díly pro auta",
+                "terms": "prodejna autodílů,autodíly,automobilový,auto"
             },
             "shop/car_repair": {
-                "name": "Autoopravna"
+                "name": "Autoopravna",
+                "terms": "opravna aut,autoservis,servis,pneuservis,opravna"
             },
             "shop/chemist": {
-                "name": "Drogérie"
+                "name": "Drogérie",
+                "terms": "drogérie,parfumérie,kosmetika,hygiena,čisticí prostředky"
             },
             "shop/clothes": {
-                "name": "Oblečení"
+                "name": "Oblečení",
+                "terms": "oděvy,oděv,šaty,oblečení,obchod s oblečením,móda,módní"
             },
             "shop/computer": {
-                "name": "Počítače"
+                "name": "Počítače",
+                "terms": "obchod s výpočetní technikou,počítače,elektro,elektronika,výpočetní technika"
             },
             "shop/confectionery": {
-                "name": "Cukrovinky"
+                "name": "Cukrovinky",
+                "terms": "cukrárna,cukrovinky,cukrářství,cukrářské zboží,sladkosti,cukroví"
             },
             "shop/convenience": {
-                "name": "Smíšené zboží"
+                "name": "Smíšené zboží",
+                "terms": "smíšené zboží,krám,obchod,potraviny,večerka"
             },
             "shop/deli": {
-                "name": "Lahůdkářství"
+                "name": "Lahůdkářství",
+                "terms": "lahůdky,lahůdkářství,delikatesy,delikatesa,deli"
             },
             "shop/department_store": {
-                "name": "Obchodní dům"
+                "name": "Obchodní dům",
+                "terms": "obchodní dům,nákupní středisko,obchodní středisko,nákupní centrum"
             },
             "shop/doityourself": {
-                "name": "Obchod pro kutily"
+                "name": "Obchod pro kutily",
+                "terms": "obchod pro kutily,stavební materiál,stavebniny,staviva,potřeby pro kutily,zahradní potřeby,železářství,kutil"
             },
             "shop/dry_cleaning": {
-                "name": "Čistírna"
+                "name": "Čistírna",
+                "terms": "čistírna,chemické čištění,čištění oděvů za sucha"
             },
             "shop/electronics": {
                 "name": "Elektro",
                 "terms": "stánek,ovoce,zelenina,trh,tržiště,farmářský trh,farmářské tržiště,farma"
             },
             "shop/fishmonger": {
-                "name": "Rybárna"
+                "name": "Rybárna",
+                "terms": "prodej ryb,prodavač ryb,ryby,obchodník s rybami,obchod s rybami,rybárna,mořské plody,plody moře"
             },
             "shop/florist": {
-                "name": "Květinářství"
+                "name": "Květinářství",
+                "terms": "květinář,květinářství,květy,květiny,kytice"
             },
             "shop/furniture": {
-                "name": "Nábytek"
+                "name": "Nábytek",
+                "terms": "obchod s nábytkem,nábytek,domácnost"
             },
             "shop/garden_centre": {
-                "name": "Zahradnictví"
+                "name": "Zahradnictví",
+                "terms": "zahradnictví,zahradní centrum,zahradnické středisko,zahradnické centrum"
             },
             "shop/gift": {
-                "name": "Dárky, suvenýry"
+                "name": "Dárky, suvenýry",
+                "terms": "obchod s dárky,suvenýry"
             },
             "shop/greengrocer": {
-                "name": "Ovoce a zelenina"
+                "name": "Ovoce a zelenina",
+                "terms": "zelinář,zelinářství,prodejna zeleniny,zelenina,ovoce,ovoce a zelenina"
             },
             "shop/hairdresser": {
-                "name": "Kadeřnictví"
+                "name": "Kadeřnictví",
+                "terms": "kadeřník,holič,vizážista,kadeřnictví"
             },
             "shop/hardware": {
                 "name": "Železářství",
                 "terms": "Železářství"
             },