]> git.openstreetmap.org Git - rails.git/blobdiff - vendor/assets/iD/iD.js
Update to iD v1.5.4
[rails.git] / vendor / assets / iD / iD.js
index 85e8adcef4ae0f92b485638c68ded08a622f5779..11c3eb29ba1371f42429a41988249deac01098f3 100644 (file)
@@ -6100,8 +6100,12 @@ d3.combobox = function() {
                         // on mousedown
                         d3.event.stopPropagation();
                         d3.event.preventDefault();
-                        input.node().focus();
-                        fetch('', render);
+                        if (!shown) {
+                            input.node().focus();
+                            fetch('', render);
+                        } else {
+                            hide();
+                        }
                     });
             });
 
@@ -16407,7 +16411,7 @@ window.iD = function () {
     return d3.rebind(context, dispatch, 'on');
 };
 
-iD.version = '1.5.2';
+iD.version = '1.5.4';
 
 (function() {
     var detected = {};
@@ -21716,7 +21720,7 @@ iD.areaKeys = {
         var elems = obj.getElementsByTagName(ndStr),
             nodes = new Array(elems.length);
         for (var i = 0, l = elems.length; i < l; i++) {
-            nodes[i] = 'n' + elems[i].attributes.ref.nodeValue;
+            nodes[i] = 'n' + elems[i].attributes.ref.value;
         }
         return nodes;
     }
@@ -21726,7 +21730,7 @@ iD.areaKeys = {
             tags = {};
         for (var i = 0, l = elems.length; i < l; i++) {
             var attrs = elems[i].attributes;
-            tags[attrs.k.nodeValue] = attrs.v.nodeValue;
+            tags[attrs.k.value] = attrs.v.value;
         }
         return tags;
     }
@@ -21737,9 +21741,9 @@ iD.areaKeys = {
         for (var i = 0, l = elems.length; i < l; i++) {
             var attrs = elems[i].attributes;
             members[i] = {
-                id: attrs.type.nodeValue[0] + attrs.ref.nodeValue,
-                type: attrs.type.nodeValue,
-                role: attrs.role.nodeValue
+                id: attrs.type.value[0] + attrs.ref.value,
+                type: attrs.type.value,
+                role: attrs.role.value
             };
         }
         return members;
@@ -21749,10 +21753,10 @@ iD.areaKeys = {
         node: function nodeData(obj) {
             var attrs = obj.attributes;
             return new iD.Node({
-                id: iD.Entity.id.fromOSM(nodeStr, attrs.id.nodeValue),
-                loc: [parseFloat(attrs.lon.nodeValue), parseFloat(attrs.lat.nodeValue)],
-                version: attrs.version.nodeValue,
-                user: attrs.user && attrs.user.nodeValue,
+                id: iD.Entity.id.fromOSM(nodeStr, attrs.id.value),
+                loc: [parseFloat(attrs.lon.value), parseFloat(attrs.lat.value)],
+                version: attrs.version.value,
+                user: attrs.user && attrs.user.value,
                 tags: getTags(obj)
             });
         },
@@ -21760,9 +21764,9 @@ iD.areaKeys = {
         way: function wayData(obj) {
             var attrs = obj.attributes;
             return new iD.Way({
-                id: iD.Entity.id.fromOSM(wayStr, attrs.id.nodeValue),
-                version: attrs.version.nodeValue,
-                user: attrs.user && attrs.user.nodeValue,
+                id: iD.Entity.id.fromOSM(wayStr, attrs.id.value),
+                version: attrs.version.value,
+                user: attrs.user && attrs.user.value,
                 tags: getTags(obj),
                 nodes: getNodes(obj)
             });
@@ -21771,9 +21775,9 @@ iD.areaKeys = {
         relation: function relationData(obj) {
             var attrs = obj.attributes;
             return new iD.Relation({
-                id: iD.Entity.id.fromOSM(relationStr, attrs.id.nodeValue),
-                version: attrs.version.nodeValue,
-                user: attrs.user && attrs.user.nodeValue,
+                id: iD.Entity.id.fromOSM(relationStr, attrs.id.value),
+                version: attrs.version.value,
+                user: attrs.user && attrs.user.value,
                 tags: getTags(obj),
                 members: getMembers(obj)
             });
@@ -21907,9 +21911,9 @@ iD.areaKeys = {
             }
 
             userDetails = {
-                display_name: u.attributes.display_name.nodeValue,
+                display_name: u.attributes.display_name.value,
                 image_url: image_url,
-                id: u.attributes.id.nodeValue
+                id: u.attributes.id.value
             };
 
             callback(undefined, userDetails);
@@ -23784,8 +23788,15 @@ iD.Background = function(context) {
 
     background.zoomToGpxLayer = function() {
         if (background.hasGpxLayer()) {
-            context.map()
-                .extent(d3.geo.bounds(gpxLayer.geojson()));
+            var viewport = context.map().extent().polygon(),
+                coords = _.reduce(gpxLayer.geojson().features, function(coords, feature) {
+                    var c = feature.geometry.coordinates;
+                    return _.union(coords, feature.geometry.type === 'Point' ? [c] : c);
+                }, []);
+
+            if (!iD.geo.polygonIntersectsPolygon(viewport, coords)) {
+                context.map().extent(d3.geo.bounds(gpxLayer.geojson()));
+            }
         }
     };
 
@@ -24594,6 +24605,7 @@ iD.TileLayer = function() {
             tile().forEach(function(d) {
                 addSource(d);
                 if (d[3] === '') return;
+                if (typeof d[3] !== 'string') return; // Workaround for chrome crash https://github.com/openstreetmap/iD/issues/2295
                 requests.push(d);
                 if (cache[d[3]] === false && lookUp(d)) {
                     requests.push(addSource(lookUp(d)));
@@ -24817,6 +24829,12 @@ iD.svg.Areas = function(projection) {
 
     var patternKeys = ['landuse', 'natural', 'amenity'];
 
+    var clipped = ['residential', 'commercial', 'retail', 'industrial'];
+
+    function clip(entity) {
+        return clipped.indexOf(entity.tags.landuse) !== -1;
+    }
+
     function setPattern(d) {
         for (var i = 0; i < patternKeys.length; i++) {
             if (patterns.hasOwnProperty(d.tags[patternKeys[i]])) {
@@ -24859,11 +24877,28 @@ iD.svg.Areas = function(projection) {
         });
 
         var data = {
+            clip: areas.filter(clip),
             shadow: strokes,
             stroke: strokes,
             fill: areas
         };
 
+        var clipPaths = surface.selectAll('defs').selectAll('.clipPath')
+           .filter(filter)
+           .data(data.clip, iD.Entity.key);
+
+        clipPaths.enter()
+           .append('clipPath')
+           .attr('class', 'clipPath')
+           .attr('id', function(entity) { return entity.id + '-clippath'; })
+           .append('path');
+
+        clipPaths.selectAll('path')
+           .attr('d', path);
+
+        clipPaths.exit()
+           .remove();
+
         var areagroup = surface
             .select('.layer-areas')
             .selectAll('g.areagroup')
@@ -24902,6 +24937,10 @@ iD.svg.Areas = function(projection) {
 
                 this.setAttribute('class', entity.type + ' area ' + layer + ' ' + entity.id);
 
+                if (layer === 'fill' && clip(entity)) {
+                    this.setAttribute('clip-path', 'url(#' + entity.id + '-clippath)');
+                }
+
                 if (layer === 'fill') {
                     setPattern.apply(this, arguments);
                 }
@@ -25679,23 +25718,33 @@ iD.svg.Midpoints = function(projection, context) {
             .filter(midpointFilter)
             .data(_.values(midpoints), function(d) { return d.id; });
 
-        var group = groups.enter()
+        var enter = groups.enter()
             .insert('g', ':first-child')
             .attr('class', 'midpoint');
 
-        group.append('circle')
-            .attr('r', 7)
+        enter.append('polygon')
+            .attr('points', '-6,8 10,0 -6,-8')
             .attr('class', 'shadow');
 
-        group.append('circle')
-            .attr('r', 3)
+        enter.append('polygon')
+            .attr('points', '-3,4 5,0 -3,-4')
             .attr('class', 'fill');
 
-        groups.attr('transform', iD.svg.PointTransform(projection));
+        groups
+            .attr('transform', function(d) {
+                var translate = iD.svg.PointTransform(projection),
+                    a = context.entity(d.edge[0]),
+                    b = context.entity(d.edge[1]),
+                    angle = Math.round(iD.geo.angle(a, b, projection) * (180 / Math.PI));
+                return translate(d) + ' rotate(' + angle + ')';
+            })
+            .call(iD.svg.TagClasses().tags(
+                function(d) { return d.parents[0].tags; }
+            ));
 
         // Propagate data bindings.
-        groups.select('circle.shadow');
-        groups.select('circle.fill');
+        groups.select('polygon.shadow');
+        groups.select('polygon.fill');
 
         groups.exit()
             .remove();
@@ -25772,6 +25821,11 @@ iD.svg.Points = function(projection, context) {
 };
 iD.svg.Surface = function() {
     return function (selection) {
+        selection.selectAll('defs')
+            .data([0])
+            .enter()
+            .append('defs');
+
         var layers = selection.selectAll('.layer')
             .data(['areas', 'lines', 'hit', 'halo', 'label']);
 
@@ -29626,7 +29680,7 @@ iD.ui.Save = function(context) {
 };
 iD.ui.Scale = function(context) {
     var projection = context.projection,
-        imperial = (iD.detect().locale === 'en-us'),
+        imperial = (iD.detect().locale.toLowerCase() === 'en-us'),
         maxLength = 180,
         tickHeight = 8;
 
@@ -30841,6 +30895,9 @@ iD.ui.preset.defaultcheck = function(field) {
 iD.ui.preset.combo =
 iD.ui.preset.typeCombo = function(field) {
     var event = d3.dispatch('change'),
+        optstrings = field.strings && field.strings.options,
+        optarray = field.options,
+        strings = {},
         input;
 
     function combo(selection) {
@@ -30849,44 +30906,66 @@ iD.ui.preset.typeCombo = function(field) {
         input = selection.selectAll('input')
             .data([0]);
 
-        input.enter().append('input')
+        var enter = input.enter()
+            .append('input')
             .attr('type', 'text')
             .attr('id', 'preset-input-' + field.id);
 
+        if (optstrings) { enter.attr('readonly', 'readonly'); }
+
         input
             .call(combobox)
             .on('change', change)
             .on('blur', change)
             .each(function() {
-                if (field.options) {
-                    options(field.options);
+                if (optstrings) {
+                    _.each(optstrings, function(v, k) {
+                        strings[k] = field.t('options.' + k, { 'default': v });
+                    });
+                    stringsLoaded();
+                } else if (optarray) {
+                    _.each(optarray, function(k) {
+                        strings[k] = k.replace(/_+/g, ' ');
+                    });
+                    stringsLoaded();
                 } else {
-                    iD.taginfo().values({
-                        key: field.key
-                    }, function(err, data) {
-                        if (!err) options(_.pluck(data, 'value'));
+                    iD.taginfo().values({key: field.key}, function(err, data) {
+                        if (!err) {
+                            _.each(_.pluck(data, 'value'), function(k) {
+                                strings[k] = k.replace(/_+/g, ' ');
+                            });
+                            stringsLoaded();
+                        }
                     });
                 }
             });
 
-        function options(opts) {
-            combobox.data(opts.map(function(d) {
-                var o = {};
-                o.title = o.value = d.replace(/_+/g, ' ');
+        function stringsLoaded() {
+            var keys = _.keys(strings),
+                strs = [],
+                placeholders;
+
+            combobox.data(keys.map(function(k) {
+                var s = strings[k],
+                    o = {};
+                o.title = o.value = s;
+                if (s.length < 20) { strs.push(s); }
                 return o;
             }));
 
+            placeholders = strs.length > 1 ? strs : keys;
             input.attr('placeholder', field.placeholder() ||
-                (opts.length < 3 ? '' : opts.slice(0, 3).join(', ') + '...'));
+                (placeholders.slice(0, 3).join(', ') + '...'));
         }
     }
 
     function change() {
-        var value = input.value()
-            .split(';')
-            .map(function(s) { return s.trim(); })
-            .join(';')
-            .replace(/\s+/g, '_');
+        var optstring = _.find(_.keys(strings), function(k) { return strings[k] === input.value(); }),
+            value = optstring || (input.value()
+                .split(';')
+                .map(function(s) { return s.trim(); })
+                .join(';')
+                .replace(/\s+/g, '_'));
 
         if (field.type === 'typeCombo' && !value) value = 'yes';
 
@@ -30896,8 +30975,9 @@ iD.ui.preset.typeCombo = function(field) {
     }
 
     combo.tags = function(tags) {
-        var value = tags[field.key] || '';
-        if (field.type === 'typeCombo' && value === 'yes') value = '';
+        var key = tags[field.key],
+            value = strings[key] || key || '';
+        if (field.type === 'typeCombo' && value.toLowerCase() === 'yes') value = '';
         input.value(value);
     };
 
@@ -64495,6 +64575,19 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                 ],
                 "name": "Boat Rental"
             },
+            "amenity/bus_station": {
+                "geometry": [
+                    "point",
+                    "area"
+                ],
+                "tags": {
+                    "amenity": "bus_station"
+                },
+                "fields": [
+                    "operator"
+                ],
+                "name": "Bus Station"
+            },
             "amenity/cafe": {
                 "icon": "cafe",
                 "fields": [
@@ -67926,9 +68019,12 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "width",
                     "structure",
                     "access",
-                    "sac_scale",
                     "incline",
+                    "sac_scale",
                     "trail_visibility",
+                    "mtb/scale",
+                    "mtb/scale/uphill",
+                    "mtb/scale/imba",
                     "ref"
                 ],
                 "geometry": [
@@ -68311,12 +68407,16 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "highway/track": {
                 "icon": "highway-track",
                 "fields": [
-                    "tracktype",
-                    "oneway",
-                    "maxspeed",
+                    "surface",
+                    "width",
                     "structure",
                     "access",
-                    "surface"
+                    "incline",
+                    "tracktype",
+                    "smoothness",
+                    "mtb/scale",
+                    "mtb/scale/uphill",
+                    "mtb/scale/imba"
                 ],
                 "geometry": [
                     "line"
@@ -101416,12 +101516,14 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "aerialway/access": {
                 "key": "aerialway:access",
                 "type": "combo",
-                "options": [
-                    "entry",
-                    "exit",
-                    "both"
-                ],
-                "label": "Access"
+                "label": "Access",
+                "strings": {
+                    "options": {
+                        "entry": "Entry",
+                        "exit": "Exit",
+                        "both": "Both"
+                    }
+                }
             },
             "aerialway/bubble": {
                 "key": "aerialway:bubble",
@@ -101454,12 +101556,14 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "aerialway/summer/access": {
                 "key": "aerialway:summer:access",
                 "type": "combo",
-                "options": [
-                    "entry",
-                    "exit",
-                    "both"
-                ],
-                "label": "Access (summer)"
+                "label": "Access (summer)",
+                "strings": {
+                    "options": {
+                        "entry": "Entry",
+                        "exit": "Exit",
+                        "both": "Both"
+                    }
+                }
             },
             "aeroway": {
                 "key": "aeroway",
@@ -101527,32 +101631,31 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "cardinal_direction": {
                 "key": "direction",
                 "type": "combo",
-                "options": [
-                    "N",
-                    "E",
-                    "S",
-                    "W",
-                    "NE",
-                    "SE",
-                    "SW",
-                    "NNE",
-                    "ENE",
-                    "ESE",
-                    "SSE",
-                    "SSW",
-                    "WSW",
-                    "WNW",
-                    "NNW"
-                ],
-                "label": "Direction"
+                "label": "Direction",
+                "strings": {
+                    "options": {
+                        "N": "North",
+                        "E": "East",
+                        "S": "South",
+                        "W": "West",
+                        "NE": "Northeast",
+                        "SE": "Southeast",
+                        "SW": "Southwest",
+                        "NW": "Northwest",
+                        "NNE": "North-northeast",
+                        "ENE": "East-northeast",
+                        "ESE": "East-southeast",
+                        "SSE": "South-southeast",
+                        "SSW": "South-southwest",
+                        "WSW": "West-southwest",
+                        "WNW": "West-northwest",
+                        "NNW": "North-northwest"
+                    }
+                }
             },
             "clock_direction": {
                 "key": "direction",
                 "type": "combo",
-                "options": [
-                    "clockwise",
-                    "anticlockwise"
-                ],
                 "label": "Direction",
                 "strings": {
                     "options": {
@@ -101594,7 +101697,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "cuisine": {
                 "key": "cuisine",
                 "type": "combo",
-                "indexed": true,
                 "label": "Cuisine"
             },
             "denomination": {
@@ -101616,12 +101718,15 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                 "key": "electrified",
                 "type": "combo",
                 "label": "Electrification",
-                "options": [
-                    "contact_line",
-                    "rail",
-                    "yes",
-                    "no"
-                ]
+                "placeholder": "Contact Line, Electrified Rail...",
+                "strings": {
+                    "options": {
+                        "contact_line": "Contact Line",
+                        "rail": "Electrified Rail",
+                        "yes": "Yes (unspecified)",
+                        "no": "No"
+                    }
+                }
             },
             "elevation": {
                 "key": "ele",
@@ -101659,13 +101764,15 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "fire_hydrant/type": {
                 "key": "fire_hydrant:type",
                 "type": "combo",
-                "options": [
-                    "pillar",
-                    "pond",
-                    "underground",
-                    "wall"
-                ],
-                "label": "Type"
+                "label": "Type",
+                "strings": {
+                    "options": {
+                        "pillar": "Pillar/Aboveground",
+                        "underground": "Underground",
+                        "wall": "Wall",
+                        "pond": "Pond"
+                    }
+                }
             },
             "fixme": {
                 "key": "fixme",
@@ -101793,13 +101900,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "internet_access": {
                 "key": "internet_access",
                 "type": "combo",
-                "options": [
-                    "yes",
-                    "no",
-                    "wlan",
-                    "wired",
-                    "terminal"
-                ],
                 "label": "Internet Access",
                 "strings": {
                     "options": {
@@ -101869,6 +101969,54 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                 "label": "Speed Limit",
                 "placeholder": "40, 50, 60..."
             },
+            "mtb/scale": {
+                "key": "mtb:scale",
+                "type": "combo",
+                "label": "Mountain Biking Difficulty",
+                "placeholder": "0, 1, 2, 3...",
+                "strings": {
+                    "options": {
+                        "0": "0: Solid gravel/packed earth, no obstacles, wide curves",
+                        "1": "1: Some loose surface, small obstacles, wide curves",
+                        "2": "2: Much loose surface, large obstacles, easy hairpins",
+                        "3": "3: Slippery surface, large obstacles, tight hairpins",
+                        "4": "4: Loose surface or boulders, dangerous hairpins",
+                        "5": "5: Maximum difficulty, boulder fields, landslides",
+                        "6": "6: Not rideable except by the very best mountain bikers"
+                    }
+                }
+            },
+            "mtb/scale/imba": {
+                "key": "mtb:scale:imba",
+                "type": "combo",
+                "label": "IMBA Trail Difficulty",
+                "placeholder": "Easy, Medium, Difficult...",
+                "strings": {
+                    "options": {
+                        "0": "Easiest (white circle)",
+                        "1": "Easy (green circle)",
+                        "2": "Medium (blue square)",
+                        "3": "Difficult (black diamond)",
+                        "4": "Extremely Difficult (double black diamond)"
+                    }
+                }
+            },
+            "mtb/scale/uphill": {
+                "key": "mtb:scale:uphill",
+                "type": "combo",
+                "label": "Mountain Biking Uphill Difficulty",
+                "placeholder": "0, 1, 2, 3...",
+                "strings": {
+                    "options": {
+                        "0": "0: Avg. incline <10%, gravel/packed earth, no obstacles",
+                        "1": "1: Avg. incline <15%, gravel/packed earth, few small objects",
+                        "2": "2: Avg. incline <20%, stable surface, fistsize rocks/roots",
+                        "3": "3: Avg. incline <25%, variable surface, fistsize rocks/branches",
+                        "4": "4: Avg. incline <30%, poor condition, big rocks/branches",
+                        "5": "5: Very steep, bike generally needs to be pushed or carried"
+                    }
+                }
+            },
             "name": {
                 "key": "name",
                 "type": "localized",
@@ -101945,16 +102093,18 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "parking": {
                 "key": "parking",
                 "type": "combo",
-                "options": [
-                    "surface",
-                    "multi-storey",
-                    "underground",
-                    "sheds",
-                    "carports",
-                    "garage_boxes",
-                    "lane"
-                ],
-                "label": "Type"
+                "label": "Type",
+                "strings": {
+                    "options": {
+                        "surface": "Surface",
+                        "multi-storey": "Multilevel",
+                        "underground": "Underground",
+                        "sheds": "Sheds",
+                        "carports": "Carports",
+                        "garage_boxes": "Garage Boxes",
+                        "lane": "Roadside Lane"
+                    }
+                }
             },
             "phone": {
                 "key": "phone",
@@ -101967,17 +102117,52 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "piste/difficulty": {
                 "key": "piste:difficulty",
                 "type": "combo",
-                "label": "Difficulty"
+                "label": "Difficulty",
+                "placeholder": "Easy, Intermediate, Advanced...",
+                "strings": {
+                    "options": {
+                        "novice": "Novice (instructional)",
+                        "easy": "Easy (green circle)",
+                        "intermediate": "Intermediate (blue square)",
+                        "advanced": "Advanced (black diamond)",
+                        "expert": "Expert (double black diamond)",
+                        "freeride": "Freeride (off-piste)",
+                        "extreme": "Extreme (climbing equipment required)"
+                    }
+                }
             },
             "piste/grooming": {
                 "key": "piste:grooming",
                 "type": "combo",
-                "label": "Grooming"
+                "label": "Grooming",
+                "strings": {
+                    "options": {
+                        "classic": "Classic",
+                        "mogul": "Mogul",
+                        "backcountry": "Backcountry",
+                        "classic+skating": "Classic and Skating",
+                        "scooter": "Scooter/Snowmobile",
+                        "skating": "Skating"
+                    }
+                }
             },
             "piste/type": {
                 "key": "piste:type",
                 "type": "typeCombo",
-                "label": "Type"
+                "label": "Type",
+                "strings": {
+                    "options": {
+                        "downhill": "Downhill",
+                        "nordic": "Nordic",
+                        "skitour": "Skitour",
+                        "sled": "Sled",
+                        "hike": "Hike",
+                        "sleigh": "Sleigh",
+                        "ice_skate": "Ice Skate",
+                        "snow_park": "Snow Park",
+                        "playground": "Playground"
+                    }
+                }
             },
             "place": {
                 "key": "place",
@@ -102032,27 +102217,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "religion": {
                 "key": "religion",
                 "type": "combo",
-                "options": [
-                    "christian",
-                    "muslim",
-                    "buddhist",
-                    "jewish",
-                    "hindu",
-                    "shinto",
-                    "taoist"
-                ],
-                "label": "Religion",
-                "strings": {
-                    "options": {
-                        "christian": "Christian",
-                        "muslim": "Muslim",
-                        "buddhist": "Buddhist",
-                        "jewish": "Jewish",
-                        "hindu": "Hindu",
-                        "shinto": "Shinto",
-                        "taoist": "Taoist"
-                    }
-                }
+                "label": "Religion"
             },
             "restriction": {
                 "key": "restriction",
@@ -102081,7 +102246,18 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "sac_scale": {
                 "key": "sac_scale",
                 "type": "combo",
-                "label": "Path Difficulty"
+                "label": "Hiking Difficulty",
+                "placeholder": "Mountain Hiking, Alpine Hiking...",
+                "strings": {
+                    "options": {
+                        "hiking": "T1: Hiking",
+                        "mountain_hiking": "T2: Mountain Hiking",
+                        "demanding_mountain_hiking": "T3: Demanding Mountain Hiking",
+                        "alpine_hiking": "T4: Alpine Hiking",
+                        "demanding_alpine_hiking": "T5: Demanding Alpine Hiking",
+                        "difficult_alpine_hiking": "T6: Difficult Alpine Hiking"
+                    }
+                }
             },
             "seasonal": {
                 "key": "seasonal",
@@ -102091,14 +102267,14 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "service": {
                 "key": "service",
                 "type": "combo",
+                "label": "Type",
                 "options": [
                     "parking_aisle",
                     "driveway",
                     "alley",
-                    "drive-through",
-                    "emergency_access"
-                ],
-                "label": "Type"
+                    "emergency_access",
+                    "drive-through"
+                ]
             },
             "shelter": {
                 "key": "shelter",
@@ -102108,15 +102284,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "shelter_type": {
                 "key": "shelter_type",
                 "type": "combo",
-                "options": [
-                    "public_transport",
-                    "picnic_shelter",
-                    "weather_shelter",
-                    "lean_to",
-                    "basic_hut",
-                    "field_shelter",
-                    "rock_shelter"
-                ],
                 "label": "Type"
             },
             "shop": {
@@ -102132,13 +102299,36 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "smoking": {
                 "key": "smoking",
                 "type": "combo",
-                "options": [
-                    "no",
-                    "outside",
-                    "separated",
-                    "yes"
-                ],
-                "label": "Smoking"
+                "label": "Smoking",
+                "placeholder": "No, Separated, Yes...",
+                "strings": {
+                    "options": {
+                        "no": "No smoking anywhere",
+                        "separated": "In smoking areas, not physically isolated",
+                        "isolated": "In smoking areas, physically isolated",
+                        "outside": "Allowed outside",
+                        "yes": "Allowed everywhere",
+                        "dedicated": "Dedicated to smokers (e.g. smokers' club)"
+                    }
+                }
+            },
+            "smoothness": {
+                "key": "smoothness",
+                "type": "combo",
+                "label": "Smoothness",
+                "placeholder": "Thin Rollers, Wheels, Off-Road...",
+                "strings": {
+                    "options": {
+                        "excellent": "Thin Rollers: rollerblade, skateboard",
+                        "good": "Thin Wheels: racing bike",
+                        "intermediate": "Wheels: city bike, wheelchair, scooter",
+                        "bad": "Robust Wheels: trekking bike, car, rickshaw",
+                        "very_bad": "High Clearance: light duty off-road vehicle",
+                        "horrible": "Off-Road: heavy duty off-road vehicle",
+                        "very_horrible": "Specialized off-road: tractor, ATV",
+                        "impassible": "Impassible / No wheeled vehicle"
+                    }
+                }
             },
             "social_facility_for": {
                 "key": "social_facility:for",
@@ -102177,14 +102367,14 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "sport_ice": {
                 "key": "sport",
                 "type": "combo",
+                "label": "Sport",
                 "options": [
                     "skating",
                     "hockey",
                     "multi",
                     "curling",
                     "ice_stock"
-                ],
-                "label": "Sport"
+                ]
             },
             "structure": {
                 "type": "radio",
@@ -102210,11 +102400,11 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "studio_type": {
                 "key": "type",
                 "type": "combo",
+                "label": "Type",
                 "options": [
                     "audio",
                     "video"
-                ],
-                "label": "Type"
+                ]
             },
             "supervised": {
                 "key": "supervised",
@@ -102234,7 +102424,15 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "toilets/disposal": {
                 "key": "toilets:disposal",
                 "type": "combo",
-                "label": "Disposal"
+                "label": "Disposal",
+                "strings": {
+                    "options": {
+                        "flush": "Flush",
+                        "pitlatrine": "Pit/Latrine",
+                        "chemical": "Chemical",
+                        "bucket": "Bucket"
+                    }
+                }
             },
             "tourism": {
                 "key": "tourism",
@@ -102249,22 +102447,43 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             "tracktype": {
                 "key": "tracktype",
                 "type": "combo",
-                "label": "Type"
+                "label": "Track Type",
+                "placeholder": "Solid, Mostly Solid, Soft...",
+                "strings": {
+                    "options": {
+                        "grade1": "Solid: paved or heavily compacted hardcore surface",
+                        "grade2": "Mostly Solid: gravel/rock with some soft material mixed in",
+                        "grade3": "Even mixture of hard and soft materials",
+                        "grade4": "Mostly Soft: soil/sand/grass with some hard material mixed in",
+                        "grade5": "Soft: soil/sand/grass"
+                    }
+                }
             },
             "trail_visibility": {
                 "key": "trail_visibility",
                 "type": "combo",
-                "label": "Trail Visibility"
+                "label": "Trail Visibility",
+                "placeholder": "Excellent, Good, Bad...",
+                "strings": {
+                    "options": {
+                        "excellent": "Excellent: unambiguous path or markers everywhere",
+                        "good": "Good: markers visible, sometimes require searching",
+                        "intermediate": "Intermediate: few markers, path mostly visible",
+                        "bad": "Bad: no markers, path sometimes invisible/pathless",
+                        "horrible": "Horrible: often pathless, some orientation skills required",
+                        "no": "No: pathless, excellent orientation skills required"
+                    }
+                }
             },
             "tree_type": {
                 "key": "type",
                 "type": "combo",
+                "label": "Type",
                 "options": [
                     "broad_leaved",
                     "conifer",
                     "palm"
-                ],
-                "label": "Type"
+                ]
             },
             "trees": {
                 "key": "trees",
@@ -114457,7 +114676,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
             },
             "delete": {
                 "title": "Delete",
-                "description": "Remove this from the map.",
+                "description": "Delete object permanently.",
                 "annotation": {
                     "point": "Deleted a point.",
                     "vertex": "Deleted a node from a way.",
@@ -114878,7 +115097,12 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "label": "Type"
                 },
                 "aerialway/access": {
-                    "label": "Access"
+                    "label": "Access",
+                    "options": {
+                        "entry": "Entry",
+                        "exit": "Exit",
+                        "both": "Both"
+                    }
                 },
                 "aerialway/bubble": {
                     "label": "Bubble"
@@ -114899,7 +115123,12 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "placeholder": "2, 4, 8..."
                 },
                 "aerialway/summer/access": {
-                    "label": "Access (summer)"
+                    "label": "Access (summer)",
+                    "options": {
+                        "entry": "Entry",
+                        "exit": "Exit",
+                        "both": "Both"
+                    }
                 },
                 "aeroway": {
                     "label": "Type"
@@ -114939,7 +115168,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "placeholder": "50, 100, 200..."
                 },
                 "cardinal_direction": {
-                    "label": "Direction"
+                    "label": "Direction",
+                    "options": {
+                        "N": "North",
+                        "E": "East",
+                        "S": "South",
+                        "W": "West",
+                        "NE": "Northeast",
+                        "SE": "Southeast",
+                        "SW": "Southwest",
+                        "NW": "Northwest",
+                        "NNE": "North-northeast",
+                        "ENE": "East-northeast",
+                        "ESE": "East-southeast",
+                        "SSE": "South-southeast",
+                        "SSW": "South-southwest",
+                        "WSW": "West-southwest",
+                        "WNW": "West-northwest",
+                        "NNW": "North-northwest"
+                    }
                 },
                 "clock_direction": {
                     "label": "Direction",
@@ -114979,7 +115226,14 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "label": "Description"
                 },
                 "electrified": {
-                    "label": "Electrification"
+                    "label": "Electrification",
+                    "placeholder": "Contact Line, Electrified Rail...",
+                    "options": {
+                        "contact_line": "Contact Line",
+                        "rail": "Electrified Rail",
+                        "yes": "Yes (unspecified)",
+                        "no": "No"
+                    }
                 },
                 "elevation": {
                     "label": "Elevation"
@@ -115001,7 +115255,13 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "label": "Fee"
                 },
                 "fire_hydrant/type": {
-                    "label": "Type"
+                    "label": "Type",
+                    "options": {
+                        "pillar": "Pillar/Aboveground",
+                        "underground": "Underground",
+                        "wall": "Wall",
+                        "pond": "Pond"
+                    }
                 },
                 "fixme": {
                     "label": "Fix Me"
@@ -115124,6 +115384,42 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "label": "Speed Limit",
                     "placeholder": "40, 50, 60..."
                 },
+                "mtb/scale": {
+                    "label": "Mountain Biking Difficulty",
+                    "placeholder": "0, 1, 2, 3...",
+                    "options": {
+                        "0": "0: Solid gravel/packed earth, no obstacles, wide curves",
+                        "1": "1: Some loose surface, small obstacles, wide curves",
+                        "2": "2: Much loose surface, large obstacles, easy hairpins",
+                        "3": "3: Slippery surface, large obstacles, tight hairpins",
+                        "4": "4: Loose surface or boulders, dangerous hairpins",
+                        "5": "5: Maximum difficulty, boulder fields, landslides",
+                        "6": "6: Not rideable except by the very best mountain bikers"
+                    }
+                },
+                "mtb/scale/imba": {
+                    "label": "IMBA Trail Difficulty",
+                    "placeholder": "Easy, Medium, Difficult...",
+                    "options": {
+                        "0": "Easiest (white circle)",
+                        "1": "Easy (green circle)",
+                        "2": "Medium (blue square)",
+                        "3": "Difficult (black diamond)",
+                        "4": "Extremely Difficult (double black diamond)"
+                    }
+                },
+                "mtb/scale/uphill": {
+                    "label": "Mountain Biking Uphill Difficulty",
+                    "placeholder": "0, 1, 2, 3...",
+                    "options": {
+                        "0": "0: Avg. incline <10%, gravel/packed earth, no obstacles",
+                        "1": "1: Avg. incline <15%, gravel/packed earth, few small objects",
+                        "2": "2: Avg. incline <20%, stable surface, fistsize rocks/roots",
+                        "3": "3: Avg. incline <25%, variable surface, fistsize rocks/branches",
+                        "4": "4: Avg. incline <30%, poor condition, big rocks/branches",
+                        "5": "5: Very steep, bike generally needs to be pushed or carried"
+                    }
+                },
                 "name": {
                     "label": "Name",
                     "placeholder": "Common name (if any)"
@@ -115170,20 +115466,58 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "label": "Park and Ride"
                 },
                 "parking": {
-                    "label": "Type"
+                    "label": "Type",
+                    "options": {
+                        "surface": "Surface",
+                        "multi-storey": "Multilevel",
+                        "underground": "Underground",
+                        "sheds": "Sheds",
+                        "carports": "Carports",
+                        "garage_boxes": "Garage Boxes",
+                        "lane": "Roadside Lane"
+                    }
                 },
                 "phone": {
                     "label": "Phone",
                     "placeholder": "+31 42 123 4567"
                 },
                 "piste/difficulty": {
-                    "label": "Difficulty"
+                    "label": "Difficulty",
+                    "placeholder": "Easy, Intermediate, Advanced...",
+                    "options": {
+                        "novice": "Novice (instructional)",
+                        "easy": "Easy (green circle)",
+                        "intermediate": "Intermediate (blue square)",
+                        "advanced": "Advanced (black diamond)",
+                        "expert": "Expert (double black diamond)",
+                        "freeride": "Freeride (off-piste)",
+                        "extreme": "Extreme (climbing equipment required)"
+                    }
                 },
                 "piste/grooming": {
-                    "label": "Grooming"
+                    "label": "Grooming",
+                    "options": {
+                        "classic": "Classic",
+                        "mogul": "Mogul",
+                        "backcountry": "Backcountry",
+                        "classic+skating": "Classic and Skating",
+                        "scooter": "Scooter/Snowmobile",
+                        "skating": "Skating"
+                    }
                 },
                 "piste/type": {
-                    "label": "Type"
+                    "label": "Type",
+                    "options": {
+                        "downhill": "Downhill",
+                        "nordic": "Nordic",
+                        "skitour": "Skitour",
+                        "sled": "Sled",
+                        "hike": "Hike",
+                        "sleigh": "Sleigh",
+                        "ice_skate": "Ice Skate",
+                        "snow_park": "Snow Park",
+                        "playground": "Playground"
+                    }
                 },
                 "place": {
                     "label": "Type"
@@ -115216,16 +115550,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "label": "Type"
                 },
                 "religion": {
-                    "label": "Religion",
-                    "options": {
-                        "christian": "Christian",
-                        "muslim": "Muslim",
-                        "buddhist": "Buddhist",
-                        "jewish": "Jewish",
-                        "hindu": "Hindu",
-                        "shinto": "Shinto",
-                        "taoist": "Taoist"
-                    }
+                    "label": "Religion"
                 },
                 "restriction": {
                     "label": "Type"
@@ -115240,7 +115565,16 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "label": "Type"
                 },
                 "sac_scale": {
-                    "label": "Path Difficulty"
+                    "label": "Hiking Difficulty",
+                    "placeholder": "Mountain Hiking, Alpine Hiking...",
+                    "options": {
+                        "hiking": "T1: Hiking",
+                        "mountain_hiking": "T2: Mountain Hiking",
+                        "demanding_mountain_hiking": "T3: Demanding Mountain Hiking",
+                        "alpine_hiking": "T4: Alpine Hiking",
+                        "demanding_alpine_hiking": "T5: Demanding Alpine Hiking",
+                        "difficult_alpine_hiking": "T6: Difficult Alpine Hiking"
+                    }
                 },
                 "seasonal": {
                     "label": "Seasonal"
@@ -115261,7 +115595,30 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "label": "Sloped Curb"
                 },
                 "smoking": {
-                    "label": "Smoking"
+                    "label": "Smoking",
+                    "placeholder": "No, Separated, Yes...",
+                    "options": {
+                        "no": "No smoking anywhere",
+                        "separated": "In smoking areas, not physically isolated",
+                        "isolated": "In smoking areas, physically isolated",
+                        "outside": "Allowed outside",
+                        "yes": "Allowed everywhere",
+                        "dedicated": "Dedicated to smokers (e.g. smokers' club)"
+                    }
+                },
+                "smoothness": {
+                    "label": "Smoothness",
+                    "placeholder": "Thin Rollers, Wheels, Off-Road...",
+                    "options": {
+                        "excellent": "Thin Rollers: rollerblade, skateboard",
+                        "good": "Thin Wheels: racing bike",
+                        "intermediate": "Wheels: city bike, wheelchair, scooter",
+                        "bad": "Robust Wheels: trekking bike, car, rickshaw",
+                        "very_bad": "High Clearance: light duty off-road vehicle",
+                        "horrible": "Off-Road: heavy duty off-road vehicle",
+                        "very_horrible": "Specialized off-road: tractor, ATV",
+                        "impassible": "Impassible / No wheeled vehicle"
+                    }
                 },
                 "social_facility_for": {
                     "label": "People served",
@@ -115300,7 +115657,13 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "label": "Tactile Paving"
                 },
                 "toilets/disposal": {
-                    "label": "Disposal"
+                    "label": "Disposal",
+                    "options": {
+                        "flush": "Flush",
+                        "pitlatrine": "Pit/Latrine",
+                        "chemical": "Chemical",
+                        "bucket": "Bucket"
+                    }
                 },
                 "tourism": {
                     "label": "Type"
@@ -115309,10 +115672,27 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "label": "Tower type"
                 },
                 "tracktype": {
-                    "label": "Type"
+                    "label": "Track Type",
+                    "placeholder": "Solid, Mostly Solid, Soft...",
+                    "options": {
+                        "grade1": "Solid: paved or heavily compacted hardcore surface",
+                        "grade2": "Mostly Solid: gravel/rock with some soft material mixed in",
+                        "grade3": "Even mixture of hard and soft materials",
+                        "grade4": "Mostly Soft: soil/sand/grass with some hard material mixed in",
+                        "grade5": "Soft: soil/sand/grass"
+                    }
                 },
                 "trail_visibility": {
-                    "label": "Trail Visibility"
+                    "label": "Trail Visibility",
+                    "placeholder": "Excellent, Good, Bad...",
+                    "options": {
+                        "excellent": "Excellent: unambiguous path or markers everywhere",
+                        "good": "Good: markers visible, sometimes require searching",
+                        "intermediate": "Intermediate: few markers, path mostly visible",
+                        "bad": "Bad: no markers, path sometimes invisible/pathless",
+                        "horrible": "Horrible: often pathless, some orientation skills required",
+                        "no": "No: pathless, excellent orientation skills required"
+                    }
                 },
                 "tree_type": {
                     "label": "Type"
@@ -115473,6 +115853,10 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081],"
                     "name": "Boat Rental",
                     "terms": ""
                 },
+                "amenity/bus_station": {
+                    "name": "Bus Station",
+                    "terms": ""
+                },
                 "amenity/cafe": {
                     "name": "Cafe",
                     "terms": "coffee,tea,coffee shop"